@@ -722,14 +722,60 @@ runKexec() {
722722 kexecUrl=${kexecUrl/ " github.com" / " gh-v6.com" }
723723 fi
724724
725+ if [[ -z $remoteLogFile ]]; then
726+ abort " Could not create a temporary log file for $sshUser "
727+ fi
728+
729+ # Unified kexec error handling function
730+ handleKexecResult () {
731+ local exitCode=$1
732+ local operation=$2
733+
734+ if [[ $exitCode -eq 0 ]]; then
735+ echo " $operation completed successfully" >&2
736+ else
737+ # If operation failed, try to fetch the log file
738+ local logContent=" "
739+ if logContent=$(
740+ set +x
741+ runSsh " cat \" $remoteLogFile \" 2>/dev/null" 2> /dev/null
742+ ) ; then
743+ echo " Remote output log:" >&2
744+ echo " $logContent " >&2
745+ fi
746+ echo " $operation failed" >&2
747+ exit 1
748+ fi
749+ }
750+
725751 # Define common remote commands template
726752 local remoteCommandTemplate
727753 remoteCommandTemplate="
754+ ${enableDebug: +set -x}
755+ # Create a script that we can run with sudo
756+ kexec_script_tmp=\$ (mktemp /tmp/kexec-script.XXXXXX.sh)
757+ trap 'rm -f \"\$ kexec_script_tmp\" ' EXIT
758+ cat > \"\$ kexec_script_tmp\" << 'KEXEC_SCRIPT'
759+ #!/usr/bin/env bash
728760set -eu ${enableDebug}
729- ${maybeSudo} rm -rf /root/kexec
730- ${maybeSudo} mkdir -p /root/kexec
731- %TAR_COMMAND%
732- TMPDIR=/root/kexec setsid --wait ${maybeSudo} /root/kexec/kexec/run --kexec-extra-flags $( printf ' %q ' " $kexecExtraFlags " )
761+ rm -rf /root/kexec
762+ mkdir -p /root/kexec
763+ cd /root/kexec
764+ echo 'Downloading kexec tarball (this may take a moment)...'
765+ # Execute tar command
766+ %TAR_COMMAND% && TMPDIR=/root/kexec setsid --wait /root/kexec/kexec/run --kexec-extra-flags $( printf ' %q ' " $kexecExtraFlags " )
767+ KEXEC_SCRIPT
768+
769+ # Run the script and let output flow naturally
770+ ${maybeSudo} bash \"\$ kexec_script_tmp\" 2>&1 | tee \" $remoteLogFile \" || true
771+ # The script will likely disconnect us, so we consider it successful if we see the kexec message
772+ if grep -q 'machine will boot into nixos' \" $remoteLogFile \" ; then
773+ echo 'Kexec initiated successfully'
774+ exit 0
775+ else
776+ echo 'Kexec may have failed - check output above'
777+ exit 1
778+ fi
733779"
734780
735781 # Define upload commands
@@ -759,21 +805,50 @@ TMPDIR=/root/kexec setsid --wait ${maybeSudo} /root/kexec/kexec/run --kexec-extr
759805 localUploadCommand=(curl --fail -Ss -L " ${kexecUrl} " )
760806 fi
761807
762- local tarCommand
763- local remoteCommands
808+ # If no local upload command is defined, we use the remote command to download and execute
764809 if [[ ${# localUploadCommand[@]} -eq 0 ]]; then
765810 # Use remote command for download and execution
766- tarCommand=" $( printf ' %q ' " ${remoteUploadCommand[@]} " ) | ${maybeSudo} tar -C /root/kexec -xv ${tarDecomp} "
767-
811+ local tarCommand
812+ tarCommand=" $( printf ' %q ' " ${remoteUploadCommand[@]} " ) | tar -xv ${tarDecomp} "
813+ local remoteCommands
768814 remoteCommands=${remoteCommandTemplate// ' %TAR_COMMAND%' / $tarCommand }
769815
770- runSsh sh -c " $( printf ' %q' " $remoteCommands " ) "
816+ # Run the SSH command - for kexec with sudo, we expect it might disconnect
817+ local sshExitCode
818+ (
819+ set +x
820+ runSsh sh -c " $( printf ' %q' " $remoteCommands " ) "
821+ )
822+ sshExitCode=$?
823+
824+ handleKexecResult $sshExitCode " Kexec"
771825 else
826+ # Why do we need $remoteHomeDir?
827+ # In the case where the ssh user is not root, we need to upload the kexec tarball
828+ # to a location where the user has write permissions. We then use sudo to run
829+ # kexec from that location.
830+ if [[ -z $remoteHomeDir ]]; then
831+ abort " Could not determine home directory for user $sshUser "
832+ fi
833+
834+ (
835+ set +x
836+ " ${localUploadCommand[@]} " | runSsh " cat > \" $remoteHomeDir \" /kexec-tarball.tar.gz"
837+ )
838+
772839 # Use local command with pipe to remote
773- tarCommand=" ${maybeSudo} tar -C /root/kexec -xv ${tarDecomp} "
774- remoteCommands=${remoteCommandTemplate// ' %TAR_COMMAND%' / $tarCommand }
840+ local tarCommand=" cat \" $remoteHomeDir \" /kexec-tarball.tar.gz | tar -xv ${tarDecomp} "
841+ local remoteCommands=${remoteCommandTemplate// ' %TAR_COMMAND%' / $tarCommand }
842+
843+ # Execute the local upload command and check for success
844+ local uploadExitCode
845+ (
846+ set +x
847+ runSsh sh -c " $( printf ' %q' " $remoteCommands " ) "
848+ )
849+ uploadExitCode=$?
775850
776- " ${localUploadCommand[@]} " | runSsh sh -c " $( printf ' %q ' " $remoteCommands " ) "
851+ handleKexecResult $uploadExitCode " Upload "
777852 fi
778853
779854 # use the default SSH port to connect at this point
0 commit comments