Skip to content

Instantly share code, notes, and snippets.

@YOU54F
Created October 4, 2023 14:40
Show Gist options
  • Save YOU54F/789c53ae8380a1f90325952615635f8a to your computer and use it in GitHub Desktop.
Save YOU54F/789c53ae8380a1f90325952615635f8a to your computer and use it in GitHub Desktop.
Run GitHub Actions projects, locally, using on Parallels Virtual Machines
#!/bin/bash -l
# prlctl-ssh
# ==========
# Parallels Desktop command line utility for open a new SSH connection to a given virtual machine.
# If the virtual machine is stopped or suspended the utility will attempt to respawn it before it attemts to SSH into the machine.
# ## Preconditions
# 1. `Paralells tools` has to be installed, this is becuase the utility uses the `prlctl exec` command to find the machine's IP address.
# 2. The virtual machine must be running SSH server with a working ssh key set up for the `user`.
# Tested with Ubuntu Server 10.04 LTS and 12.04 LTS.
# ## Usage
# $ ./prlctl-ssh <user>@<vm_id|vm_name>
# ### Make a shortcut cmd
# Make a shortcut to your favorite virtual machine by adding an alias to you `.bash_profile`
# $ alias mymachine=./prlctl-ssh user@mymachine
# get status of vm
# @param $1 vm-name or id
getVmStatus() {
prlctl list -o status $1 | tail -1
return 0
}
# Get default interface of the vm
# @param $1 vm-name or id
getVmIface() {
prlctl exec $1 route | grep '^default' | grep -o '[^ ]*$'
return 0
}
# get ip address of vm
# @param $1 vm-name or id
# getVmAddr() {
# prlctl exec $1 ifconfig `getVmIface $vm` | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'
# return 0
# }
getVmAddr() {
prlctl exec "$1" ipconfig | grep IPv4 | cut -d: -f2 | tr -d '[:space:]'
return 0
}
# takes a snapshot and returns the id of the snaphot
vmSnapshot() {
prlctl snapshot "$1" --name "$1"clone | grep -o '{[^}]*}' | tr -d '{}'
return 0
}
vmSnapshotDelete() {
prlctl snapshot-delete "$1" --id "$2"
return 0
}
# restore a snapshot
# @param $1 vm-name or id
# @param $2 snapshot id
vmSnapshotSwitch() {
prlctl snapshot-switch "$1" --id "$2"
return 0
}
# Windows 11
# Windows IP Configuration
# Connection-specific DNS Suffix . : localdomain
# IPv4 Address. . . . . . . . . . . : 10.211.55.24
IFS='@' read -r -a array <<< "$1"
user=${array[0]}
vm=${array[1]}
act=${2}
keep=${3:-$2}
running=0
addr=""
snapshot_id=""
function cleanup {
echo "Cleaning up..."
prlctl stop "$vm"
if [ "$keep" == "keep" ]; then
echo "no snapshot"
else
vmSnapshotSwitch "$vm" "$snapshot_id"
vmSnapshotDelete "$vm" "$snapshot_id"
fi
}
trap cleanup EXIT
while [ $running == 0 ]; do
state=$(getVmStatus "$vm")
case "$state" in
running )
echo "virtual machine $vm is running"
addr=$(getVmAddr "$vm")
running=1
;;
suspended ) echo "Resuming virtual machine $vm"
prlctl resume "$vm"
sleep 5
;;
stopped ) echo "Starting virtual machine $vm"
if [ "$keep" == "keep" ]; then
echo "this vm will be preserved"
else
snapshot_id=$(vmSnapshot "$vm")
fi
prlctl start "$vm"
sleep 20
;;
*) echo "Unknown status $state of virtual machine $vm"
running=1;
;;
esac
done
if [ "$addr" != "" ] && [ "$act" == "act" ]; then
echo "$*"
PLATFORM=windows-latest
WORKFLOW=${WORKFLOW:-.github/workflows/test.yml}
prlctl set "$vm" --shf-host-add work_dir --path "$PWD"
passh -p "$SSH_PASS" ssh $user@$addr -o StrictHostKeyChecking=accept-new "net use;cd \\\Mac\\work_dir; act -P ${PLATFORM}=-self-hosted -W ${WORKFLOW} --matrix os:${PLATFORM} -C \\\Mac\\work_dir --env WORK_DIR=\\\Mac\\work_dir ${ACT_ARGS}"
ACT_EXIT_CODE="$?"
prlctl set "$vm" --shf-host-del work_dir
elif [ "$addr" != "" ]; then
passh -p "$SSH_PASS" ssh $user@$addr -o StrictHostKeyChecking=accept-new
fi
if [ "$ACT_EXIT_CODE" ]; then
exit "$ACT_EXIT_CODE"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment