@@ -716,14 +716,63 @@ runKexec() {
716
716
kexecUrl=${kexecUrl/ " github.com" / " gh-v6.com" }
717
717
fi
718
718
719
+ # Unified kexec error handling function
720
+ handleKexecResult () {
721
+ local exitCode=$1
722
+ local operation=$2
723
+
724
+ if [[ $exitCode -eq 0 ]]; then
725
+ echo " $operation completed successfully" >&2
726
+ else
727
+ # If operation failed, try to fetch the log file
728
+ local logContent=" "
729
+ if logContent=$(
730
+ set +x
731
+ runSsh " cat /tmp/kexec-output.log 2>/dev/null" 2> /dev/null
732
+ ) ; then
733
+ echo " Remote output log:" >&2
734
+ echo " $logContent " >&2
735
+ fi
736
+ echo " $operation failed" >&2
737
+ exit 1
738
+ fi
739
+
740
+ # Clean up the log file
741
+ echo " Cleaning up remote kexec log file" >&2
742
+ (
743
+ set +x
744
+ runSsh " rm -f /tmp/kexec-output.log" 2> /dev/null || true
745
+ )
746
+ }
747
+
719
748
# Define common remote commands template
720
749
local remoteCommandTemplate
721
750
remoteCommandTemplate="
751
+ ${enableDebug: +set -x}
752
+ # Create a script that we can run with sudo
753
+ kexec_script_tmp=\$ (mktemp /tmp/kexec-script.XXXXXX.sh)
754
+ trap 'rm -f \"\$ kexec_script_tmp\" ' EXIT
755
+ cat > \"\$ kexec_script_tmp\" << 'KEXEC_SCRIPT'
756
+ #!/usr/bin/env bash
722
757
set -eu ${enableDebug}
723
- ${maybeSudo} rm -rf /root/kexec
724
- ${maybeSudo} mkdir -p /root/kexec
725
- %TAR_COMMAND%
726
- TMPDIR=/root/kexec setsid --wait ${maybeSudo} /root/kexec/kexec/run --kexec-extra-flags $( printf ' %q ' " $kexecExtraFlags " )
758
+ rm -rf /root/kexec
759
+ mkdir -p /root/kexec
760
+ cd /root/kexec
761
+ echo 'Downloading kexec tarball (this may take a moment)...'
762
+ # Execute tar command
763
+ %TAR_COMMAND% && TMPDIR=/root/kexec setsid --wait /root/kexec/kexec/run --kexec-extra-flags $( printf ' %q ' " $kexecExtraFlags " )
764
+ KEXEC_SCRIPT
765
+
766
+ # Run the script and let output flow naturally
767
+ ${maybeSudo} bash \"\$ kexec_script_tmp\" 2>&1 | tee /tmp/kexec-output.log || true
768
+ # The script will likely disconnect us, so we consider it successful if we see the kexec message
769
+ if grep -q 'machine will boot into nixos' /tmp/kexec-output.log; then
770
+ echo 'Kexec initiated successfully'
771
+ exit 0
772
+ else
773
+ echo 'Kexec may have failed - check output above'
774
+ exit 1
775
+ fi
727
776
"
728
777
729
778
# Define upload commands
@@ -753,21 +802,46 @@ TMPDIR=/root/kexec setsid --wait ${maybeSudo} /root/kexec/kexec/run --kexec-extr
753
802
localUploadCommand=(curl --fail -Ss -L " ${kexecUrl} " )
754
803
fi
755
804
756
- local tarCommand
757
- local remoteCommands
805
+ # If no local upload command is defined, we use the remote command to download and execute
758
806
if [[ ${# localUploadCommand[@]} -eq 0 ]]; then
759
807
# Use remote command for download and execution
760
- tarCommand=" $( printf ' %q ' " ${remoteUploadCommand[@]} " ) | ${maybeSudo} tar -C /root/kexec -xv ${tarDecomp} "
808
+ local tarCommand=" $( printf ' %q ' " ${remoteUploadCommand[@]} " ) | tar -xv ${tarDecomp} "
809
+ local remoteCommands=${remoteCommandTemplate// ' %TAR_COMMAND%' / $tarCommand }
761
810
762
- remoteCommands=${remoteCommandTemplate// ' %TAR_COMMAND%' / $tarCommand }
811
+ # Run the SSH command - for kexec with sudo, we expect it might disconnect
812
+ local sshExitCode
813
+ (
814
+ set +x
815
+ runSsh sh -c " $( printf ' %q' " $remoteCommands " ) "
816
+ )
817
+ sshExitCode=$?
763
818
764
- runSsh sh -c " $( printf ' %q ' " $remoteCommands " ) "
819
+ handleKexecResult $sshExitCode " Kexec "
765
820
else
821
+ # Query remote home directory for the user
822
+ remoteHomeDir=$( runSshNoTty -o ConnectTimeout=10 " getent passwd \" $sshUser \" | cut -d: -f6" )
823
+ if [[ -z $remoteHomeDir ]]; then
824
+ abort " Could not determine home directory for user $sshUser "
825
+ fi
826
+
827
+ (
828
+ set +x
829
+ " ${localUploadCommand[@]} " | runSsh " cat > \" $remoteHomeDir \" /kexec-tarball.tar.gz"
830
+ )
831
+
766
832
# Use local command with pipe to remote
767
- tarCommand=" ${maybeSudo} tar -C /root/kexec -xv ${tarDecomp} "
768
- remoteCommands=${remoteCommandTemplate// ' %TAR_COMMAND%' / $tarCommand }
833
+ local tarCommand=" cat \" $remoteHomeDir \" /kexec-tarball.tar.gz | tar -xv ${tarDecomp} "
834
+ local remoteCommands=${remoteCommandTemplate// ' %TAR_COMMAND%' / $tarCommand }
835
+
836
+ # Execute the local upload command and check for success
837
+ local uploadExitCode
838
+ (
839
+ set +x
840
+ runSsh sh -c " $( printf ' %q' " $remoteCommands " ) "
841
+ )
842
+ uploadExitCode=$?
769
843
770
- " ${localUploadCommand[@]} " | runSsh sh -c " $( printf ' %q ' " $remoteCommands " ) "
844
+ handleKexecResult $uploadExitCode " Upload "
771
845
fi
772
846
773
847
# use the default SSH port to connect at this point
0 commit comments