@@ -580,7 +580,7 @@ tasks:
580580 - |
581581 echo "Deleting CMX VM {{.CMX_VM_NAME}}..."
582582 replicated vm rm {{.CMX_VM_NAME}}
583-
583+
584584 cmx-vm-install :
585585 desc : Download and install the app as Embedded Cluster on CMX VM
586586 silent : true
@@ -589,6 +589,7 @@ tasks:
589589 vars :
590590 CHANNEL : ' {{.CHANNEL | default "Unstable"}}'
591591 SKIP_INSTALL : ' {{.SKIP_INSTALL | default "false"}}'
592+ AIRGAP : ' {{.AIRGAP | default "false"}}'
592593 ADMIN_CONSOLE_PASSWORD :
593594 sh : uuidgen | cut -c1-13
594595 deps :
@@ -610,34 +611,125 @@ tasks:
610611 exit 1
611612 fi
612613
614+ # Run airgap-build task if airgap mode is enabled
615+ if [ "{{.AIRGAP}}" = "true" ]; then
616+ echo "Airgap mode enabled, ensuring airgap build is ready..."
617+ task airgap-build
618+ fi
619+
613620 echo "SSH into the VM and download the app binary..."
614621 SSH_BASE_CMD="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
615622 if [ -n "{{.CMX_VM_PUBLIC_KEY}}" ]; then
616623 SSH_BASE_CMD="$SSH_BASE_CMD -i {{.CMX_VM_PUBLIC_KEY}}"
617624 fi
618625 VM_SSH_CMD=$(replicated vm ls --output=json | jq -r ".[] | select(.name == \"{{.CMX_VM_NAME}}\") | \"$SSH_BASE_CMD -p \(.direct_ssh_port) {{.CMX_VM_USER}}@\(.direct_ssh_endpoint)\"")
619626
627+ # Determine download URL based on airgap setting
628+ DOWNLOAD_URL="https://replicated.app/embedded/{{.APP_SLUG}}/{{.CHANNEL}}"
629+ if [ "{{.AIRGAP}}" = "true" ]; then
630+ DOWNLOAD_URL="${DOWNLOAD_URL}?airgap=true"
631+ fi
632+
620633 echo "SSH base command: $SSH_BASE_CMD"
621- $VM_SSH_CMD << ' EOF'
634+ $VM_SSH_CMD << EOF
622635 set -e
623- echo 'Downloading {{.APP_NAME }} installer...'
624- curl -f 'https://replicated.app/embedded/{{.APP_NAME}}/{{.CHANNEL}} ' -H 'Authorization: {{.REPLICATED_LICENSE_ID}}' -o {{.APP_NAME }}-{{.CHANNEL}}.tgz
636+ echo 'Downloading {{.APP_SLUG }} installer...'
637+ curl -f '$DOWNLOAD_URL ' -H 'Authorization: {{.REPLICATED_LICENSE_ID}}' -o {{.APP_SLUG }}-{{.CHANNEL}}.tgz
625638
626639 echo 'Extracting installer...'
627- tar -xvzf {{.APP_NAME}}-{{.CHANNEL}}.tgz
640+ tar -xvzf {{.APP_SLUG}}-{{.CHANNEL}}.tgz
641+
642+ echo "Binary is available at ./{{.APP_SLUG}}"
643+ EOF
628644
629- if [ "{{.SKIP_INSTALL}}" = "false" ]; then
630- echo "Installing {{.APP_NAME}}..."
631- sudo ./{{.APP_NAME}} install --license license.yaml --admin-console-password {{.ADMIN_CONSOLE_PASSWORD}} --yes
632- else
633- echo "Skipping installation as requested. Binary is available at ./{{.APP_NAME}}"
645+ if [ "{{.AIRGAP}}" = "true" ]; then
646+ echo "Updating network policy for airgap installation..."
647+ NETWORK_ID=$(replicated vm ls --output=json | jq -r ".[] | select(.name == \"{{.CMX_VM_NAME}}\") | .network_id")
648+ replicated network update policy $NETWORK_ID --policy airgap
634649 fi
635- EOF
636650
637651 if [ "{{.SKIP_INSTALL}}" = "false" ]; then
652+ INSTALL_CMD="sudo ./{{.APP_SLUG}} install --license license.yaml --admin-console-password {{.ADMIN_CONSOLE_PASSWORD}} --yes"
653+ if [ "{{.AIRGAP}}" = "true" ]; then
654+ INSTALL_CMD="${INSTALL_CMD} --airgap-bundle {{.APP_SLUG}}.airgap"
655+ fi
656+
657+ echo "Running installation command: $INSTALL_CMD"
658+ $VM_SSH_CMD << EOF
659+ $INSTALL_CMD
660+ EOF
661+
638662 echo "Exposing port 30000 on the VM..."
639663 replicated vm port expose --port 30000 {{.CMX_VM_NAME}}
640664
641665 echo "Visit above URL to access the Admin Console, password: {{.ADMIN_CONSOLE_PASSWORD}}"
642666 fi
643667
668+ airgap-build :
669+ desc : Check and build airgap bundle for the latest release
670+ silent : true
671+ cmds :
672+ - |
673+ echo "Checking if airgap build is available for latest release in channel {{.RELEASE_CHANNEL}}..."
674+
675+ # Get release list and extract app ID and channel ID
676+ RELEASE_DATA=$(replicated release ls -o json)
677+ APP_ID=$(echo "$RELEASE_DATA" | jq -r '.[0].appId')
678+ CHANNEL_ID=$(echo "$RELEASE_DATA" | jq -r '.[0].activeChannels[] | select(.name == "{{.RELEASE_CHANNEL}}") | .id')
679+
680+ if [ -z "$APP_ID" ] || [ "$APP_ID" = "null" ]; then
681+ echo "Error: Could not retrieve app ID from latest releases"
682+ exit 1
683+ fi
684+
685+ if [ -z "$CHANNEL_ID" ] || [ "$CHANNEL_ID" = "null" ]; then
686+ echo "Error: Could not find channel ID for channel {{.RELEASE_CHANNEL}}"
687+ exit 1
688+ fi
689+
690+ echo "Found app ID: $APP_ID, channel ID: $CHANNEL_ID"
691+
692+ # Get channel releases and check airgap build status
693+ CHANNEL_RELEASES=$(replicated api get "v3/app/$APP_ID/channel/$CHANNEL_ID/releases")
694+ AIRGAP_BUILD_STATUS=$(echo "$CHANNEL_RELEASES" | jq -r '.releases[0].airgapBuildStatus // "none"')
695+ AIRGAP_BUILD_ERROR=$(echo "$CHANNEL_RELEASES" | jq -r '.releases[0].airgapBuildError // "none"')
696+ AIRGAP_BUNDLE_IMAGES=$(echo "$CHANNEL_RELEASES" | jq -r '.releases[0].airgapBundleImages // "none"')
697+ AIRGAP_LATEST_SEQUENCE=$(echo "$CHANNEL_RELEASES" | jq -r '.releases[0].channelSequence')
698+
699+ echo "Airgap build status: $AIRGAP_BUILD_STATUS"
700+
701+ if [ "$AIRGAP_BUILD_STATUS" = "built" ]; then
702+ echo "Airgap is already buit for sequence $AIRGAP_LATEST_SEQUENCE"
703+ echo "Airgap bundle images: $AIRGAP_BUNDLE_IMAGES"
704+ exit 0
705+ fi
706+
707+ if [ "$AIRGAP_BUILD_STATUS" = "metadata" ]; then
708+ echo "Airgap has not been built yet. Triggering build..."
709+ replicated api post "v3/app/$APP_ID/channel/$CHANNEL_ID/release/$AIRGAP_LATEST_SEQUENCE/airgap/build"
710+ fi
711+
712+ echo "Airgap build triggered. Polling every 10 seconds for up to 5 minutes..."
713+ for i in $(seq 1 30); do
714+ echo "Checking airgap build status... (attempt $i/30)"
715+
716+ CHANNEL_RELEASES=$(replicated api get "v3/app/$APP_ID/channel/$CHANNEL_ID/releases")
717+ AIRGAP_BUILD_STATUS=$(echo "$CHANNEL_RELEASES" | jq -r '.releases[0].airgapBuildStatus // "none"')
718+ AIRGAP_BUILD_ERROR=$(echo "$CHANNEL_RELEASES" | jq -r '.releases[0].airgapBuildError // "none"')
719+ AIRGAP_BUNDLE_IMAGES=$(echo "$CHANNEL_RELEASES" | jq -r '.releases[0].airgapBundleImages // "none"')
720+ AIRGAP_LATEST_SEQUENCE=$(echo "$CHANNEL_RELEASES" | jq -r '.releases[0].channelSequence')
721+
722+ echo "Airgap build current status: $AIRGAP_BUILD_STATUS"
723+
724+ if [ "$AIRGAP_BUILD_STATUS" = "built" ]; then
725+ echo "Airgap build completed successfully!"
726+ echo "Airgap bundle images: $AIRGAP_BUNDLE_IMAGES"
727+ exit 0
728+ fi
729+ sleep 10
730+ done
731+
732+ echo "Timeout: Airgap build did not complete within 5 minutes."
733+ echo "Last build status: $AIRGAP_BUILD_STATUS"
734+ echo "Last build error: $AIRGAP_BUILD_ERROR"
735+ exit 1
0 commit comments