diff --git a/scripts/build/run_build_macos_arm64.sh b/scripts/build/run_build_macos_arm64.sh index b2a62306a..997425776 100755 --- a/scripts/build/run_build_macos_arm64.sh +++ b/scripts/build/run_build_macos_arm64.sh @@ -5,36 +5,61 @@ # This script is designed to run on a local machine: it will clone the repos # remotely and execute the `build_macos_arm64.sh` script remotely, then will # download the built packages. A tag to build must be specified. -# -# In order to run the script, the `m1` host must be specified in -# `~/.ssh/config`; for instance: -# -# Host m1 -# User m1 -# HostName 1.2.3.4 + +# The script requires a Scaleway secret key in the SCW_SECRET_KEY env var: +# It will use scaleway_m1.sh to provision a server and use it. set -euo pipefail # set -x +function log { + echo "$@" >&2 +} +function error { + # Print an error message and exit. + log "ERROR: $@" + exit 1 +} + tag=${1:-} if [[ ! "${tag}" ]]; then - echo "Usage: $0 TAG" >&2 - exit 2 + error "Usage: $0 REF" fi -rdir=psycobuild +dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# Clone the repos -ssh m1 rm -rf "${rdir}" -ssh m1 git clone https://github.com/psycopg/psycopg2.git --branch ${tag} "${rdir}" +server=$("${dir}/scaleway_m1.sh" ensure) -# Allow sudoing without password, to allow brew to install -ssh -t m1 bash -c \ - 'test -f /etc/sudoers.d/m1 || echo "m1 ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/m1' +status=$(echo "$server" | jq -r .status) +if [[ "$status" != "ready" ]]; then + error "server status is $status" +fi + +# Get user, password, ip from vnc url +tmp=$(echo "$server" | jq -r .vnc_url) # vnc://m1:PASS@1.2.3.4:5900 +tmp=${tmp/vnc:\/\//} # m1:PASS@1.2.3.4:5900 +user=${tmp%%:*} # m1 +tmp=${tmp#*:} # PASS@1.2.3.4:5900 +password=${tmp%%@*} # PASS +tmp=${tmp#*@} # 1.2.3.4:5900 +host=${tmp%%:*} # 1.2.3.4 + +ssh="ssh ${user}@${host} -o StrictHostKeyChecking=no" + +# Allow the user to sudo without asking for password. +echo "$password" | \ + $ssh sh -c "test -f /etc/sudoers.d/${user} \ + || sudo -S --prompt= sh -c \ + 'echo \"${user} ALL=(ALL) NOPASSWD:ALL\" > /etc/sudoers.d/${user}'" + +# Clone the repos +rdir=psycobuild +$ssh rm -rf "${rdir}" +$ssh git clone https://github.com/psycopg/psycopg2.git --branch ${tag} "${rdir}" # Build the wheel packages -ssh m1 "${rdir}/scripts/build/build_macos_arm64.sh" +$ssh "${rdir}/scripts/build/build_macos_arm64.sh" # Transfer the packages locally -scp -r "m1:${rdir}/wheelhouse" . +scp -r "${user}@${host}:${rdir}/wheelhouse" . diff --git a/scripts/build/scaleway_m1.sh b/scripts/build/scaleway_m1.sh new file mode 100755 index 000000000..cc0fa6ef1 --- /dev/null +++ b/scripts/build/scaleway_m1.sh @@ -0,0 +1,119 @@ +#!/bin/bash + +# Implement the following commands: +# +# ensure: +# +# Get data about currently provisioned M1 server on Scaleway. If needed, +# provision one. +# +# The script requires the SCW_SECRET_KEY env var set to a valid secret. +# +# If successful, return the response data on stdout. It may look like: +# +# { +# "id": "8b196119-3cea-4a9d-b916-265037a85e60", +# "type": "M1-M", +# "name": "mac-m1-psycopg", +# "project_id": "4cf7a85e-f21e-40d4-b758-21d1f4ad3dfb", +# "organization_id": "4cf7a85e-f21e-40d4-b758-21d1f4ad3dfb", +# "ip": "1.2.3.4", +# "vnc_url": "vnc://m1:PASSWORD@1.2.3.4:5900", +# "status": "starting", +# "created_at": "2023-09-22T18:00:18.754646Z", +# "updated_at": "2023-09-22T18:00:18.754646Z", +# "deletable_at": "2023-09-23T18:00:18.754646Z", +# "zone": "fr-par-3" +# } +# +# delete: +# +# Delete one provisioned server, if available. +# +# See https://www.scaleway.com/en/developers/api/apple-silicon/ for api docs. + +set -euo pipefail +# set -x + +project_id="4cf7a85e-f21e-40d4-b758-21d1f4ad3dfb" +zone=fr-par-3 +servers_url="https://api.scaleway.com/apple-silicon/v1alpha1/zones/${zone}/servers" + +function log { + echo "$@" >&2 +} +function error { + log "ERROR: $@" + exit 1 +} + +function req { + method=$1 + shift + curl -sSL --fail-with-body -X $method \ + -H "Content-Type: application/json" \ + -H "X-Auth-Token: ${SCW_SECRET_KEY}" \ + "$@" +} +function get { + req GET "$@" +} +function post { + req POST "$@" +} +function delete { + req DELETE "$@" +} + +function server_id { + # Return the id of the first server available, else the empty string + servers=$(get $servers_url || error "failed to request servers list") + server_ids=$(echo "$servers" | jq -r ".servers[].id") + for id in $server_ids; do + echo $id + break + done +} + +function maybe_jq { + # Process the output via jq if displaying on console, otherwise leave + # it unprocessed. + if [ -t 1 ]; then + jq . + else + cat + fi +} + +cmd=${1:-list} +case $cmd in + ensure) + id=$(server_id) + if [[ "$id" ]]; then + log "You have servers." + get "$servers_url/$id" | maybe_jq + else + log "Creating new server." + post $servers_url -d " + { + \"name\": \"mac-m1-psycopg\", + \"project_id\": \"$project_id\", + \"type\": \"M1-M\" + }" | maybe_jq + fi + ;; + delete) + id=$(server_id) + if [[ "$id" ]]; then + log "Deleting server $id." + delete "$servers_url/$id" | maybe_jq + else + log "No server found." + fi + ;; + list) + get $servers_url | maybe_jq + ;; + *) + error "Usage: $(basename $0) [list|ensure|delete]" +esac