From 536bb78984085b0ca70295ef0ec13e36e2e40b52 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Mon, 21 Jul 2025 12:50:50 -0700 Subject: [PATCH] update remote-workstation scripts for new GCP account - Create with private IP on shared subnet - Use regular ssh instead of gcloud ssh - Update deps.sh to remove packages that don't exist anymore --- hack/remote-workstation/create.sh | 64 +++++++++++++++++++---- hack/remote-workstation/delete.sh | 5 ++ hack/remote-workstation/lib/deps.sh | 12 ++--- hack/remote-workstation/rsync-to-local.sh | 30 +++++++---- hack/remote-workstation/rsync.sh | 30 +++++++---- hack/remote-workstation/ssh.sh | 16 +++++- hack/remote-workstation/start.sh | 5 ++ hack/remote-workstation/stop.sh | 5 ++ 8 files changed, 124 insertions(+), 43 deletions(-) diff --git a/hack/remote-workstation/create.sh b/hack/remote-workstation/create.sh index 8b0c86130..3dd9286ad 100755 --- a/hack/remote-workstation/create.sh +++ b/hack/remote-workstation/create.sh @@ -10,6 +10,26 @@ if [[ -z "${PINNIPED_GCP_PROJECT:-}" ]]; then exit 1 fi +if [[ -z "${SHARED_VPC_PROJECT:-}" ]]; then + echo "SHARED_VPC_PROJECT env var must be set" + exit 1 +fi + +if [[ -z "${SUBNET_NAME:-}" ]]; then + echo "SUBNET_NAME env var must be set" + exit 1 +fi + +if [[ -z "${DISK_IMAGES_PROJECT:-}" ]]; then + echo "DISK_IMAGES_PROJECT env var must be set" + exit 1 +fi + +if ! gcloud auth print-access-token &>/dev/null; then + echo "Please run \`gcloud auth login\` and try again." + exit 1 +fi + instance_name="${REMOTE_INSTANCE_NAME:-${USER}}" instance_user="${REMOTE_INSTANCE_USERNAME:-${USER}}" project="$PINNIPED_GCP_PROJECT" @@ -21,23 +41,45 @@ echo "Creating VM with name $instance_name..." gcloud compute instances create "$instance_name" \ --project="$project" --zone="$zone" \ --machine-type="e2-standard-8" \ - --boot-disk-size="40GB" --boot-disk-type="pd-ssd" --boot-disk-device-name="$instance_name" + --network-interface=stack-type=IPV4_ONLY,subnet=projects/"$SHARED_VPC_PROJECT"/regions/us-west1/subnetworks/"${SUBNET_NAME}",no-address \ + --create-disk=auto-delete=yes,boot=yes,device-name="$instance_name",image=projects/"${DISK_IMAGES_PROJECT}"/global/images/labs-saas-gcp-debian12-packer-latest,mode=rw,size=40,type=pd-ssd -# Give a little time for the server to be ready. -while true; do - sleep 5 - if ! "$here"/ssh.sh ls; then - echo "Waiting for VM to be accessible via ssh..." - else - echo "VM ready!" - break +# Make a private key for ssh. +ssh_key_file="$HOME/.ssh/gcp-remote-workstation-key" +if [[ ! -f "$ssh_key_file" ]]; then + ssh-keygen -t rsa -b 4096 -q -N "" -f "$ssh_key_file" +fi + +# Add the key only to the specific VM instance (as VM metadata). +echo "${instance_user}:$(cat "${ssh_key_file}.pub")" >/tmp/ssh-key-values +gcloud compute instances add-metadata "$instance_name" \ + --metadata-from-file ssh-keys=/tmp/ssh-key-values \ + --zone "$zone" --project "$project" + +# Get the IP so we can use regular ssh (not gcloud ssh). +gcloud_instance_ip=$(gcloud compute instances describe \ + --zone "$zone" --project "$project" "${instance_name}" \ + --format='get(networkInterfaces[0].networkIP)') + +ssh_dest="${instance_user}@${gcloud_instance_ip}" + +# Wait for the ssh server of the new instance to be ready. +attempts=0 +while ! ssh -i "$ssh_key_file" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$ssh_dest" echo connection test; do + echo "Waiting for ssh server to start ..." + attempts=$((attempts + 1)) + if [[ $attempts -gt 25 ]]; then + echo "ERROR: ssh server never accepted connections after waiting for a while" + exit 1 fi + sleep 2 done # Copy the deps script to the new VM. echo "Copying deps.sh to $instance_name..." -gcloud compute scp "$here"/lib/deps.sh "$instance_user@$instance_name":/tmp \ - --project="$project" --zone="$zone" +scp -i "$ssh_key_file" \ + -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "$here"/lib/deps.sh "$ssh_dest":/tmp # Run the deps script on the new VM. "$here"/ssh.sh /tmp/deps.sh diff --git a/hack/remote-workstation/delete.sh b/hack/remote-workstation/delete.sh index 7b1e48bf3..8c7387a68 100755 --- a/hack/remote-workstation/delete.sh +++ b/hack/remote-workstation/delete.sh @@ -10,6 +10,11 @@ if [[ -z "${PINNIPED_GCP_PROJECT:-}" ]]; then exit 1 fi +if ! gcloud auth print-access-token &>/dev/null; then + echo "Please run \`gcloud auth login\` and try again." + exit 1 +fi + instance_name="${REMOTE_INSTANCE_NAME:-${USER}}" project="$PINNIPED_GCP_PROJECT" zone="us-west1-a" diff --git a/hack/remote-workstation/lib/deps.sh b/hack/remote-workstation/lib/deps.sh index a936d1015..e20515414 100755 --- a/hack/remote-workstation/lib/deps.sh +++ b/hack/remote-workstation/lib/deps.sh @@ -19,12 +19,10 @@ brew install gcc # Install go. brew install go -# On linux go really wants gcc5 to also be installed for some reason. -brew install gcc@5 # Install and configure zsh and plugins. brew install zsh zsh-history-substring-search -brew install fasd fzf +brew install fzf /home/linuxbrew/.linuxbrew/opt/fzf/install --all --no-bash --no-fish # Install https://ohmyz.sh export PATH=$PATH:/home/linuxbrew/.linuxbrew/bin @@ -46,11 +44,11 @@ curl -fsSL https://gist.githubusercontent.com/cfryanr/80ada8af9a78f08b368327401e # Install other useful packages. brew tap homebrew/command-not-found -brew tap vmware-tanzu/carvel +brew tap carvel-dev/carvel brew install ytt kbld kapp imgpkg kwt vendir brew install git git-duet/tap/git-duet pre-commit gh brew install k9s kind kubectl kubectx stern -brew install exa acarl005/homebrew-formulas/ls-go ripgrep procs bat tokei git-delta dust fd httpie chroma +brew install acarl005/homebrew-formulas/ls-go ripgrep procs bat tokei git-delta dust fd httpie chroma brew install watch htop wget brew install jesseduffield/lazydocker/lazydocker ctop dive brew install jq yq @@ -81,9 +79,7 @@ sudo systemctl enable containerd.service mkdir workspace pushd workspace ssh-keyscan -H github.com >> $HOME/.ssh/known_hosts -# This assumes that you used `--ssh-flag=-A` when using `gcloud compute ssh` to log in to the host, -# which will forward your ssh identities. -git clone git@github.com:vmware-tanzu/pinniped.git +git clone https://github.com/vmware/pinniped.git pushd pinniped pre-commit install ./hack/install-linter.sh diff --git a/hack/remote-workstation/rsync-to-local.sh b/hack/remote-workstation/rsync-to-local.sh index b7898229d..d62ac3501 100755 --- a/hack/remote-workstation/rsync-to-local.sh +++ b/hack/remote-workstation/rsync-to-local.sh @@ -13,6 +13,11 @@ if [[ -z "${PINNIPED_GCP_PROJECT:-}" ]]; then exit 1 fi +if ! gcloud auth print-access-token &>/dev/null; then + echo "Please run \`gcloud auth login\` and try again." + exit 1 +fi + SRC_DIR=${SRC_DIR:-"$HOME/workspace/pinniped"} src_dir_parent=$(dirname "$SRC_DIR") dest_dir="./workspace/pinniped" @@ -20,21 +25,24 @@ instance_name="${REMOTE_INSTANCE_NAME:-${USER}}" instance_user="${REMOTE_INSTANCE_USERNAME:-${USER}}" project="$PINNIPED_GCP_PROJECT" zone="us-west1-a" -config_file="/tmp/gcp-ssh-config" here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ssh_key_file="$HOME/.ssh/gcp-remote-workstation-key" + +# Get the IP so we can use regular ssh (not gcloud ssh). +gcloud_instance_ip=$(gcloud compute instances describe \ + --zone "$zone" --project "$project" "${instance_name}" \ + --format='get(networkInterfaces[0].networkIP)') + +ssh_dest="${instance_user}@${gcloud_instance_ip}" if [[ ! -d "$SRC_DIR" ]]; then echo "ERROR: $SRC_DIR does not exist" exit 1 fi -# Get the ssh fingerprints of all the GCP VMs. -gcloud compute config-ssh --ssh-config-file="$config_file" \ - --project="$project" >/dev/null - cd "$SRC_DIR" -local_commit=$(git rev-parse --short HEAD) -remote_commit=$("$here"/ssh.sh "cd $dest_dir; git rev-parse --short HEAD" 2>/dev/null | tr -dc '[:print:]') +local_commit=$(git rev-parse HEAD) +remote_commit=$("$here"/ssh.sh "cd $dest_dir; git rev-parse HEAD" 2>/dev/null | tr -dc '[:print:]') if [[ -z "$local_commit" || -z "$remote_commit" ]]; then echo "ERROR: Could not determine currently checked out git commit sha" @@ -43,8 +51,8 @@ fi if [[ "$local_commit" != "$remote_commit" ]]; then echo "ERROR: Local and remote repos are not on the same commit. This is usually a mistake." - echo "Local was $SRC_DIR at *${local_commit}*" - echo "Remote was ${instance_name}:${dest_dir} at *${remote_commit}*" + echo "Local was $SRC_DIR at ${local_commit}" + echo "Remote was ${instance_name}:${dest_dir} at ${remote_commit}" exit 1 fi @@ -55,5 +63,5 @@ rsync \ --progress --delete --archive --compress --human-readable \ --max-size 200K \ --exclude .git/ --exclude .idea/ --exclude .DS_Store --exclude '*.test' --exclude '*.out' \ - --rsh "ssh -F $config_file" \ - "${instance_user}@${instance_name}.${zone}.${project}:$dest_dir" "$src_dir_parent" + --rsh "ssh -i '$ssh_key_file' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ + "$ssh_dest:$dest_dir" "$src_dir_parent" diff --git a/hack/remote-workstation/rsync.sh b/hack/remote-workstation/rsync.sh index 63d89d7e0..c51d12da8 100755 --- a/hack/remote-workstation/rsync.sh +++ b/hack/remote-workstation/rsync.sh @@ -13,27 +13,35 @@ if [[ -z "${PINNIPED_GCP_PROJECT:-}" ]]; then exit 1 fi +if ! gcloud auth print-access-token &>/dev/null; then + echo "Please run \`gcloud auth login\` and try again." + exit 1 +fi + SRC_DIR=${SRC_DIR:-"$HOME/workspace/pinniped"} dest_dir="./workspace" instance_name="${REMOTE_INSTANCE_NAME:-${USER}}" instance_user="${REMOTE_INSTANCE_USERNAME:-${USER}}" project="$PINNIPED_GCP_PROJECT" zone="us-west1-a" -config_file="/tmp/gcp-ssh-config" here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ssh_key_file="$HOME/.ssh/gcp-remote-workstation-key" + +# Get the IP so we can use regular ssh (not gcloud ssh). +gcloud_instance_ip=$(gcloud compute instances describe \ + --zone "$zone" --project "$project" "${instance_name}" \ + --format='get(networkInterfaces[0].networkIP)') + +ssh_dest="${instance_user}@${gcloud_instance_ip}" if [[ ! -d "$SRC_DIR" ]]; then echo "ERROR: $SRC_DIR does not exist" exit 1 fi -# Get the ssh fingerprints of all the GCP VMs. -gcloud compute config-ssh --ssh-config-file="$config_file" \ - --project="$project" >/dev/null - cd "$SRC_DIR" -local_commit=$(git rev-parse --short HEAD) -remote_commit=$("$here"/ssh.sh "cd $dest_dir/pinniped; git rev-parse --short HEAD" 2>/dev/null | tr -dc '[:print:]') +local_commit=$(git rev-parse HEAD) +remote_commit=$("$here"/ssh.sh "cd $dest_dir/pinniped; git rev-parse HEAD" 2>/dev/null | tr -dc '[:print:]') if [[ -z "$local_commit" || -z "$remote_commit" ]]; then echo "ERROR: Could not determine currently checked out git commit sha" @@ -42,8 +50,8 @@ fi if [[ "$local_commit" != "$remote_commit" ]]; then echo "ERROR: Local and remote repos are not on the same commit. This is usually a mistake." - echo "Local was $SRC_DIR at *${local_commit}*" - echo "Remote was ${instance_name}:${dest_dir}/pinniped at *${remote_commit}*" + echo "Local was $SRC_DIR at ${local_commit}" + echo "Remote was ${instance_name}:${dest_dir}/pinniped at ${remote_commit}" exit 1 fi @@ -54,5 +62,5 @@ rsync \ --progress --delete --archive --compress --human-readable \ --max-size 200K \ --exclude .git/ --exclude .idea/ --exclude .DS_Store --exclude '*.test' --exclude '*.out' \ - --rsh "ssh -F $config_file" \ - "$SRC_DIR" "${instance_user}@${instance_name}.${zone}.${project}:$dest_dir" + --rsh "ssh -i '$ssh_key_file' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ + "$SRC_DIR" "$ssh_dest:$dest_dir" diff --git a/hack/remote-workstation/ssh.sh b/hack/remote-workstation/ssh.sh index 43c92340f..9f841c924 100755 --- a/hack/remote-workstation/ssh.sh +++ b/hack/remote-workstation/ssh.sh @@ -10,13 +10,25 @@ if [[ -z "${PINNIPED_GCP_PROJECT:-}" ]]; then exit 1 fi +if ! gcloud auth print-access-token &>/dev/null; then + echo "Please run \`gcloud auth login\` and try again." + exit 1 +fi + instance_name="${REMOTE_INSTANCE_NAME:-${USER}}" instance_user="${REMOTE_INSTANCE_USERNAME:-${USER}}" project="$PINNIPED_GCP_PROJECT" zone="us-west1-a" +ssh_key_file="$HOME/.ssh/gcp-remote-workstation-key" + +# Get the IP so we can use regular ssh (not gcloud ssh). +gcloud_instance_ip=$(gcloud compute instances describe \ + --zone "$zone" --project "$project" "${instance_name}" \ + --format='get(networkInterfaces[0].networkIP)') + +ssh_dest="${instance_user}@${gcloud_instance_ip}" # Run ssh with identities forwarded so you can use them with git on the remote host. # Optionally run an arbitrary command on the remote host. # By default, start an interactive session. -gcloud compute ssh --ssh-flag=-A "$instance_user@$instance_name" \ - --project="$project" --zone="$zone" -- "$@" +ssh -i "$ssh_key_file" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -A "$ssh_dest" -- "$@" diff --git a/hack/remote-workstation/start.sh b/hack/remote-workstation/start.sh index 169e9f78b..f980c91ad 100755 --- a/hack/remote-workstation/start.sh +++ b/hack/remote-workstation/start.sh @@ -10,6 +10,11 @@ if [[ -z "${PINNIPED_GCP_PROJECT:-}" ]]; then exit 1 fi +if ! gcloud auth print-access-token &>/dev/null; then + echo "Please run \`gcloud auth login\` and try again." + exit 1 +fi + instance_name="${REMOTE_INSTANCE_NAME:-${USER}}" project="$PINNIPED_GCP_PROJECT" zone="us-west1-a" diff --git a/hack/remote-workstation/stop.sh b/hack/remote-workstation/stop.sh index 4951c87b3..7ffe54752 100755 --- a/hack/remote-workstation/stop.sh +++ b/hack/remote-workstation/stop.sh @@ -10,6 +10,11 @@ if [[ -z "${PINNIPED_GCP_PROJECT:-}" ]]; then exit 1 fi +if ! gcloud auth print-access-token &>/dev/null; then + echo "Please run \`gcloud auth login\` and try again." + exit 1 +fi + instance_name="${REMOTE_INSTANCE_NAME:-${USER}}" project="$PINNIPED_GCP_PROJECT" zone="us-west1-a"