-
-
Notifications
You must be signed in to change notification settings - Fork 166
Fix sudo password prompt #573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Qubasa
wants to merge
5
commits into
nix-community:main
Choose a base branch
from
Qubasa:fix_password_prompt
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
2b354fc
Add breakpoint debugging function
Qubasa 68c8cb1
Add debug logging to SSH commands
Qubasa 1e8ad55
Update debug variable handling and exports
Qubasa cc170a0
Refactor kexec execution to handle sudo passwords
Qubasa 0763ae8
Fix logging in as incorrect user if phases kexec is not set
Qubasa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -68,6 +68,53 @@ declare -A extraFilesOwnership=() | |||||
declare -a nixCopyOptions=() | ||||||
declare -a sshArgs=("-o" "IdentitiesOnly=yes" "-i" "$tempDir/nixos-anywhere" "-o" "UserKnownHostsFile=/dev/null" "-o" "StrictHostKeyChecking=no") | ||||||
|
||||||
breakpoint() { | ||||||
( | ||||||
set +x | ||||||
echo "Breakpoint reached at line ${BASH_LINENO[0]}." | ||||||
|
||||||
# Create a temporary directory for debug files | ||||||
debugTmpDir=$(mktemp -d /tmp/nixos-anywhere-debug.XXXXXX) | ||||||
# we need to export this var as the trap will access it outside of function context | ||||||
export debugTmpDir | ||||||
|
||||||
# Set up cleanup trap | ||||||
trap 'rm -rf "$debugTmpDir"' RETURN | ||||||
|
||||||
# Save all variables (local and exported) to a file | ||||||
( | ||||||
set -o posix | ||||||
set | ||||||
) >"$debugTmpDir/debug_vars.sh" | ||||||
|
||||||
# Create the rcfile with explicit terminal handling | ||||||
cat >"$debugTmpDir/debug_rcfile.sh" <<EOF | ||||||
# Source all variables | ||||||
set +o posix | ||||||
source "$debugTmpDir/debug_vars.sh" | ||||||
|
||||||
# Force output to terminal | ||||||
exec 2>/dev/tty | ||||||
exec 1>/dev/tty | ||||||
exec 0</dev/tty | ||||||
|
||||||
# Show some helpful info | ||||||
echo "Debug shell started. All variables from parent scope are available." | ||||||
echo "Example: echo \\$tempDir" | ||||||
echo "Type 'exit' to continue execution." | ||||||
|
||||||
# Set a nice prompt | ||||||
PS1="[DEBUG]> " | ||||||
EOF | ||||||
|
||||||
echo "Variables saved to $debugTmpDir/debug_vars.sh" | ||||||
echo "Starting debug shell (redirecting to /dev/tty for interactivity)..." | ||||||
|
||||||
# Start an interactive shell with explicit terminal redirection | ||||||
bash --rcfile "$debugTmpDir/debug_rcfile.sh" </dev/tty >/dev/tty 2>&1 | ||||||
) | ||||||
} | ||||||
|
||||||
showUsage() { | ||||||
cat <<USAGE | ||||||
Usage: nixos-anywhere [options] [<ssh-host>] | ||||||
|
@@ -423,9 +470,15 @@ runSshTimeout() { | |||||
timeout 10 ssh "${sshArgs[@]}" "$sshConnection" "$@" | ||||||
} | ||||||
runSsh() { | ||||||
# shellcheck disable=SC2029 | ||||||
# We want to expand "$@" to get the command to run over SSH | ||||||
ssh "$sshTtyParam" "${sshArgs[@]}" "$sshConnection" "$@" | ||||||
( | ||||||
set +x | ||||||
if [[ -n ${enableDebug} ]]; then | ||||||
echo -e "\033[1;34mSSH COMMAND:\033[0m ssh $sshTtyParam ${sshArgs[*]} $sshConnection $*\n" | ||||||
fi | ||||||
# shellcheck disable=SC2029 | ||||||
# We want to expand "$@" to get the command to run over SSH | ||||||
ssh "$sshTtyParam" "${sshArgs[@]}" "$sshConnection" "$@" | ||||||
) | ||||||
} | ||||||
|
||||||
nixCopy() { | ||||||
|
@@ -522,6 +575,8 @@ importFacts() { | |||||
if [[ -z $filteredFacts ]]; then | ||||||
abort "Retrieving host facts via SSH failed. Check with --debug for the root cause, unless you have done so already" | ||||||
fi | ||||||
|
||||||
set +x | ||||||
# make facts available in script | ||||||
# shellcheck disable=SC2046 | ||||||
export $(echo "$filteredFacts" | xargs) | ||||||
|
@@ -535,6 +590,10 @@ importFacts() { | |||||
done | ||||||
set -u | ||||||
|
||||||
if [[ -n ${enableDebug} ]]; then | ||||||
set -x | ||||||
fi | ||||||
|
||||||
if [[ ${isRoot} == "y" ]]; then | ||||||
maybeSudo= | ||||||
elif [[ ${hasSudo} == "y" ]]; then | ||||||
|
@@ -657,14 +716,63 @@ runKexec() { | |||||
kexecUrl=${kexecUrl/"github.com"/"gh-v6.com"} | ||||||
fi | ||||||
|
||||||
# Unified kexec error handling function | ||||||
handleKexecResult() { | ||||||
local exitCode=$1 | ||||||
local operation=$2 | ||||||
|
||||||
if [[ $exitCode -eq 0 ]]; then | ||||||
echo "$operation completed successfully" >&2 | ||||||
else | ||||||
# If operation failed, try to fetch the log file | ||||||
local logContent="" | ||||||
if logContent=$( | ||||||
set +x | ||||||
runSsh "cat /tmp/kexec-output.log 2>/dev/null" 2>/dev/null | ||||||
); then | ||||||
echo "Remote output log:" >&2 | ||||||
echo "$logContent" >&2 | ||||||
fi | ||||||
echo "$operation failed" >&2 | ||||||
exit 1 | ||||||
fi | ||||||
|
||||||
# Clean up the log file | ||||||
echo "Cleaning up remote kexec log file" >&2 | ||||||
( | ||||||
set +x | ||||||
runSsh "rm -f /tmp/kexec-output.log" 2>/dev/null || true | ||||||
) | ||||||
} | ||||||
|
||||||
# Define common remote commands template | ||||||
local remoteCommandTemplate | ||||||
remoteCommandTemplate=" | ||||||
${enableDebug:+set -x} | ||||||
# Create a script that we can run with sudo | ||||||
kexec_script_tmp=\$(mktemp /tmp/kexec-script.XXXXXX.sh) | ||||||
trap 'rm -f \"\$kexec_script_tmp\"' EXIT | ||||||
cat > \"\$kexec_script_tmp\" << 'KEXEC_SCRIPT' | ||||||
#!/usr/bin/env bash | ||||||
Qubasa marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
set -eu ${enableDebug} | ||||||
${maybeSudo} rm -rf /root/kexec | ||||||
${maybeSudo} mkdir -p /root/kexec | ||||||
%TAR_COMMAND% | ||||||
TMPDIR=/root/kexec setsid --wait ${maybeSudo} /root/kexec/kexec/run --kexec-extra-flags $(printf '%q ' "$kexecExtraFlags") | ||||||
rm -rf /root/kexec | ||||||
mkdir -p /root/kexec | ||||||
cd /root/kexec | ||||||
echo 'Downloading kexec tarball (this may take a moment)...' | ||||||
# Execute tar command | ||||||
%TAR_COMMAND% && TMPDIR=/root/kexec setsid --wait /root/kexec/kexec/run --kexec-extra-flags $(printf '%q ' "$kexecExtraFlags") | ||||||
KEXEC_SCRIPT | ||||||
|
||||||
# Run the script and let output flow naturally | ||||||
${maybeSudo} bash \"\$kexec_script_tmp\" 2>&1 | tee /tmp/kexec-output.log || true | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
# The script will likely disconnect us, so we consider it successful if we see the kexec message | ||||||
if grep -q 'machine will boot into nixos' /tmp/kexec-output.log; then | ||||||
echo 'Kexec initiated successfully' | ||||||
exit 0 | ||||||
else | ||||||
echo 'Kexec may have failed - check output above' | ||||||
Qubasa marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
exit 1 | ||||||
fi | ||||||
" | ||||||
|
||||||
# Define upload commands | ||||||
|
@@ -694,21 +802,48 @@ TMPDIR=/root/kexec setsid --wait ${maybeSudo} /root/kexec/kexec/run --kexec-extr | |||||
localUploadCommand=(curl --fail -Ss -L "${kexecUrl}") | ||||||
fi | ||||||
|
||||||
local tarCommand | ||||||
local remoteCommands | ||||||
# If no local upload command is defined, we use the remote command to download and execute | ||||||
if [[ ${#localUploadCommand[@]} -eq 0 ]]; then | ||||||
# Use remote command for download and execution | ||||||
tarCommand="$(printf '%q ' "${remoteUploadCommand[@]}") | ${maybeSudo} tar -C /root/kexec -xv ${tarDecomp}" | ||||||
|
||||||
local tarCommand | ||||||
tarCommand="$(printf '%q ' "${remoteUploadCommand[@]}") | tar -xv ${tarDecomp}" | ||||||
local remoteCommands | ||||||
remoteCommands=${remoteCommandTemplate//'%TAR_COMMAND%'/$tarCommand} | ||||||
|
||||||
runSsh sh -c "$(printf '%q' "$remoteCommands")" | ||||||
# Run the SSH command - for kexec with sudo, we expect it might disconnect | ||||||
local sshExitCode | ||||||
( | ||||||
set +x | ||||||
runSsh sh -c "$(printf '%q' "$remoteCommands")" | ||||||
) | ||||||
sshExitCode=$? | ||||||
|
||||||
handleKexecResult $sshExitCode "Kexec" | ||||||
else | ||||||
# Query remote home directory for the user | ||||||
remoteHomeDir=$(runSshNoTty -o ConnectTimeout=10 "getent passwd \"$sshUser\" | cut -d: -f6") | ||||||
if [[ -z $remoteHomeDir ]]; then | ||||||
abort "Could not determine home directory for user $sshUser" | ||||||
fi | ||||||
|
||||||
( | ||||||
set +x | ||||||
"${localUploadCommand[@]}" | runSsh "cat > \"$remoteHomeDir\"/kexec-tarball.tar.gz" | ||||||
) | ||||||
|
||||||
# Use local command with pipe to remote | ||||||
tarCommand="${maybeSudo} tar -C /root/kexec -xv ${tarDecomp}" | ||||||
remoteCommands=${remoteCommandTemplate//'%TAR_COMMAND%'/$tarCommand} | ||||||
local tarCommand="cat \"$remoteHomeDir\"/kexec-tarball.tar.gz | tar -xv ${tarDecomp}" | ||||||
local remoteCommands=${remoteCommandTemplate//'%TAR_COMMAND%'/$tarCommand} | ||||||
|
||||||
# Execute the local upload command and check for success | ||||||
local uploadExitCode | ||||||
( | ||||||
set +x | ||||||
runSsh sh -c "$(printf '%q' "$remoteCommands")" | ||||||
) | ||||||
uploadExitCode=$? | ||||||
|
||||||
"${localUploadCommand[@]}" | runSsh sh -c "$(printf '%q' "$remoteCommands")" | ||||||
handleKexecResult $uploadExitCode "Upload" | ||||||
fi | ||||||
|
||||||
# use the default SSH port to connect at this point | ||||||
|
@@ -876,6 +1011,12 @@ main() { | |||||
sshUser=$(echo "$sshSettings" | awk '/^user / { print $2 }') | ||||||
sshHost="${sshConnection//*@/}" | ||||||
|
||||||
# If kexec phase is not present, we assume kexec has already been run | ||||||
# and change the user to root@<sshHost> for the rest of the script. | ||||||
if [[ ${phases[kexec]} != 1 ]]; then | ||||||
sshConnection="root@${sshHost}" | ||||||
fi | ||||||
|
||||||
uploadSshKey | ||||||
|
||||||
importFacts | ||||||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.