#!/bin/sh # GNU Guix --- Functional package management for GNU # Copyright © 2017 sharlatan # Copyright © 2018 Ricardo Wurmus # Copyright © 2018 Efraim Flashner # Copyright © 2019–2020, 2022 Tobias Geerinckx-Rice # Copyright © 2020 Morgan Smith # Copyright © 2020 Simon Tournier # Copyright © 2020 Daniel Brooks # Copyright © 2021 Jakub Kądziołka # Copyright © 2021 Chris Marusich # Copyright © 2021, 2022, 2023 Maxim Cournoyer # Copyright © 2022 Prafulla Giri # Copyright © 2023 Andrew Tropin # Copyright © 2020 David A. Redick # Copyright © 2024 Janneke Nieuwenhuizen # Copyright © 2024 Tomas Volf <~@wolfsden.cz> # Copyright © 2024 Richard Sent # # This file is part of GNU Guix. # # GNU Guix is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or (at # your option) any later version. # # GNU Guix is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Guix. If not, see . # We require Bash but for portability we'd rather not use /bin/bash or # /usr/bin/env in the shebang, hence this hack. # Environment variables # # GUIX_BINARY_FILE_NAME # # Can be used to override the automatic download mechanism and point # to a local Guix binary archive filename like # "/tmp/guix-binary-1.4.0rc2.armhf-linux.tar.xz" # # GUIX_ALLOW_OVERWRITE # # Instead of aborting to avoid overwriting a previous installations, # allow copying over /var/guix or /gnu. This can be useful when the # installation required the user to extract Guix packs under /gnu to # satisfy its dependencies. if [ "x$BASH_VERSION" = "x" ] then exec bash "$0" "$@" fi set -eo pipefail [ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1; } REQUIRE=( "dirname" "readlink" "wget" "gpg" "grep" "which" "sed" "sort" "getent" "mktemp" "rm" "chmod" "uname" "groupadd" "groupdel" "useradd" "userdel" "tail" "tr" "xz" ) # Add variables using form FOO_INIT_REQUIRE when init system FOO dependencies # should be checked. SYSV_INIT_REQUIRE=( "daemonize" ) PAS=$'[ \033[32;1mPASS\033[0m ] ' ERR=$'[ \033[31;1mFAIL\033[0m ] ' WAR=$'[ \033[33;1mWARN\033[0m ] ' INF="[ INFO ] " DEBUG=0 GNU_URL="https://ftp.gnu.org/gnu/guix/" #GNU_URL="https://alpha.gnu.org/gnu/guix/" # The following associative array holds set of GPG keys used to sign the # releases, keyed by their corresponding Savannah user ID. declare -A GPG_SIGNING_KEYS GPG_SIGNING_KEYS[15145]=3CE464558A84FDC69DB40CFB090B11993D9AEBB5 # ludo GPG_SIGNING_KEYS[127547]=27D586A4F8900854329FF09F1260E46482E63562 # maxim # ------------------------------------------------------------------------------ #+UTILITIES _err() { # All errors go to stderr. printf "[%s]: %s\n" "$(date +%s.%3N)" "$1" } _msg() { # Default message to stdout. printf "[%s]: %s\n" "$(date +%s.%3N)" "$1" } _debug() { if [ "${DEBUG}" = '1' ]; then printf "[%s]: %s\n" "$(date +%s.%3N)" "$1" fi } die() { _err "${ERR}$*" exit 1 } # Return true if user answered yes, false otherwise. The prompt is # yes-biased, that is, when the user simply enter newline, it is equivalent to # answering "yes". # $1: The prompt question. prompt_yes_no() { local -l yn read -rp "$1 [Y/n]" yn [[ ! $yn || $yn = y || $yn = yes ]] || return 1 } chk_require() { # Check that every required command is available. declare -a warn local c _debug "--- [ ${FUNCNAME[0]} ] ---" for c in "$@"; do command -v "$c" &>/dev/null || warn+=("$c") done [ "${#warn}" -ne 0 ] && die "Missing commands: ${warn[*]}." _msg "${PAS}verification of required commands completed" } add_init_sys_require() { # Add the elements of FOO_INIT_SYS to REQUIRE local init_require="${INIT_SYS}_REQUIRE[@]" if [[ ! -z "$init_require" ]]; then # Have to add piecemeal because ${!foo[@]} performs direct array key # expansion, not indirect plain array expansion. for r in "${!init_require}"; do REQUIRE+=("$r") done fi } chk_gpg_keyring() { # Check whet