Skip to content

Instantly share code, notes, and snippets.

@zudljk
Last active April 5, 2024 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zudljk/c5ea17a95a9b396d099c9a96da3f1eb1 to your computer and use it in GitHub Desktop.
Save zudljk/c5ea17a95a9b396d099c9a96da3f1eb1 to your computer and use it in GitHub Desktop.
A bash script and equivalent PowerShell script that starts a remote Paperspace instance, starts VirtualHere USB server locally, and creates an SSH tunnel to forward the USB server to the remote instance. Press Ctrl-C to exit the script and shut down the remote instance.
function Get-PublicIP {
param(
[string]$MachineId,
[string]$ApiKey
)
$Headers = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer $ApiKey"
}
$Response = Invoke-RestMethod -Uri "https://api.paperspace.io/machines/$MachineId" -Headers $Headers
$PublicIP = $Response.ip
return $PublicIP
}
function Start-Machine {
param(
[string]$MachineId,
[string]$ApiKey
)
$Headers = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer $ApiKey"
}
Invoke-RestMethod -Uri "https://api.paperspace.io/machines/$MachineId/start" -Headers $Headers
# Wait until machine is ready
while ($true) {
$State = Check-State -MachineId $MachineId -ApiKey $ApiKey
if ($State -eq "ready") {
break
}
Start-Sleep -Seconds 5
}
}
function Check-State {
param(
[string]$MachineId,
[string]$ApiKey
)
$Headers = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer $ApiKey"
}
$Response = Invoke-RestMethod -Uri "https://api.paperspace.io/machines/$MachineId" -Headers $Headers
$State = $Response.state
return $State
}
function Stop-Machine {
param(
[string]$MachineId,
[string]$ApiKey
)
$Headers = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer $ApiKey"
}
Invoke-RestMethod -Method Post -Uri "https://api.paperspace.io/machines/$MachineId/stop" -Headers $Headers
# Wait until machine is stopped
while ($true) {
$State = Check-State -MachineId $MachineId -ApiKey $ApiKey
if ($State -eq "off") {
break
}
Start-Sleep -Seconds 5
}
}
function Determine-HostName {
param(
[string[]]$Ids
)
foreach ($id in $Ids) {
$sshOutput = ssh -G $id
$hostLine = $sshOutput | Select-String -Pattern '^HostName' -IgnoreCase
if ($hostLine) {
$thehost = ($hostLine -split '\s+')[1]
return $thehost
}
}
}
Write-Host "Starting USB server ..."
Start-Process "C:\Program Files\VirtualHere\vhusbdwin64.exe"
# Get the public IP of the machine
$PUBLIC_IP = Get-PublicIP -MachineId $args[0] -ApiKey $args[1]
$THE_HOST = Determine-HostName -Ids $args[0], $PUBLIC_IP
# Start the machine
Start-Machine -MachineId $args[0] -ApiKey $args[1]
# Create SSH tunnel
Write-Host "Creating SSH tunnel..."
Start-Process ssh -ArgumentList "-N -R 7575:localhost:7575 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $THE_HOST" -NoNewWindow
# Trap Ctrl-C to stop the machine and close the SSH tunnel
Write-Host "Press Ctrl-C to stop the machine and close the SSH tunnel..."
$null = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Stop-Machine -MachineId $args[0] -ApiKey $args[1]
Stop-Process -Name "ssh"
#!/bin/bash
# Function to retrieve the public IP of the Paperspace machine
get_public_ip() {
machine_id=$1
api_key=$2
public_ip=$(curl -s \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $api_key" \
https://api.paperspace.io/machines/$machine_id | jq -r '.ip')
echo $public_ip
}
# Function to start the Paperspace machine
start_machine() {
machine_id=$1
api_key=$2
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $api_key" \
-d '{"machineId": "'"$machine_id"'"}' \
https://api.paperspace.io/machines/$machine_id/start
# Wait until machine is ready
while true; do
state=$(check_state $1)
if [ "$state" = "ready" ]; then
break
fi
sleep 5
done
}
# Function to check the state of the Paperspace machine
check_state() {
machine_id=$1
api_key=$2
state=$(curl -s \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ap_key" \
https://api.paperspace.io/machines/$machine_id | jq -r '.state')
echo $state
}
# Function to stop the Paperspace machine
stop_machine() {
machine_id=$1
api_key=$2
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $api_key" \
-d '{"machineId": "'"$machine_id"'"}' \
https://api.paperspace.io/machines/$machine_id/stop
# Wait until machine is stopped
while true; do
state=$(check_state $1)
if [ "$state" = "off" ]; then
break
fi
sleep 5
done
}
determine_host_name() {
for id in $* ; do
ssh -G $id | grep -i ^HostName | read key host
if [ -n "$host" ] ; then
echo $host
break
fi
done
}
echo "Starting USB server ..."
/Applications/VirtualHereServerUniversal.app/Contents/MacOS/vhusbdosx || echo "Cannot start USB server; maybe already started?"
# Get the public IP of the machine
PUBLIC_IP=$(get_public_ip $1)
HOST=$(determine_host_name $PUBLIC_IP $1)
# Start the machine
start_machine $1
# Create SSH tunnel
echo "Creating SSH tunnel..."
ssh -N -R 7575:localhost:7575 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $HOST &
# Trap Ctrl-C to stop the machine and close the SSH tunnel
trap 'stop_machine $1' INT
# Wait until user presses Ctrl-C
echo "Press Ctrl-C to stop the machine and close the SSH tunnel..."
while true; do
sleep 1
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment