📜 Scripts Management#

Workstation Sync Shortcut: To automatically backup all your scripts and custom terminal aliases configuration (staging and pushing your entire ~/Scripts/ repository):

pushscripts

This will stage all modified files in ~/Scripts/, commit, and push updates directly to GitHub and your NAS (without running Homebrew operations).

MCP Configuration Sync: MCP configuration is maintained in a separate repository, ~/.mcp-config, linked to git@github.com:marcoue/MCP-Config-MacOS.git. Use:

pushmcp   # Commit selected MCP master files, compile through the post-commit hook, and push to GitHub
pullmcp   # Pull MCP changes; the post-merge hook recompiles client configurations

These commands do not operate on ~/Scripts and do not replace pushscripts or pullscripts.

Workstation Update Shortcut: To pull down the latest custom scripts and terminal aliases from GitHub on an existing machine (after the first-time setup is complete):

pullscripts

This will run git pull on your scripts repository to keep your code environment up-to-date.

Homelab Vault Force-Alignment: Run pulllab to reset the vault to origin/main. If uncommitted changes are present, it displays them and asks Overwrite local changes and continue? [Y/n]; pressing Enter accepts the default Yes. The command refuses to run while Obsidian is open.

Removed GenDash/GPSDash Mac workflows: On 2026-10-09, the pushgen, pullgen, pushgps, and pullgps aliases and their local scripts were removed. The Mac Studio GenDash cron entries at 12:10 and 20:10 were also removed. No backup was retained. The alias and script removals are still local changes in the ~/Scripts repository and have not been committed or pushed.

Xcode Project Force-Alignment: Run pullxgen for /Users/marc/Xcode/GenDash or pullxgps for /Users/marc/Xcode/GPSDash to fetch and reset the project to origin/main, then remove untracked files with git clean -fd. Both commands require the main branch, refuse to run while Xcode is open, and prompt before overwriting when uncommitted changes are present; pressing Enter accepts the default Yes.

Quick Clone & Restore (Secondary Computer): Restore the scripts repository first, then configure the local shell profile before setting up the separate MCP repository:

git clone git@github.com:marcoue/Scripts.git ~/Scripts

Then create or update ~/.zshrc with the private values from 1Password, ensure it sources ~/Scripts/MacOS/Aliases/MacOS-Aliases.zsh, and run source ~/.zshrc. Set up ~/.mcp-config only after the aliases and service-account environment are available; follow MCP Configuration Guide.

Quick Sync / Update (Existing Workstation - First Time): To transition an existing machine to the new layout (or pull updates manually when the alias is not yet loaded):

cd ~/Scripts && git pull
source ~/Scripts/MacOS/Aliases/MacOS-Aliases.zsh
source ~/.zshrc

This pulls the latest repo changes and refreshes the shell session. On a new machine, create ~/.zshrc manually and copy the private values from the 1Password Homelab vault entry Mac OS .zshrc file before sourcing it.

This document is the authoritative, long-term operational standard for authoring, version-controlling, distributing, and executing scripts across the homelab infrastructure.


1. Core Architecture & Philosophy#

All homelab scripts are managed under a single-source-of-truth architecture designed for centralized editing, automatic distribution, and hardware independence.

🎯 The Four Architectural Pillars#

  1. Master Workstation Repository: /Users/marc/Scripts on the Mac Studio is the primary master workspace where all scripts are authored, edited, tested, and version-controlled.
  2. Cloud Version Control: Linked to GitHub remote git@github.com:marcoue/Scripts.git on branch main.
  3. Automated Distribution Mirror: A local Git post-commit hook automatically mirrors committed scripts from Mac Studio (~/Scripts/) to UNAS-Pro NAS (/Volumes/Software/Software/Scripts/).
  4. Independent Server Execution: Remote nodes pull or execute their versioned scripts from the central distribution mirror or local dataset copies.
  ┌────────────────────────────────────────────────────────┐
  │         Mac Workstation (Master Workspace)             │
  │                  ~/Scripts/                            │
  │     (Linked to git@github.com:marcoue/Scripts.git)     │
  └──────────────────────────┬─────────────────────────────┘
                             │
                             │ (git commit)
                             ▼
  ┌────────────────────────────────────────────────────────┐
  │                Git post-commit Hook                    │
  │       (rsync auto-mirror to mounted SMB share)         │
  └──────────────────────────┬─────────────────────────────┘
                             │
                             ▼
  ┌────────────────────────────────────────────────────────┐
  │            UNAS-Pro NAS (Distribution Mirror)          │
  │            /Volumes/Software/Software/Scripts/         │
  │        (Exposed as Rsync Module: ::Software)           │
  └──────────────────────────┬─────────────────────────────┘
                             │
                             │ (Rsync / Git pull on schedule)
                             ▼
  ┌────────────────────────────────────────────────────────┐
  │          Remote Server Nodes (TrueNAS, PVE, Linux)     │
  │           Execution of Version-Controlled Scripts      │
  └────────────────────────────────────────────────────────┘

1.1 Ubuntu/Linux Workstation Implementation#

The Ubuntu workstation uses the same GitHub Scripts repository as the Mac Studio, but Linux-specific scripts and aliases are kept separate from all macOS files.

Resource Ubuntu/Linux path
Scripts repository /home/marc/Scripts
Homelab vault /home/marc/Obsidian/Homelab
Linux alias file /home/marc/Scripts/Linux/Aliases/Linux-Aliases.bash
Local shell loader /home/marc/.bashrc
Scripts Git remote git@github.com:marcoue/Scripts.git

The Ubuntu .bashrc sources the tracked Linux alias file. The MacOS alias file and all MacOS scripts remain independent and unchanged.

Active Ubuntu/Linux aliases#

Alias or function Linux implementation Description
pulllab Linux/pull-obsidian-homelab.sh Checks that Obsidian is closed, requires branch main, fetches GitHub, prompts before overwriting changes, then force-aligns the vault with origin/main.
pushlab Linux/sync-obsidian-homelab-hugo.sh Converts a temporary Hugo copy of the vault, synchronizes notes and icons to the Hugo VM, triggers remote publishing, and backs up the vault to GitHub. Supports --sync-only / -s.
gitstatus Linux/git_status.py Scans Git repositories under the user home directory, fetches remotes, and reports local, ahead, behind, and fetch-error states.
speed Linux/speed_test.sh Performs a 4 GiB Linux disk write/read benchmark. Defaults to $HOME; use SPEED_TARGET_DIR=/path speed for another target.
pushscripts Bash function in Linux/Aliases/Linux-Aliases.bash Stages, commits, and pushes the Scripts repository to origin/main.
pullscripts Bash alias in Linux/Aliases/Linux-Aliases.bash Pulls the latest Scripts repository changes from origin/main.

The Linux pushlab implementation preserves the Mac workflow while using /home/marc/Obsidian/Homelab/Notes, /home/marc/Obsidian/Homelab/assets/icons, and Linux shell conventions. The optional root-level Images/ directory is synchronized when present; otherwise image synchronization is skipped.

Docker-dependent aliases 1p and clean are intentionally not enabled on this Ubuntu workstation because Docker is not installed. The existing Linux benchmark files speed.sh and speed_2.sh were left untouched; speed_test.sh is the workstation-specific counterpart to the Mac benchmark.

The completed Linux additions were committed and pushed to GitHub in commit 37fd077. The Homelab vault and Scripts repository were both verified clean afterward.

1.2 MCP Configuration Boundary#

The MCP configuration is intentionally separate from the scripts repository. The master files live in ~/.mcp-config, where config.json is the source of truth and apply.py compiles settings for the registered AI clients on the Mac Studio and MacBook Air. The local .git/hooks/post-commit and .git/hooks/post-merge files run the compiler after commits and pulls.

The pushmcp command is a shell function defined in ~/Scripts/MacOS/Aliases/MacOS-Aliases.zsh; it is not a standalone script in this repository. pullmcp is the matching shell alias. Their definitions and behavior are documented in Mac OS - Aliases Management and MCP Configuration Guide.

1.3 Intel iMac Managed Workstation#

The 2014 Intel iMac is an additional managed macOS workstation for operating ~/Scripts, Obsidian, and MCP clients. Its ~/Scripts checkout uses the same GitHub repository and aliases as the other Macs; no Intel-specific copy of the scripts is required.

The Intel Homebrew prefix is /usr/local. MCP-specific Python environments may instead use standalone uv-managed Python 3.12 because some Homebrew packages build slowly or lack Intel bottles. These local runtime differences do not belong in the ~/Scripts repository. Use pushscripts only for intentional changes to tracked scripts or aliases; use pushmcp for selected changes to the separate ~/.mcp-config repository.


2. Directory Structure & Categorization Standard#

The repository uses standardized platform subdirectories. Every script MUST be placed into its appropriate category folder:

/Users/marc/Scripts/
├── MacOS/       # Workstation automation, local syncs, KVM launchers, utility tools
│   ├── Aliases/ # Managed shell configuration (MacOS-Aliases.zsh)
│   └── Brew/    # Workstation package lists (Brewfile)
├── Linux/       # General Linux server utilities, speed tests, web publishing
├── Proxmox/     # Proxmox VE node/VM backup, restore, and cluster utilities
│   └── Archives/# Retained legacy / reference scripts
└── TrueNAS/     # TrueNAS node standalone backup scripts

📋 Organization Rules:#

  • MacOS/: Scripts designed to run locally on macOS workstations (e.g., Hugo note syncs, image processing, desktop utilities). Package lists and aliases are structured under Brew/ and Aliases/ subdirectories.
  • Linux/: Scripts designed for general Linux servers, container environments, or distribution tasks.
  • Proxmox/: Scripts designed specifically for Proxmox VE hypervisors and PBS/PVE operations.
  • [TrueNAS](TrueNAS.md)/: Scripts designed specifically for TrueNAS storage nodes and zfs/midclt operations.

3. Development & Deployment Workflow#

Follow this standard 3-step workflow whenever creating or modifying scripts:

Step 1: Write & Test Locally (Mac Studio)#

Create or edit the script inside /Users/marc/Scripts/<Category>/<script_name>.sh. Grant executable permissions before committing:

chmod +x /Users/marc/Scripts/<Category>/<script_name>.sh

Step 2: Commit & Push to GitHub#

Commit the change to version control:

cd /Users/marc/Scripts
git add .
git commit -m "Describe script updates"
git push origin main

Workstation Sync Shortcut: For quick workstation updates, you can run the pushscripts alias from your terminal. It will automatically stage all changes in your scripts repository, commit them, and push them to GitHub.

Step 3: Automated NAS Distribution (Hands-Free)#

Upon executing git commit, the local Git post-commit hook automatically fires and mirrors the updated scripts to the NAS distribution share (/Volumes/Software/Software/Scripts/).

🔧 Git Hook Implementation (~/Scripts/.git/hooks/post-commit):#

#!/usr/bin/env bash
# Git post-commit hook: Auto-mirror ~/Scripts to UNAS-Pro SMB Share
if [ -d "/Volumes/Software/Software/Scripts" ]; then
    echo "=== Git Hook: Auto-mirroring ~/Scripts to UNAS-Pro NAS ==="
    rsync -av --delete --exclude='.git' --exclude='*.log' /Users/marc/Scripts/ /Volumes/Software/Software/Scripts/
else
    echo "⚠️ Warning: UNAS-Pro SMB Share (/Volumes/Software) not mounted. Mirror skipped."
fi

4. Execution & Permission Best Practices#

Network Share Permission Handling#

When scripts are synced across network storage shares (SMB/NFS), POSIX executable permissions (+x) can be stripped or mapped to default read/write modes (-rw-rw---- / 660). Attempting to execute a script directly via ./script.sh or /path/to/script.sh on network-mounted or pulled files may fail with Permission denied (13).

The Explicit Interpreter Rule#

To guarantee 100% execution reliability across all environments, scheduled tasks and automated jobs MUST invoke scripts using their explicit interpreter:

  • Shell Scripts:
    bash /path/to/script.sh
  • Python Scripts:
    python3 /path/to/script.py

Executing via an explicit interpreter (e.g., bash /path/to/script.sh) only requires read permission (r) on the file, eliminating reliance on the Unix executable +x bit completely.


5. Workstation Recovery & Disaster Protocol#

The script management architecture is completely decoupled from local workstation hardware. Reinstalling or replacing macOS on your Mac Studio causes ZERO disruption to NAS distribution storage or remote server execution.

🔄 Workstation Restoration Guide (New Mac / Reinstall)#

To restore your script management environment on a fresh macOS installation:

  1. Mount NAS SMB Share: Connect to smb://10.1.2.2/Software and add /Volumes/Software to System Settings > General > Login Items.
  2. Clone Master Repository from GitHub:
    git clone git@github.com:marcoue/Scripts.git ~/Scripts
  3. Re-install Git Auto-Mirroring Hook:
    cat << 'EOF' > ~/Scripts/.git/hooks/post-commit
    #!/usr/bin/env bash
    if [ -d "/Volumes/Software/Software/Scripts" ]; then
        echo "=== Git Hook: Auto-mirroring ~/Scripts to UNAS-Pro NAS ==="
        rsync -av --delete --exclude='.git' --exclude='*.log' /Users/marc/Scripts/ /Volumes/Software/Software/Scripts/
    fi
    EOF
    chmod +x ~/Scripts/.git/hooks/post-commit
  4. Verify Environment: Run git status in ~/Scripts/ to confirm tracking origin/main.

Restoring ~/Scripts does not restore the MCP repository. Set up or synchronize ~/.mcp-config separately using MCP Configuration Guide.


5.5 Complete Scripts Inventory#

Below is a complete index of all scripts managed in the ~/Scripts repository:

🍏 macOS Scripts (MacOS/)#

Script Alias Description
Aliases/MacOS-Aliases.zsh — Tracked zsh aliases, functions, and non-secret shell configuration.
KVM-Launch.sh kvm Launches the Java Web Start utility for the Tripp Lite KVM switch.
git_status.py gitstatus Reports Git repository status information.
Rclone-MarcGoogleDrive.sh — Runs rclone backup syncs with personal Google Drive storage.
ai_deploy_safety_on_all_servers.sh — Automates deploying AI safety configuration files to all remote servers.
convert_images_1024.sh / convert_images_900.sh convert (900px script) Resizes local image assets to 1024px or 900px width.
convert_images_jpg.sh / convert_images_raw_jpg.sh — Converts images and RAW files to standard JPG formats.
convert_images_to_1260X2736px.sh — Resizes images to exactly 1260x2736px.
convert_raw_send_to_vm.sh convertsend Converts raw image directories and uploads them to the target Proxmox VM.
convert_rename_images_raw_jpg.sh — Converts RAW files, renames files sequentially, and outputs JPGs.
file_indexer.sh — Indexes directory structures into plain text catalog maps.
generate_favicons.sh — Generates multi-size web favicon assets from a master image.
ios_icon_maker.sh — Generates all app icon sizes required for iOS device layouts.
lock_gendash.sh genl, genu, gens, genx Manages collaborative edit locking/unlocking for GenDash project strings.
lock_gpsdash.sh gpsl, gpsu, gpss, gpsx Manages locking, unlocking, and status checks for GPSDash localization worksheets and string catalog.
lock_sounddash.sh sndl, sndu, snds, sndx Manages locking, unlocking, and status checks for SoundDash localization worksheets and string catalog.
lock_dockdash.sh docl, docu, docs, docx Manages locking, unlocking, and status checks for DockDash localization worksheets and string catalog.
post-commit-hook.sh — Backup copy of the Git hook that mirrors the ~/Scripts repo to the NAS.
pull-obsidian-homelab.sh pulllab Force-aligns the local Obsidian Homelab vault with origin/main, prompting only when uncommitted changes are present and refusing to run while Obsidian is open.
pull-xcode-gendash.sh / pull-xcode-gpsdash.sh pullxgen / pullxgps Fetches and force-aligns the matching Xcode project with origin/main, prompting before overwriting local changes and refusing to run while Xcode is open.
push-xcode-gendash.sh / push-xcode-gpsdash.sh pushxgen / pushxgps Stages all local changes, creates a timestamped commit when changes exist, and pushes the matching Xcode project to origin/main.
speed_test.sh speed Runs network speed and ping diagnostic tests.
sync-gemini-to-macbook15.sh / sync-gemini-to-macbookair.sh / sync-gemini-to-macstudio.sh — Synchronizes Gemini config files to MacBook 15, MacBook Air, and Mac Studio respectively.
sync-obsidian-homelab-hugo.sh pushlab Syncs Homelab Obsidian notes to the Linux VM for Hugo hosting.
sync-obsidian-peru-hugo.sh — Syncs Peru Obsidian notes to the Linux VM for Hugo hosting.
sync-obsidian-homelab-hugo-preview.sh testlab Delegates to the existing Homelab sync-only mode to prepare and sync preview files without Hugo, publishing, commits, or pushes.
sync-obsidian-dashapps-hugo.sh pushdash Syncs the DashApps vault’s Notes/ and Images/ to dedicated input folders on HP1Docker, converts content, builds and validates Hugo, commits/pushes changed website source to marcoue/DashApps.app (triggering Cloudflare Pages), then commits/pushes the editable Notes/Images backup to marcoue/Obsidian-DashApps.app. --sync-only syncs only; --build-only syncs/converts/builds without committing or pushing either repository.
sync-obsidian-dashapps-hugo-preview.sh testdash Syncs DashApps vault inputs and runs the server-side converter so the LAN Hugo preview sees updated generated content; does not run a Hugo build or publish.

🐧 Linux Scripts (Linux/)#

Script Alias Description
Aliases/Linux-Aliases.bash pulllab, pushlab, gitstatus, speed, pushscripts, pullscripts Tracked Linux Bash aliases and functions, sourced from the local .bashrc.
RN-VPSPangoling_pull_backups.sh — Pulls backups from VPS Pangoling.
RN-VPSPangoling_pull_backups_integrity_check.sh — Checks backup file integrity for VPS Pangoling.
pull-obsidian-homelab.sh pulllab Linux-safe force-alignment of the local Homelab vault with origin/main.
sync-obsidian-homelab-hugo.sh pushlab Linux Homelab vault-to-Hugo synchronization, remote publication, and GitHub backup.
git_status.py gitstatus Reports Git repository status information across the Linux home directory.
speed_test.sh speed Linux disk benchmark equivalent of the macOS speed_test.sh; defaults to $HOME.
publish-hugo-gendash.sh — Builds and publishes GenDash site using Hugo on Linux VM.
publish-hugo-homelab.sh — Builds and publishes Homelab site using Hugo on Linux VM.
HP1_Synology_Photos_Push.sh pushphotos Mirrors the read-only Synology Photos mount to the UNAS-Pro Photos share; usable on configured Linux hosts.
setup_ai_safety.sh — Configures AI safety configurations on Linux hosts.
speed.sh / speed_2.sh — Existing Linux disk benchmark variants; not replaced by the workstation speed_test.sh.
Netbox/Netbox_import.py — Python script to import devices/assets into NetBox.
Netbox/Netbox_sync_gsheets_to_netbox.py netbox Synchronizes Google Sheets inventory records into NetBox database.

🛡️ Proxmox Scripts (Proxmox/)#

Script Alias Description
proxmox_backup.sh — Manages backup tasks for Proxmox VE nodes.
proxmox_restore.sh — Handles restore routines for Proxmox VE containers/VMs.

💾 TrueNAS Scripts (TrueNAS/)#

Script Alias Description
HP1_UNAS_Pull_Backup.sh / HP2_UNAS_Pull_Backup.sh / HP3_UNAS_Pull_Backup.sh / HP6_UNAS_Pull_Backup.sh / HP8_UNAS_Pull_Backup.sh — Standalone backup pull scripts; HP8_UNAS_Pull_Backup.sh is the legacy filename for the current HP7TrueNAS job.