ci/release/aws: Setup windows instance

This commit is contained in:
Anmol Sethi 2022-12-15 07:14:06 -08:00
parent d23eb5b332
commit ece68225b1
No known key found for this signature in database
GPG key ID: 25BC68888A99A8BA
3 changed files with 249 additions and 101 deletions

View file

@ -1,11 +1,12 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
. "$(dirname "$0")/../../../../ci/sub/lib.sh" . "$(dirname "$0")/../../../ci/sub/lib.sh"
cd -- "$(dirname "$0")/../../../.." cd -- "$(dirname "$0")/../../.."
help() { help() {
cat <<EOF cat <<EOF
usage: $0 [--dry-run] [--skip-create] [--copy-id=id.pub] usage: $0 [--dry-run] [--skip-create] [--skip-init] [--copy-id=id.pub]
[--run=jobregex]
$0 creates and ensures the d2 builders in AWS. $0 creates and ensures the d2 builders in AWS.
EOF EOF
@ -27,14 +28,14 @@ main() {
flag_noarg && shift "$FLAGSHIFT" flag_noarg && shift "$FLAGSHIFT"
export DRY_RUN=1 export DRY_RUN=1
;; ;;
skip-create)
flag_noarg && shift "$FLAGSHIFT"
SKIP_CREATE=1
;;
copy-id) copy-id)
flag_nonemptyarg && shift "$FLAGSHIFT" flag_nonemptyarg && shift "$FLAGSHIFT"
ID_PUB_PATH=$FLAGARG ID_PUB_PATH=$FLAGARG
;; ;;
run)
flag_reqarg && shift "$FLAGSHIFT"
JOBFILTER="$FLAGARG"
;;
*) *)
flag_errusage "unrecognized flag $FLAGRAW" flag_errusage "unrecognized flag $FLAGRAW"
;; ;;
@ -48,18 +49,26 @@ main() {
flag_errusage "--copy-id is required" flag_errusage "--copy-id is required"
fi fi
if [ -z "${SKIP_CREATE-}" ]; then JOBNAME=create runjob_filter create_remote_hosts
create_remote_hosts JOBNAME=init && runjob_filter init_remote_hosts
fi
init_remote_hosts
} }
create_remote_hosts() { create_remote_hosts() {
bigheader create_remote_hosts bigheader create_remote_hosts
KEY_NAME=$(aws ec2 describe-key-pairs | jq -r .KeyPairs[0].KeyName) KEY_NAME=$(aws ec2 describe-key-pairs | jq -r .KeyPairs[0].KeyName)
KEY_NAME_WINDOWS=windows
VPC_ID=$(aws ec2 describe-vpcs | jq -r .Vpcs[0].VpcId) VPC_ID=$(aws ec2 describe-vpcs | jq -r .Vpcs[0].VpcId)
JOBNAME=$JOBNAME/security-groups runjob_filter create_security_groups
JOBNAME=$JOBNAME/linux/amd64 runjob_filter create_linux_amd64
JOBNAME=$JOBNAME/linux/arm64 runjob_filter create_linux_arm64
JOBNAME=$JOBNAME/macos/amd64 runjob_filter create_macos_amd64
JOBNAME=$JOBNAME/macos/arm64 runjob_filter create_macos_arm64
JOBNAME=$JOBNAME/windows/amd64 runjob_filter create_windows_amd64
}
create_security_groups() {
header security-group header security-group
SG_ID=$(aws ec2 describe-security-groups --group-names ssh 2>/dev/null \ SG_ID=$(aws ec2 describe-security-groups --group-names ssh 2>/dev/null \
| jq -r .SecurityGroups[0].GroupId) | jq -r .SecurityGroups[0].GroupId)
@ -81,36 +90,61 @@ create_remote_hosts() {
--cidr 0.0.0.0/0 >/dev/null --cidr 0.0.0.0/0 >/dev/null
fi fi
header windows-security-group
SG_ID=$(aws ec2 describe-security-groups --group-names windows 2>/dev/null \
| jq -r .SecurityGroups[0].GroupId)
if [ -z "$SG_ID" ]; then
SG_ID=$(sh_c aws ec2 create-security-group \
--group-name windows \
--description windows \
--vpc-id "$VPC_ID" | jq -r .GroupId)
fi
header windows-security-group-ingress
SG_RULES_COUNT=$(aws ec2 describe-security-groups --group-names windows \
| jq -r '.SecurityGroups[0].IpPermissions | length')
if [ "$SG_RULES_COUNT" -ne 2 ]; then
sh_c aws ec2 authorize-security-group-ingress \
--group-id "$SG_ID" \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0 >/dev/null
sh_c aws ec2 authorize-security-group-ingress \
--group-id "$SG_ID" \
--protocol tcp \
--port 3389 \
--cidr 0.0.0.0/0 >/dev/null
fi
}
create_linux_amd64() {
header linux-amd64 header linux-amd64
REMOTE_NAME=ci-d2-linux-amd64
state=$(aws ec2 describe-instances --filters \ state=$(aws ec2 describe-instances --filters \
'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-linux-amd64' \ 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=ci-d2-linux-amd64' \
| jq -r '.Reservations[].Instances[].State.Name') | jq -r '.Reservations[].Instances[].State.Name')
if [ -z "$state" ]; then if [ -z "$state" ]; then
sh_c aws ec2 run-instances \ sh_c aws ec2 run-instances \
--image-id=ami-0ecc74eca1d66d8a6 \ --image-id=ami-0ecc74eca1d66d8a6 \
--count=1 \ --count=1 \
--instance-type=t2.small \ --instance-type=t3.small \
--security-groups=ssh \ --security-groups=ssh \
"--key-name=$KEY_NAME" \ "--key-name=$KEY_NAME" \
--iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \ --iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \
--tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=d2-builder-linux-amd64}]"' \ --block-device-mappings '"DeviceName=/dev/sda1,Ebs={VolumeSize=64,VolumeType=gp3}"' \
'"ResourceType=volume,Tags=[{Key=Name,Value=d2-builder-linux-amd64}]"' >/dev/null --tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=ci-d2-linux-amd64}]"' \
'"ResourceType=volume,Tags=[{Key=Name,Value=ci-d2-linux-amd64}]"' >/dev/null
fi fi
while true; do wait_remote_host_ip
dnsname=$(sh_c aws ec2 describe-instances \ log "CI_D2_LINUX_AMD64=ubuntu@$ip"
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-linux-amd64' \ export CI_D2_LINUX_AMD64=ubuntu@$ip
| jq -r '.Reservations[].Instances[].PublicDnsName') }
if [ -n "$dnsname" ]; then
log "TSTRUCT_LINUX_AMD64_BUILDER=ubuntu@$dnsname"
export TSTRUCT_LINUX_AMD64_BUILDER=ubuntu@$dnsname
break
fi
sleep 5
done
create_linux_arm64() {
header linux-arm64 header linux-arm64
REMOTE_NAME=ci-d2-linux-arm64
state=$(aws ec2 describe-instances --filters \ state=$(aws ec2 describe-instances --filters \
'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-linux-arm64' \ 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=ci-d2-linux-arm64' \
| jq -r '.Reservations[].Instances[].State.Name') | jq -r '.Reservations[].Instances[].State.Name')
if [ -z "$state" ]; then if [ -z "$state" ]; then
sh_c aws ec2 run-instances \ sh_c aws ec2 run-instances \
@ -120,40 +154,28 @@ create_remote_hosts() {
--security-groups=ssh \ --security-groups=ssh \
"--key-name=$KEY_NAME" \ "--key-name=$KEY_NAME" \
--iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \ --iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \
--tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=d2-builder-linux-arm64}]"' \ --block-device-mappings '"DeviceName=/dev/sda1,Ebs={VolumeSize=64,VolumeType=gp3}"' \
'"ResourceType=volume,Tags=[{Key=Name,Value=d2-builder-linux-arm64}]"' >/dev/null --tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=ci-d2-linux-arm64}]"' \
'"ResourceType=volume,Tags=[{Key=Name,Value=ci-d2-linux-arm64}]"' >/dev/null
fi fi
while true; do wait_remote_host_ip
dnsname=$(sh_c aws ec2 describe-instances \ log "CI_D2_LINUX_ARM64=ubuntu@$ip"
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-linux-arm64' \ export CI_D2_LINUX_ARM64=ubuntu@$ip
| jq -r '.Reservations[].Instances[].PublicDnsName') }
if [ -n "$dnsname" ]; then
log "TSTRUCT_LINUX_ARM64_BUILDER=ubuntu@$dnsname"
export TSTRUCT_LINUX_ARM64_BUILDER=ubuntu@$dnsname
break
fi
sleep 5
done
header "macos-amd64-host" create_macos_amd64() {
MACOS_AMD64_HOST_ID=$(aws ec2 describe-hosts --filter 'Name=state,Values=pending,available' 'Name=tag:Name,Values=d2-builder-macos-amd64' | jq -r '.Hosts[].HostId') header macos-amd64-host
if [ -z "$MACOS_AMD64_HOST_ID" ]; then MACOS_AMD64_ID=$(aws ec2 describe-hosts --filter 'Name=state,Values=pending,available' 'Name=tag:Name,Values=ci-d2-macos-amd64' | jq -r '.Hosts[].HostId')
MACOS_AMD64_HOST_ID=$(sh_c aws ec2 allocate-hosts --instance-type mac1.metal --quantity 1 --availability-zone us-west-2a \ if [ -z "$MACOS_AMD64_ID" ]; then
--tag-specifications '"ResourceType=dedicated-host,Tags=[{Key=Name,Value=d2-builder-macos-amd64}]"' \ MACOS_AMD64_ID=$(sh_c aws ec2 allocate-hosts --instance-type mac1.metal --quantity 1 --availability-zone us-west-2a \
| jq -r .HostIds[0]) --tag-specifications '"ResourceType=dedicated-host,Tags=[{Key=Name,Value=ci-d2-macos-amd64}]"' \
fi
header "macos-arm64-host"
MACOS_ARM64_HOST_ID=$(aws ec2 describe-hosts --filter 'Name=state,Values=pending,available' 'Name=tag:Name,Values=d2-builder-macos-arm64' | jq -r '.Hosts[].HostId')
if [ -z "$MACOS_ARM64_HOST_ID" ]; then
MACOS_ARM64_HOST_ID=$(sh_c aws ec2 allocate-hosts --instance-type mac2.metal --quantity 1 --availability-zone us-west-2a \
--tag-specifications '"ResourceType=dedicated-host,Tags=[{Key=Name,Value=d2-builder-macos-amd64}]"' \
| jq -r .HostIds[0]) | jq -r .HostIds[0])
fi fi
header macos-amd64 header macos-amd64
REMOTE_NAME=ci-d2-macos-amd64
state=$(aws ec2 describe-instances --filters \ state=$(aws ec2 describe-instances --filters \
'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-macos-amd64' \ 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=ci-d2-macos-amd64' \
| jq -r '.Reservations[].Instances[].State.Name') | jq -r '.Reservations[].Instances[].State.Name')
if [ -z "$state" ]; then if [ -z "$state" ]; then
sh_c aws ec2 run-instances \ sh_c aws ec2 run-instances \
@ -163,25 +185,29 @@ create_remote_hosts() {
--security-groups=ssh \ --security-groups=ssh \
"--key-name=$KEY_NAME" \ "--key-name=$KEY_NAME" \
--iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \ --iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \
--placement "Tenancy=host,HostId=$MACOS_AMD64_HOST_ID" \ --placement "Tenancy=host,HostId=$MACOS_AMD64_ID" \
--tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=d2-builder-macos-amd64}]"' \ --block-device-mappings '"DeviceName=/dev/sda1,Ebs={VolumeSize=100,VolumeType=gp3}"' \
'"ResourceType=volume,Tags=[{Key=Name,Value=d2-builder-macos-amd64}]"' >/dev/null --tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=ci-d2-macos-amd64}]"' \
'"ResourceType=volume,Tags=[{Key=Name,Value=ci-d2-macos-amd64}]"' >/dev/null
fi fi
while true; do wait_remote_host_ip
dnsname=$(sh_c aws ec2 describe-instances \ log "CI_D2_MACOS_AMD64=ec2-user@$ip"
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-macos-amd64' \ export CI_D2_MACOS_AMD64=ec2-user@$ip
| jq -r '.Reservations[].Instances[].PublicDnsName') }
if [ -n "$dnsname" ]; then
log "TSTRUCT_MACOS_AMD64_BUILDER=ec2-user@$dnsname" create_macos_arm64() {
export TSTRUCT_MACOS_AMD64_BUILDER=ec2-user@$dnsname header macos-arm64-host
break MACOS_ARM64_ID=$(aws ec2 describe-hosts --filter 'Name=state,Values=pending,available' 'Name=tag:Name,Values=ci-d2-macos-arm64' | jq -r '.Hosts[].HostId')
if [ -z "$MACOS_ARM64_ID" ]; then
MACOS_ARM64_ID=$(sh_c aws ec2 allocate-hosts --instance-type mac2.metal --quantity 1 --availability-zone us-west-2a \
--tag-specifications '"ResourceType=dedicated-host,Tags=[{Key=Name,Value=ci-d2-macos-amd64}]"' \
| jq -r .HostIds[0])
fi fi
sleep 5
done
header macos-arm64 header macos-arm64
REMOTE_NAME=ci-d2-macos-arm64
state=$(aws ec2 describe-instances --filters \ state=$(aws ec2 describe-instances --filters \
'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-macos-arm64' \ 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=ci-d2-macos-arm64' \
| jq -r '.Reservations[].Instances[].State.Name') | jq -r '.Reservations[].Instances[].State.Name')
if [ -z "$state" ]; then if [ -z "$state" ]; then
sh_c aws ec2 run-instances \ sh_c aws ec2 run-instances \
@ -191,48 +217,95 @@ create_remote_hosts() {
--security-groups=ssh \ --security-groups=ssh \
"--key-name=$KEY_NAME" \ "--key-name=$KEY_NAME" \
--iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \ --iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \
--placement "Tenancy=host,HostId=$MACOS_ARM64_HOST_ID" \ --placement "Tenancy=host,HostId=$MACOS_ARM64_ID" \
--tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=d2-builder-macos-arm64}]"' \ --block-device-mappings '"DeviceName=/dev/sda1,Ebs={VolumeSize=100,VolumeType=gp3}"' \
'"ResourceType=volume,Tags=[{Key=Name,Value=d2-builder-macos-arm64}]"' >/dev/null --tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=ci-d2-macos-arm64}]"' \
'"ResourceType=volume,Tags=[{Key=Name,Value=ci-d2-macos-arm64}]"' >/dev/null
fi fi
wait_remote_host_ip
log "CI_D2_MACOS_ARM64=ec2-user@$ip"
export CI_D2_MACOS_ARM64=ec2-user@$ip
}
create_windows_amd64() {
header windows-amd64
REMOTE_NAME=ci-d2-windows-amd64
state=$(aws ec2 describe-instances --filters \
'Name=instance-state-name,Values=pending,running,stopping,stopped' "Name=tag:Name,Values=$REMOTE_NAME" \
| jq -r '.Reservations[].Instances[].State.Name')
if [ -z "$state" ]; then
sh_c aws ec2 run-instances \
--image-id=ami-0c5300e833c2b32f3 \
--count=1 \
--instance-type=t3.medium \
--security-groups=windows \
"--key-name=$KEY_NAME_WINDOWS" \
--iam-instance-profile 'Name=AmazonSSMRoleForInstancesQuickSetup' \
--block-device-mappings '"DeviceName=/dev/sda1,Ebs={VolumeSize=64,VolumeType=gp3}"' \
--tag-specifications "'ResourceType=instance,Tags=[{Key=Name,Value=$REMOTE_NAME}]'" \
"'ResourceType=volume,Tags=[{Key=Name,Value=$REMOTE_NAME}]'" >/dev/null
fi
wait_remote_host_ip
log "CI_D2_WINDOWS_AMD64=Administrator@$ip"
export CI_D2_WINDOWS_AMD64=Administrator@$ip
}
wait_remote_host_ip() {
while true; do while true; do
dnsname=$(sh_c aws ec2 describe-instances \ ip=$(sh_c aws ec2 describe-instances \
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-macos-arm64' \ --filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' "Name=tag:Name,Values=$REMOTE_NAME" \
| jq -r '.Reservations[].Instances[].PublicDnsName') | jq -r '.Reservations[].Instances[].PublicIpAddress')
if [ -n "$dnsname" ]; then if [ -n "$ip" ]; then
log "TSTRUCT_MACOS_ARM64_BUILDER=ec2-user@$dnsname" alloc_static_ip
export TSTRUCT_MACOS_ARM64_BUILDER=ec2-user@$dnsname ip=$(sh_c aws ec2 describe-instances \
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' "Name=tag:Name,Values=$REMOTE_NAME" \
| jq -r '.Reservations[].Instances[].PublicIpAddress')
break break
fi fi
sleep 5 sleep 5
done done
} }
alloc_static_ip() {
# No-op until our limit is increased.
return 0
allocation_id=$(aws ec2 describe-addresses --filters "Name=tag:Name,Values=$REMOTE_NAME" | jq -r '.Addresses[].AllocationId')
if [ -z "$allocation_id" ]; then
sh_c aws ec2 allocate-address --tag-specifications "'ResourceType=elastic-ip,Tags=[{Key=Name,Value=$REMOTE_NAME}]'"
allocation_id=$(aws ec2 describe-addresses --filters "Name=tag:Name,Values=$REMOTE_NAME" | jq -r '.Addresses[].AllocationId')
fi
instance_id=$(aws ec2 describe-instances \
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' "Name=tag:Name,Values=$REMOTE_NAME" \
| jq -r '.Reservations[].Instances[].InstanceId')
aws ec2 associate-address --instance-id "$instance_id" --allocation-id "$allocation_id"
}
init_remote_hosts() { init_remote_hosts() {
bigheader init_remote_hosts bigheader init_remote_hosts
header linux-amd64 JOBNAME=$JOBNAME/linux/amd64 runjob_filter REMOTE_HOST=$CI_D2_LINUX_AMD64 REMOTE_NAME=ci-d2-linux-amd64 init_remote_linux
REMOTE_HOST=$TSTRUCT_LINUX_AMD64_BUILDER init_remote_linux JOBNAME=$JOBNAME/linux/arm64 runjob_filter REMOTE_HOST=$CI_D2_LINUX_ARM64 REMOTE_NAME=ci-d2-linux-arm64 init_remote_linux
header linux-arm64 JOBNAME=$JOBNAME/macos/amd64 runjob_filter REMOTE_HOST=$CI_D2_MACOS_AMD64 REMOTE_NAME=ci-d2-macos-amd64 init_remote_macos
REMOTE_HOST=$TSTRUCT_LINUX_ARM64_BUILDER init_remote_linux JOBNAME=$JOBNAME/macos/arm64 runjob_filter REMOTE_HOST=$CI_D2_MACOS_ARM64 REMOTE_NAME=ci-d2-macos-arm64 init_remote_macos
header macos-amd64 JOBNAME=$JOBNAME/windows/amd64 runjob_filter REMOTE_HOST=$CI_D2_WINDOWS_AMD64 REMOTE_NAME=ci-d2-windows-amd64 init_remote_windows
REMOTE_HOST=$TSTRUCT_MACOS_AMD64_BUILDER init_remote_macos
header macos-arm64
REMOTE_HOST=$TSTRUCT_MACOS_ARM64_BUILDER init_remote_macos
FGCOLOR=2 header summary FGCOLOR=2 header summary
echo "export TSTRUCT_LINUX_AMD64_BUILDER=$TSTRUCT_LINUX_AMD64_BUILDER" echo "export CI_D2_LINUX_AMD64=$CI_D2_LINUX_AMD64"
echo "export TSTRUCT_LINUX_ARM64_BUILDER=$TSTRUCT_LINUX_ARM64_BUILDER" echo "export CI_D2_LINUX_ARM64=$CI_D2_LINUX_ARM64"
echo "export TSTRUCT_MACOS_AMD64_BUILDER=$TSTRUCT_MACOS_AMD64_BUILDER" echo "export CI_D2_MACOS_AMD64=$CI_D2_MACOS_AMD64"
echo "export TSTRUCT_MACOS_ARM64_BUILDER=$TSTRUCT_MACOS_ARM64_BUILDER" echo "export CI_D2_MACOS_ARM64=$CI_D2_MACOS_ARM64"
echo "export CI_D2_WINDOWS_AMD64=$CI_D2_WINDOWS_AMD64"
# Windows and AWS SSM both defeated me.
FGCOLOR=3 bigheader "WARNING: WINDOWS INITIALIZATION MUST BE COMPLETED MANUALLY OVER RDP AND POWERSHELL!"
} }
init_remote_linux() { init_remote_linux() {
header "$REMOTE_NAME"
wait_remote_host wait_remote_host
if [ -n "${ID_PUB_PATH-}" ]; then
sh_c ssh_copy_id -i="$ID_PUB_PATH" "$REMOTE_HOST" sh_c ssh_copy_id -i="$ID_PUB_PATH" "$REMOTE_HOST"
fi
sh_c ssh "$REMOTE_HOST" sh -s -- <<EOF sh_c ssh "$REMOTE_HOST" sh -s -- <<EOF
set -eux set -eux
@ -240,6 +313,7 @@ export DEBIAN_FRONTEND=noninteractive
sudo -E apt-get update -y sudo -E apt-get update -y
sudo -E apt-get dist-upgrade -y sudo -E apt-get dist-upgrade -y
sudo -E apt-get update -y
sudo -E apt-get install -y build-essential rsync sudo -E apt-get install -y build-essential rsync
# Docker from https://docs.docker.com/engine/install/ubuntu/ # Docker from https://docs.docker.com/engine/install/ubuntu/
@ -272,6 +346,7 @@ EOF
} }
init_remote_macos() { init_remote_macos() {
header "$REMOTE_NAME"
wait_remote_host wait_remote_host
sh_c ssh "$REMOTE_HOST" '"/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""' sh_c ssh "$REMOTE_HOST" '"/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""'
@ -290,7 +365,6 @@ PATH=\$HOME/.local/bin:\$PATH
MANPATH=\$HOME/.local/share/man:\$MANPATH MANPATH=\$HOME/.local/share/man:\$MANPATH
EOF EOF
fi fi
init_remote_env init_remote_env
sh_c ssh "$REMOTE_HOST" brew update sh_c ssh "$REMOTE_HOST" brew update
sh_c ssh "$REMOTE_HOST" brew upgrade sh_c ssh "$REMOTE_HOST" brew upgrade
@ -322,4 +396,77 @@ wait_remote_host() {
done done
} }
wait_remote_host_windows() {
instance_id=$(aws ec2 describe-instances \
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' "Name=tag:Name,Values=$REMOTE_NAME" \
| jq -r '.Reservations[].Instances[].InstanceId')
while true; do
if sh_c aws ssm start-session --target "$instance_id" \
--document-name 'AWS-StartNonInteractiveCommand' \
--parameters "'{\"command\": [\"echo true; exit\"]}'"; then
break
fi
sleep 5
done
}
init_remote_windows() {
header "$REMOTE_NAME"
wait_remote_host_windows
init_ps1=$(cat <<EOF
\$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri "https://github.com/msys2/msys2-installer/releases/download/2022-10-28/msys2-x86_64-20221028.exe" -OutFile "./msys2-x86_64.exe"
./msys2-x86_64.exe install --default-answer --confirm-command --root C:\msys64
C:\msys64\msys2_shell.cmd -defterm -here -no-start -mingw64 -c 'pacman -Sy --noconfirm base-devel'
C:\msys64\msys2_shell.cmd -defterm -here -no-start -mingw64 -c 'curl -fsSL https://d2lang.com/install.sh | sh -s -- --tala'
C:\msys64\msys2_shell.cmd -defterm -here -no-start -mingw64 -c 'd2 --version'
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.3 -OutFile .\microsoft.ui.xaml.2.7.3.zip
Expand-Archive -Force .\microsoft.ui.xaml.2.7.3.zip
Add-AppxPackage .\microsoft.ui.xaml.2.7.3\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx
Invoke-WebRequest -Uri https://github.com/microsoft/winget-cli/releases/download/v1.3.2691/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle -OutFile .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Invoke-WebRequest -Uri https://github.com/microsoft/winget-cli/releases/download/v1.3.2691/7bcb1a0ab33340daa57fa5b81faec616_License1.xml -OutFile .\7bcb1a0ab33340daa57fa5b81faec616_License1.xml
Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -OutFile Microsoft.VCLibs.x64.14.00.Desktop.appx
Add-AppxProvisionedPackage -online -PackagePath .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle -LicensePath .\7bcb1a0ab33340daa57fa5b81faec616_License1.xml -DependencyPackagePath Microsoft.VCLibs.x64.14.00.Desktop.appx
Add-AppxPackage .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
winget install --silent --accept-package-agreements --accept-source-agreements Microsoft.DotNet.SDK.7
# Refresh env.
\$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
dotnet tool install --global wix --version 4.0.0-preview.1
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'
ConvertFrom-Json -InputObject @'
$(perl -pe 's#\n#\r\n#' "$ID_PUB_PATH" | jq -Rs .)
'@ | Out-File -Encoding utf8 "\$env:ProgramData\ssh\administrators_authorized_keys"
# utf8BOM -> utf8: https://stackoverflow.com/a/34969243/4283659
\$null = New-Item -Force "\$env:ProgramData\ssh\administrators_authorized_keys" -Value (Get-Content -Path "\$env:ProgramData\ssh\administrators_authorized_keys" | Out-String)
get-acl "\$env:ProgramData\ssh\ssh_host_rsa_key" | set-acl "\$env:ProgramData\ssh\administrators_authorized_keys"
EOF
)
gen_init_ps1=$(cat <<EOF
ConvertFrom-Json -InputObject @'
$(printf %s "$init_ps1" | perl -pe 'chomp if eof' | perl -pe 's#\n#\r\n#' | jq -Rs .)
'@ | Out-File -Encoding utf8 C:\Users\Administrator\Desktop\init.ps1; C:\Users\Administrator\Desktop\init.ps1
EOF
)
# Windows and AWS SSM both defeated me.
FGCOLOR=3 bigheader "WARNING: WINDOWS INITIALIZATION MUST BE COMPLETED MANUALLY OVER RDP AND POWERSHELL!"
warn '1. Obtain Windows RDP password with:'
echo " aws ec2 get-password-data --instance-id \$(aws ec2 describe-instances --filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' "Name=tag:Name,Values=$REMOTE_NAME" | jq -r '.Reservations[].Instances[].InstanceId') --priv-launch-key windows.pem | jq -r .PasswordData" >&2
warn "2. RDP into $REMOTE_HOST and open PowerShell."
warn '3. Generate and execute C:\Users\Administrator\Desktop\init.ps1 with:'
printf '%s\n' "$gen_init_ps1" >&2
}
main "$@" main "$@"

View file

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
set -eu set -eu
. "$(dirname "$0")/../../../../ci/sub/lib.sh" . "$(dirname "$0")/../../../ci/sub/lib.sh"
cd -- "$(dirname "$0")/../../../.." cd -- "$(dirname "$0")/../../.."
help() { help() {
cat <<EOF cat <<EOF
@ -33,10 +33,11 @@ main() {
done done
shift "$FLAGSHIFT" shift "$FLAGSHIFT"
REMOTE_HOST=$TSTRUCT_LINUX_AMD64_BUILDER; runjob linux-amd64 ssh "$REMOTE_HOST" "$@" REMOTE_HOST=$CI_HOST_D2_LINUX_AMD64 && runjob linux-amd64 ssh "$REMOTE_HOST" "$@"
REMOTE_HOST=$TSTRUCT_LINUX_ARM64_BUILDER; runjob linux-arm64 ssh "$REMOTE_HOST" "$@" REMOTE_HOST=$CI_HOST_D2_LINUX_ARM64 && runjob linux-arm64 ssh "$REMOTE_HOST" "$@"
REMOTE_HOST=$TSTRUCT_MACOS_AMD64_BUILDER; runjob macos-amd64 ssh "$REMOTE_HOST" "$@" REMOTE_HOST=$CI_HOST_D2_MACOS_AMD64 && runjob macos-amd64 ssh "$REMOTE_HOST" "$@"
REMOTE_HOST=$TSTRUCT_MACOS_ARM64_BUILDER; runjob macos-arm64 ssh "$REMOTE_HOST" "$@" REMOTE_HOST=$CI_HOST_D2_MACOS_ARM64 && runjob macos-arm64 ssh "$REMOTE_HOST" "$@"
REMOTE_HOST=$CI_HOST_D2_WINDOWS_AMD64 && runjob macos-arm64 ssh "$REMOTE_HOST" "$@"
} }
main "$@" main "$@"

2
ci/sub

@ -1 +1 @@
Subproject commit d103a19548c72d68d8aab26da1fda158489252ba Subproject commit 2f309fd0e35f323dfaafdd0075cc3da565fa630c