guix-install.sh: Add msg helpers and use stderr consistently.

Add helpers to avoid repeated manual concatenation.

_err and _msg "$ERR are used interchangeably with their only difference
being output stream; convert all errors to use _err.

* etc/guix-install.sh: Add msg helpers and consolidate errors to stderr.

Change-Id: I06e97ccc50d108ed9e279ae80c6b2386d7b8c36b
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Liam Hupfer 2025-02-05 22:25:04 -06:00 committed by Ludovic Courtès
parent 754a5ab02f
commit 201db94628
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5

View file

@ -110,7 +110,7 @@ GPG_SIGNING_KEYS[127547]=27D586A4F8900854329FF09F1260E46482E63562 # maxim
_err() _err()
{ # All errors go to stderr. { # All errors go to stderr.
printf "[%s]: %s\n" "$(date +%s.%3N)" "$1" printf "[%s]: ${ERR}%s\n" "$(date +%s.%3N)" "$1"
} }
_msg() _msg()
@ -118,6 +118,21 @@ _msg()
printf "[%s]: %s\n" "$(date +%s.%3N)" "$1" printf "[%s]: %s\n" "$(date +%s.%3N)" "$1"
} }
_msg_pass()
{
_msg "$PAS$1"
}
_msg_warn()
{
_msg "$WAR$1"
}
_msg_info()
{
_msg "$INF$1"
}
_debug() _debug()
{ {
if [ "${DEBUG}" = '1' ]; then if [ "${DEBUG}" = '1' ]; then
@ -127,7 +142,7 @@ _debug()
die() die()
{ {
_err "${ERR}$*" _err "$*"
exit 1 exit 1
} }
@ -154,7 +169,7 @@ chk_require()
[ "${#warn}" -ne 0 ] && die "Missing commands: ${warn[*]}." [ "${#warn}" -ne 0 ] && die "Missing commands: ${warn[*]}."
_msg "${PAS}verification of required commands completed" _msg_pass "verification of required commands completed"
} }
add_init_sys_require() add_init_sys_require()
@ -195,7 +210,7 @@ Would you like me to fetch it for you?"; then
fi fi
# If we reach this point, the key is (still) missing. Report further # If we reach this point, the key is (still) missing. Report further
# missing keys, if any, but then abort the installation. # missing keys, if any, but then abort the installation.
_err "${ERR}Missing OpenPGP public key ($gpg_key_id). _err "Missing OpenPGP public key ($gpg_key_id).
Fetch it with this command: Fetch it with this command:
wget \"https://sv.gnu.org/people/viewgpg.php?user_id=$user_id\" -O - | \ wget \"https://sv.gnu.org/people/viewgpg.php?user_id=$user_id\" -O - | \
@ -227,24 +242,24 @@ chk_term()
chk_init_sys() chk_init_sys()
{ # Return init system type name. { # Return init system type name.
if [[ $(/sbin/init --version 2>/dev/null) =~ upstart ]]; then if [[ $(/sbin/init --version 2>/dev/null) =~ upstart ]]; then
_msg "${INF}init system is: upstart" _msg_info "init system is: upstart"
INIT_SYS="upstart" INIT_SYS="upstart"
return 0 return 0
elif [[ $(systemctl 2>/dev/null) =~ -\.mount ]]; then elif [[ $(systemctl 2>/dev/null) =~ -\.mount ]]; then
_msg "${INF}init system is: systemd" _msg_info "init system is: systemd"
INIT_SYS="systemd" INIT_SYS="systemd"
return 0 return 0
elif [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]]; then elif [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]]; then
_msg "${INF}init system is: sysv-init" _msg_info "init system is: sysv-init"
INIT_SYS="sysv-init" INIT_SYS="sysv-init"
return 0 return 0
elif [[ $(openrc --version 2>/dev/null) =~ \(OpenRC ]]; then elif [[ $(openrc --version 2>/dev/null) =~ \(OpenRC ]]; then
_msg "${INF}init system is: OpenRC" _msg_info "init system is: OpenRC"
INIT_SYS="openrc" INIT_SYS="openrc"
return 0 return 0
else else
INIT_SYS="NA" INIT_SYS="NA"
_err "${ERR}Init system could not be detected." _err "Init system could not be detected."
fi fi
} }
@ -291,12 +306,12 @@ chk_sys_nscd()
{ # Check if nscd is up and suggest to start it or install it { # Check if nscd is up and suggest to start it or install it
if [ "$(type -P pidof)" ]; then if [ "$(type -P pidof)" ]; then
if [ ! "$(pidof nscd)" ]; then if [ ! "$(pidof nscd)" ]; then
_msg "${WAR}We recommend installing and/or starting your distribution 'nscd' service" _msg_warn "We recommend installing and/or starting your distribution 'nscd' service"
_msg "${WAR}Please read 'info guix \"Application Setup\"' about \"Name Service Switch\"" _msg_warn "Please read 'info guix \"Application Setup\"' about \"Name Service Switch\""
fi fi
else else
_msg "${INF}We cannot determine if your distribution 'nscd' service is running" _msg_info "We cannot determine if your distribution 'nscd' service is running"
_msg "${INF}Please read 'info guix \"Application Setup\"' about \"Name Service Switch\"" _msg_info "Please read 'info guix \"Application Setup\"' about \"Name Service Switch\""
fi fi
} }
@ -334,7 +349,7 @@ guix_get_bin_list()
default_ver="guix-binary-${latest_ver}.${ARCH_OS}" default_ver="guix-binary-${latest_ver}.${ARCH_OS}"
if [[ "${#bin_ver_ls}" -ne "0" ]]; then if [[ "${#bin_ver_ls}" -ne "0" ]]; then
_msg "${PAS}Release for your system: ${default_ver}" _msg_pass "Release for your system: ${default_ver}"
else else
die "Could not obtain list of Guix releases." die "Could not obtain list of Guix releases."
fi fi
@ -352,21 +367,21 @@ guix_get_bin()
_debug "--- [ ${FUNCNAME[0]} ] ---" _debug "--- [ ${FUNCNAME[0]} ] ---"
_msg "${INF}Downloading Guix release archive" _msg_info "Downloading Guix release archive"
wget --help | grep -q '\--show-progress' \ wget --help | grep -q '\--show-progress' \
&& wget_args=("--no-verbose" "--show-progress") && wget_args=("--no-verbose" "--show-progress")
if wget "${wget_args[@]}" -P "$dl_path" \ if wget "${wget_args[@]}" -P "$dl_path" \
"${url}/${bin_ver}.tar.xz" "${url}/${bin_ver}.tar.xz.sig"; then "${url}/${bin_ver}.tar.xz" "${url}/${bin_ver}.tar.xz.sig"; then
_msg "${PAS}download completed." _msg_pass "download completed."
else else
die "could not download ${url}/${bin_ver}.tar.xz." die "could not download ${url}/${bin_ver}.tar.xz."
fi fi
pushd "${dl_path}" >/dev/null pushd "${dl_path}" >/dev/null
if gpg --verify "${bin_ver}.tar.xz.sig" >/dev/null 2>&1; then if gpg --verify "${bin_ver}.tar.xz.sig" >/dev/null 2>&1; then
_msg "${PAS}Signature is valid." _msg_pass "Signature is valid."
popd >/dev/null popd >/dev/null
else else
die "could not verify the signature." die "could not verify the signature."
@ -382,18 +397,18 @@ sys_create_store()
if [[ -e /var/guix && -e /gnu ]]; then if [[ -e /var/guix && -e /gnu ]]; then
if [ -n "$GUIX_ALLOW_OVERWRITE" ]; then if [ -n "$GUIX_ALLOW_OVERWRITE" ]; then
_msg "${WAR}Overwriting existing installation!" _msg_warn "Overwriting existing installation!"
else else
die "A previous Guix installation was found. Refusing to overwrite." die "A previous Guix installation was found. Refusing to overwrite."
fi fi
fi fi
cd "$tmp_path" cd "$tmp_path"
_msg "${INF}Installing /var/guix and /gnu..." _msg_info "Installing /var/guix and /gnu..."
# Strip (skip) the leading . component, which fails on read-only /. # Strip (skip) the leading . component, which fails on read-only /.
tar --extract --strip-components=1 --file "$pkg" -C / tar --extract --strip-components=1 --file "$pkg" -C /
_msg "${INF}Linking the root user's profile" _msg_info "Linking the root user's profile"
mkdir -p ~root/.config/guix mkdir -p ~root/.config/guix
ln -sf /var/guix/profiles/per-user/root/current-guix \ ln -sf /var/guix/profiles/per-user/root/current-guix \
~root/.config/guix/current ~root/.config/guix/current
@ -403,18 +418,18 @@ sys_create_store()
# effective linting. # effective linting.
# shellcheck disable=SC1091 # shellcheck disable=SC1091
source "${GUIX_PROFILE}/etc/profile" source "${GUIX_PROFILE}/etc/profile"
_msg "${PAS}activated root profile at ${GUIX_PROFILE}" _msg_pass "activated root profile at ${GUIX_PROFILE}"
} }
sys_delete_store() sys_delete_store()
{ {
_msg "${INF}removing /var/guix" _msg_info "removing /var/guix"
rm -rf /var/guix rm -rf /var/guix
_msg "${INF}removing /gnu" _msg_info "removing /gnu"
rm -rf /gnu rm -rf /gnu
_msg "${INF}removing ~root/.config/guix" _msg_info "removing ~root/.config/guix"
rm -rf ~root/.config/guix rm -rf ~root/.config/guix
} }
@ -424,20 +439,20 @@ sys_create_build_user()
_debug "--- [ ${FUNCNAME[0]} ] ---" _debug "--- [ ${FUNCNAME[0]} ] ---"
if getent group guixbuild > /dev/null; then if getent group guixbuild > /dev/null; then
_msg "${INF}group guixbuild exists" _msg_info "group guixbuild exists"
else else
groupadd --system guixbuild groupadd --system guixbuild
_msg "${PAS}group <guixbuild> created" _msg_pass "group <guixbuild> created"
fi fi
if getent group kvm > /dev/null; then if getent group kvm > /dev/null; then
_msg "${INF}group kvm exists and build users will be added to it" _msg_info "group kvm exists and build users will be added to it"
local KVMGROUP=,kvm local KVMGROUP=,kvm
fi fi
for i in $(seq -w 1 10); do for i in $(seq -w 1 10); do
if id "guixbuilder${i}" &>/dev/null; then if id "guixbuilder${i}" &>/dev/null; then
_msg "${INF}user is already in the system, reset" _msg_info "user is already in the system, reset"
usermod -g guixbuild -G guixbuild"$KVMGROUP" \ usermod -g guixbuild -G guixbuild"$KVMGROUP" \
-d /var/empty -s "$(which nologin)" \ -d /var/empty -s "$(which nologin)" \
-c "Guix build user $i" \ -c "Guix build user $i" \
@ -447,7 +462,7 @@ sys_create_build_user()
-d /var/empty -s "$(which nologin)" \ -d /var/empty -s "$(which nologin)" \
-c "Guix build user $i" --system \ -c "Guix build user $i" --system \
"guixbuilder${i}"; "guixbuilder${i}";
_msg "${PAS}user added <guixbuilder${i}>" _msg_pass "user added <guixbuilder${i}>"
fi fi
done done
} }
@ -460,7 +475,7 @@ sys_delete_build_user()
fi fi
done done
_msg "${INF}delete group guixbuild" _msg_info "delete group guixbuild"
if getent group guixbuild &>/dev/null; then if getent group guixbuild &>/dev/null; then
groupdel -f guixbuild groupdel -f guixbuild
fi fi
@ -486,7 +501,7 @@ sys_enable_guix_daemon()
/etc/init/ && /etc/init/ &&
configure_substitute_discovery /etc/init/guix-daemon.conf && configure_substitute_discovery /etc/init/guix-daemon.conf &&
start guix-daemon; } && start guix-daemon; } &&
_msg "${PAS}enabled Guix daemon via upstart" _msg_pass "enabled Guix daemon via upstart"
;; ;;
systemd) systemd)
{ install_unit() { install_unit()
@ -511,7 +526,7 @@ sys_enable_guix_daemon()
systemctl daemon-reload && systemctl daemon-reload &&
systemctl start guix-daemon; } && systemctl start guix-daemon; } &&
_msg "${PAS}enabled Guix daemon via systemd" _msg_pass "enabled Guix daemon via systemd"
;; ;;
sysv-init) sysv-init)
{ mkdir -p /etc/init.d; { mkdir -p /etc/init.d;
@ -524,7 +539,7 @@ sys_enable_guix_daemon()
update-rc.d guix-daemon defaults && update-rc.d guix-daemon defaults &&
update-rc.d guix-daemon enable && update-rc.d guix-daemon enable &&
service guix-daemon start; } && service guix-daemon start; } &&
_msg "${PAS}enabled Guix daemon via sysv" _msg_pass "enabled Guix daemon via sysv"
;; ;;
openrc) openrc)
{ mkdir -p /etc/init.d; { mkdir -p /etc/init.d;
@ -536,15 +551,15 @@ sys_enable_guix_daemon()
rc-update add guix-daemon default && rc-update add guix-daemon default &&
rc-service guix-daemon start; } && rc-service guix-daemon start; } &&
_msg "${PAS}enabled Guix daemon via OpenRC" _msg_pass "enabled Guix daemon via OpenRC"
;; ;;
NA|*) NA|*)
_msg "${ERR}unsupported init system; run the daemon manually:" _err "unsupported init system; run the daemon manually:"
echo " ~root/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild" echo " ~root/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild"
;; ;;
esac esac
_msg "${INF}making the guix command available to other users" _msg_info "making the guix command available to other users"
[ -e "$local_bin" ] || mkdir -p "$local_bin" [ -e "$local_bin" ] || mkdir -p "$local_bin"
ln -sf "${var_guix}/bin/guix" "$local_bin" ln -sf "${var_guix}/bin/guix" "$local_bin"
@ -570,28 +585,28 @@ sys_delete_guix_daemon()
case "$INIT_SYS" in case "$INIT_SYS" in
upstart) upstart)
_msg "${INF}stopping guix-daemon" _msg_info "stopping guix-daemon"
stop guix-daemon stop guix-daemon
_msg "${INF}removing guix-daemon" _msg_info "removing guix-daemon"
rm /etc/init/guix-daemon.conf rm /etc/init/guix-daemon.conf
;; ;;
systemd) systemd)
if [ -f /etc/systemd/system/guix-daemon.service ]; then if [ -f /etc/systemd/system/guix-daemon.service ]; then
_msg "${INF}disabling guix-daemon" _msg_info "disabling guix-daemon"
systemctl disable guix-daemon systemctl disable guix-daemon
_msg "${INF}stopping guix-daemon" _msg_info "stopping guix-daemon"
systemctl stop guix-daemon systemctl stop guix-daemon
_msg "${INF}removing guix-daemon" _msg_info "removing guix-daemon"
rm -f /etc/systemd/system/guix-daemon.service rm -f /etc/systemd/system/guix-daemon.service
fi fi
if [ -f /etc/systemd/system/gnu-store.mount ]; then if [ -f /etc/systemd/system/gnu-store.mount ]; then
_msg "${INF}disabling gnu-store.mount" _msg_info "disabling gnu-store.mount"
systemctl disable gnu-store.mount systemctl disable gnu-store.mount
_msg "${INF}stopping gnu-store.mount" _msg_info "stopping gnu-store.mount"
systemctl stop gnu-store.mount systemctl stop gnu-store.mount
_msg "${INF}removing gnu-store.mount" _msg_info "removing gnu-store.mount"
rm -f /etc/systemd/system/gnu-store.mount rm -f /etc/systemd/system/gnu-store.mount
fi fi
systemctl daemon-reload systemctl daemon-reload
@ -603,16 +618,16 @@ sys_delete_guix_daemon()
rm -rf /etc/init.d/guix-daemon rm -rf /etc/init.d/guix-daemon
;; ;;
NA|*) NA|*)
_msg "${ERR}unsupported init system; disable, stop and remove the daemon manually:" _err "unsupported init system; disable, stop and remove the daemon manually:"
echo " ~root/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild" echo " ~root/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild"
;; ;;
esac esac
_msg "${INF}removing $local_bin/guix" _msg_info "removing $local_bin/guix"
rm -f "$local_bin"/guix rm -f "$local_bin"/guix
_msg "${INF}removing $info_path/guix*" _msg_info "removing $info_path/guix*"
rm -f "$info_path"/guix* rm -f "$info_path"/guix*
} }
@ -629,10 +644,10 @@ project's build farms?"; then
local key=~root/.config/guix/current/share/guix/$host.pub local key=~root/.config/guix/current/share/guix/$host.pub
[ -f "$key" ] \ [ -f "$key" ] \
&& guix archive --authorize < "$key" \ && guix archive --authorize < "$key" \
&& _msg "${PAS}Authorized public key for $host" && _msg_pass "Authorized public key for $host"
done done
else else
_msg "${INF}Skipped authorizing build farm public keys" _msg_info "Skipped authorizing build farm public keys"
fi fi
} }
@ -715,7 +730,7 @@ sys_create_shell_completion()
ln -sf ${var_guix}/etc/bash_completion.d/guix-daemon "$bash_completion"; ln -sf ${var_guix}/etc/bash_completion.d/guix-daemon "$bash_completion";
ln -sf ${var_guix}/share/zsh/site-functions/_guix "$zsh_completion"; ln -sf ${var_guix}/share/zsh/site-functions/_guix "$zsh_completion";
ln -sf ${var_guix}/share/fish/vendor_completions.d/guix.fish "$fish_completion"; } && ln -sf ${var_guix}/share/fish/vendor_completions.d/guix.fish "$fish_completion"; } &&
_msg "${PAS}installed shell completion" _msg_pass "installed shell completion"
} }
sys_delete_shell_completion() sys_delete_shell_completion()
@ -726,7 +741,7 @@ sys_delete_shell_completion()
zsh_completion=/usr/share/zsh/site-functions zsh_completion=/usr/share/zsh/site-functions
fish_completion=/usr/share/fish/vendor_completions.d fish_completion=/usr/share/fish/vendor_completions.d
_msg "${INF}removing shell completion" _msg_info "removing shell completion"
rm -f "$bash_completion"/guix; rm -f "$bash_completion"/guix;
rm -f "$bash_completion"/guix-daemon; rm -f "$bash_completion"/guix-daemon;
@ -753,7 +768,7 @@ if [ -n "$GUIX_ENVIRONMENT" ]; then
fi fi
' >> "$bashrc" ' >> "$bashrc"
done done
_msg "${PAS}Bash shell prompt successfully customized for Guix" _msg_pass "Bash shell prompt successfully customized for Guix"
} }
sys_maybe_setup_selinux() sys_maybe_setup_selinux()
@ -782,17 +797,17 @@ sys_maybe_setup_selinux()
sys_delete_init_profile() sys_delete_init_profile()
{ {
_msg "${INF}removing /etc/profile.d/guix.sh" _msg_info "removing /etc/profile.d/guix.sh"
rm -f /etc/profile.d/guix.sh rm -f /etc/profile.d/guix.sh
} }
sys_delete_user_profiles() sys_delete_user_profiles()
{ {
_msg "${INF}removing ~root/.guix-profile" _msg_info "removing ~root/.guix-profile"
rm -f ~root/.guix-profile rm -f ~root/.guix-profile
rm -rf ~root/.cache/guix rm -rf ~root/.cache/guix
_msg "${INF}removing .guix-profile, .cache/guix and .config/guix of all /home users" _msg_info "removing .guix-profile, .cache/guix and .config/guix of all /home users"
rm -rf /home/*/{.guix-profile,{.cache,.config}/guix} rm -rf /home/*/{.guix-profile,{.cache,.config}/guix}
} }
@ -841,8 +856,8 @@ EOF
if [ "$char" ]; then if [ "$char" ]; then
echo echo
echo "...that ($char) was not a return!" echo "...that ($char) was not a return!"
_msg "${WAR}Use newlines to automate installation, e.g.: yes '' | ${0##*/}" _msg_warn "Use newlines to automate installation, e.g.: yes '' | ${0##*/}"
_msg "${WAR}Any other method is unsupported and likely to break in future." _msg_warn "Any other method is unsupported and likely to break in future."
fi fi
} }
@ -861,7 +876,7 @@ main_install()
chk_sys_arch chk_sys_arch
chk_sys_nscd chk_sys_nscd
_msg "${INF}system is ${ARCH_OS}" _msg_info "system is ${ARCH_OS}"
umask 0022 umask 0022
tmp_path="$(mktemp -t -d guix.XXXXXX)" tmp_path="$(mktemp -t -d guix.XXXXXX)"
@ -874,7 +889,7 @@ main_install()
if ! [[ $GUIX_BINARY_FILE_NAME =~ $ARCH_OS ]]; then if ! [[ $GUIX_BINARY_FILE_NAME =~ $ARCH_OS ]]; then
_err "$ARCH_OS not in ${GUIX_BINARY_FILE_NAME}; aborting" _err "$ARCH_OS not in ${GUIX_BINARY_FILE_NAME}; aborting"
fi fi
_msg "${INF}Using manually provided binary ${GUIX_BINARY_FILE_NAME}" _msg_info "Using manually provided binary ${GUIX_BINARY_FILE_NAME}"
GUIX_BINARY_FILE_NAME=$(realpath "$GUIX_BINARY_FILE_NAME") GUIX_BINARY_FILE_NAME=$(realpath "$GUIX_BINARY_FILE_NAME")
fi fi
@ -887,14 +902,14 @@ main_install()
sys_create_shell_completion sys_create_shell_completion
sys_customize_bashrc sys_customize_bashrc
_msg "${INF}cleaning up ${tmp_path}" _msg_info "cleaning up ${tmp_path}"
rm -r "${tmp_path}" rm -r "${tmp_path}"
_msg "${PAS}Guix has successfully been installed!" _msg_pass "Guix has successfully been installed!"
_msg "${INF}Run 'info guix' to read the manual." _msg_info "Run 'info guix' to read the manual."
# Required to source /etc/profile in desktop environments. # Required to source /etc/profile in desktop environments.
_msg "${INF}Please log out and back in to complete the installation." _msg_info "Please log out and back in to complete the installation."
} }
main_uninstall() main_uninstall()
@ -908,7 +923,7 @@ main_uninstall()
chk_init_sys chk_init_sys
chk_sys_arch chk_sys_arch
_msg "${INF}system is ${ARCH_OS}" _msg_info "system is ${ARCH_OS}"
# stop the build, package system. # stop the build, package system.
sys_delete_guix_daemon sys_delete_guix_daemon
@ -922,12 +937,12 @@ main_uninstall()
sys_delete_shell_completion sys_delete_shell_completion
# these directories are created on the fly during usage. # these directories are created on the fly during usage.
_msg "${INF}removing /etc/guix" _msg_info "removing /etc/guix"
rm -rf /etc/guix rm -rf /etc/guix
_msg "${INF}removing /var/log/guix" _msg_info "removing /var/log/guix"
rm -rf /var/log/guix rm -rf /var/log/guix
_msg "${PAS}Guix has successfully been uninstalled!" _msg_pass "Guix has successfully been uninstalled!"
} }
main() main()