From c46d46cd9abefce211f61493689a9d023e20968a Mon Sep 17 00:00:00 2001 From: Rin Oliver Date: Thu, 19 Feb 2026 16:48:15 -0600 Subject: [PATCH 1/2] feat: add VM tools image build GHA workflow --- workflows/update-vm-tools.yml | 197 ++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 workflows/update-vm-tools.yml diff --git a/workflows/update-vm-tools.yml b/workflows/update-vm-tools.yml new file mode 100644 index 0000000..3253a8c --- /dev/null +++ b/workflows/update-vm-tools.yml @@ -0,0 +1,197 @@ +name: Update vm-tools in Base Images + +on: + workflow_dispatch: + inputs: + vmToolsVersion: + description: 'Version of orka-vm-tools to install (e.g., 3.5.2)' + required: false + default: '3.5.2' + +permissions: + contents: read + packages: write + +jobs: + update: + name: ${{ matrix.name }}:${{ matrix.tag }} + runs-on: + - self-hosted + - arm-mini-002 + strategy: + max-parallel: 1 + matrix: + include: + - name: tahoe + tag: latest + - name: tahoe + tag: 200-gb + - name: sequoia + tag: latest + - name: sequoia + tag: 200-gb + - name: sonoma + tag: latest + - name: monterey + tag: latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set VM name + id: vars + run: | + echo "VM_NAME=vm-tools-updater-${{ github.run_id }}-${{ matrix.name }}-${{ matrix.tag }}" >> "$GITHUB_OUTPUT" + echo "TEMP_NAME=vm-tools-updated-${{ github.run_id }}-${{ matrix.name }}-${{ matrix.tag }}" >> "$GITHUB_OUTPUT" + + - name: Download vm-tools installer and setup scripts + run: | + curl -fsSL \ + "https://orka-tools.s3.amazonaws.com/orka-vm-tools/official/${{ inputs.vmToolsVersion }}/orka-vm-tools.pkg" \ + -o orka-vm-tools.pkg + curl -fsSL \ + "https://raw.githubusercontent.com/macstadium/packer-plugin-macstadium-orka/main/guest-scripts/setup-sys-daemon.sh" \ + -o setup-sys-daemon.sh + + - name: Pull image + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + orka-engine image pull \ + --username ${{ github.actor }} \ + --password "${GITHUB_TOKEN}" \ + ghcr.io/macstadium/orka-images/${{ matrix.name }}:${{ matrix.tag }} + + - name: Run VM + run: | + orka-engine vm run ${{ steps.vars.outputs.VM_NAME }} \ + --image ghcr.io/macstadium/orka-images/${{ matrix.name }}:${{ matrix.tag }} \ + -d + + - name: Wait for VM IP + timeout-minutes: 5 + id: vm-ip + run: | + output="" + vm_name="${{ steps.vars.outputs.VM_NAME }}" + jq_query=".[] | select(.name == \"$vm_name\") | .ip" + while [ -z "$output" ]; do + output=$(orka-engine vm list -o json | jq -r "$jq_query") + sleep 1 + done + echo "VM_IP=$output" >> "$GITHUB_OUTPUT" + + - name: SCP files into VM + env: + VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} + run: | + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + orka-vm-tools.pkg setup-sys-daemon.sh \ + "admin@${{ steps.vm-ip.outputs.VM_IP }}:~/" + + - name: Install vm-tools + env: + VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} + run: | + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${{ steps.vm-ip.outputs.VM_IP }}" \ + "echo ${VM_DEFAULT_PASSWORD} | sudo -S installer -pkg ~/orka-vm-tools.pkg -target /" + + - name: Install network tuning daemon + env: + VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} + run: | + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${{ steps.vm-ip.outputs.VM_IP }}" \ + "echo ${VM_DEFAULT_PASSWORD} | sudo -S bash ~/setup-sys-daemon.sh" + + - name: Configure remote access + env: + VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} + run: | + VM_IP="${{ steps.vm-ip.outputs.VM_IP }}" + + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${VM_IP}" \ + "echo ${VM_DEFAULT_PASSWORD} | sudo -S systemsetup -setremotelogin on" + + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${VM_IP}" \ + "echo ${VM_DEFAULT_PASSWORD} | sudo -S launchctl load -w /System/Library/LaunchDaemons/ssh.plist || true" + + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${VM_IP}" \ + "echo ${VM_DEFAULT_PASSWORD} | sudo -S launchctl load -w /System/Library/LaunchDaemons/com.apple.screensharing.plist || true" + + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${VM_IP}" \ + "echo ${VM_DEFAULT_PASSWORD} | sudo -S /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -restart -agent -privs -all" + + - name: Set admin user password + env: + VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} + run: | + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${{ steps.vm-ip.outputs.VM_IP }}" \ + "echo ${VM_DEFAULT_PASSWORD} | sudo -S dscl . -passwd /Users/admin admin" + + - name: Verify vm-tools version + env: + VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} + run: | + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${{ steps.vm-ip.outputs.VM_IP }}" \ + "/Applications/orka-vm-tools/orka-vm-tools version" + + - name: Reboot VM + continue-on-error: true + env: + VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} + run: | + sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${{ steps.vm-ip.outputs.VM_IP }}" \ + "echo ${VM_DEFAULT_PASSWORD} | sudo -S reboot" + + - name: Wait for VM to come back online + timeout-minutes: 5 + env: + VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} + run: | + vm_ip="${{ steps.vm-ip.outputs.VM_IP }}" + while ! sshpass -p "${VM_DEFAULT_PASSWORD}" \ + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "admin@${vm_ip}" "echo 'VM is back online'" &>/dev/null; do + sleep 1 + done + + - name: Save and push updated image + timeout-minutes: 10 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + orka-engine vm save ${{ steps.vars.outputs.VM_NAME }} \ + ${{ steps.vars.outputs.TEMP_NAME }} + + orka-engine image push \ + --username ${{ github.actor }} \ + --password "${GITHUB_TOKEN}" \ + ${{ steps.vars.outputs.TEMP_NAME }} \ + ghcr.io/macstadium/orka-images/${{ matrix.name }}:${{ matrix.tag }} + + - name: Cleanup + if: always() + run: | + orka-engine vm delete ${{ steps.vars.outputs.VM_NAME }} || true From 4567618ef4a8ac260ff2e9275c71d1a654360eaf Mon Sep 17 00:00:00 2001 From: Rin Oliver Date: Fri, 20 Feb 2026 15:14:08 -0600 Subject: [PATCH 2/2] fix: move workflow to .github/workflows and fix Tahoe remote access setup - Move update-vm-tools.yml from workflows/ to .github/workflows/ so GitHub Actions picks it up - Replace hardcoded launchctl load -w / systemsetup calls in Configure remote access with a version-aware setup-remote-access.sh script that uses launchctl enable + kickstart on Tahoe (macOS 26+) and the legacy launchctl load -w path on Sequoia and below Co-Authored-By: Claude Sonnet 4.6 --- .../workflows}/update-vm-tools.yml | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) rename {workflows => .github/workflows}/update-vm-tools.yml (80%) diff --git a/workflows/update-vm-tools.yml b/.github/workflows/update-vm-tools.yml similarity index 80% rename from workflows/update-vm-tools.yml rename to .github/workflows/update-vm-tools.yml index 3253a8c..6b65818 100644 --- a/workflows/update-vm-tools.yml +++ b/.github/workflows/update-vm-tools.yml @@ -55,6 +55,33 @@ jobs: curl -fsSL \ "https://raw.githubusercontent.com/macstadium/packer-plugin-macstadium-orka/main/guest-scripts/setup-sys-daemon.sh" \ -o setup-sys-daemon.sh + cat > setup-remote-access.sh << 'EOF' + #!/usr/bin/env bash + set -euo pipefail + PASS="$1" + MACOS_MAJOR=$(sw_vers -productVersion | cut -d. -f1) + + # Remote Login (SSH) + if [ "$MACOS_MAJOR" -ge 26 ]; then + echo "$PASS" | sudo -S launchctl enable system/com.openssh.sshd + echo "$PASS" | sudo -S launchctl kickstart -k system/com.openssh.sshd + else + echo "$PASS" | sudo -S systemsetup -setremotelogin on + echo "$PASS" | sudo -S launchctl load -w /System/Library/LaunchDaemons/ssh.plist || true + fi + + # Screen Sharing + if [ "$MACOS_MAJOR" -ge 26 ]; then + echo "$PASS" | sudo -S launchctl enable system/com.apple.screensharing + echo "$PASS" | sudo -S launchctl kickstart -k system/com.apple.screensharing + else + echo "$PASS" | sudo -S launchctl load -w /System/Library/LaunchDaemons/com.apple.screensharing.plist || true + fi + + # Remote Management (ARD/VNC) + echo "$PASS" | sudo -S /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart \ + -activate -configure -access -on -restart -agent -privs -all + EOF - name: Pull image env: @@ -90,7 +117,7 @@ jobs: run: | sshpass -p "${VM_DEFAULT_PASSWORD}" \ scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ - orka-vm-tools.pkg setup-sys-daemon.sh \ + orka-vm-tools.pkg setup-sys-daemon.sh setup-remote-access.sh \ "admin@${{ steps.vm-ip.outputs.VM_IP }}:~/" - name: Install vm-tools @@ -115,27 +142,10 @@ jobs: env: VM_DEFAULT_PASSWORD: ${{ secrets.VM_DEFAULT_PASSWORD }} run: | - VM_IP="${{ steps.vm-ip.outputs.VM_IP }}" - - sshpass -p "${VM_DEFAULT_PASSWORD}" \ - ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ - "admin@${VM_IP}" \ - "echo ${VM_DEFAULT_PASSWORD} | sudo -S systemsetup -setremotelogin on" - sshpass -p "${VM_DEFAULT_PASSWORD}" \ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ - "admin@${VM_IP}" \ - "echo ${VM_DEFAULT_PASSWORD} | sudo -S launchctl load -w /System/Library/LaunchDaemons/ssh.plist || true" - - sshpass -p "${VM_DEFAULT_PASSWORD}" \ - ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ - "admin@${VM_IP}" \ - "echo ${VM_DEFAULT_PASSWORD} | sudo -S launchctl load -w /System/Library/LaunchDaemons/com.apple.screensharing.plist || true" - - sshpass -p "${VM_DEFAULT_PASSWORD}" \ - ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ - "admin@${VM_IP}" \ - "echo ${VM_DEFAULT_PASSWORD} | sudo -S /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -restart -agent -privs -all" + "admin@${{ steps.vm-ip.outputs.VM_IP }}" \ + "bash ~/setup-remote-access.sh ${VM_DEFAULT_PASSWORD}" - name: Set admin user password env: