X-Git-Url: https://git.hcoop.net/jackhill/guix/guix.git/blobdiff_plain/3cd4447f5639f45b7d833f6fb2adce11ea15ba1d..af4c633bbb96e6c5311248970efbab5f98790900:/etc/guix-install.sh diff --git a/etc/guix-install.sh b/etc/guix-install.sh index 78cd7580bb..aa77d42615 100755 --- a/etc/guix-install.sh +++ b/etc/guix-install.sh @@ -1,8 +1,9 @@ -#!/bin/bash +#!/bin/sh # GNU Guix --- Functional package management for GNU # Copyright © 2017 sharlatan # Copyright © 2018 Ricardo Wurmus # Copyright © 2018 Efraim Flashner +# Copyright © 2019, 2020 Tobias Geerinckx-Rice # # This file is part of GNU Guix. # @@ -19,6 +20,13 @@ # 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. +if [ "x$BASH_VERSION" = "x" ] +then + exec bash "$0" "$@" +fi + set -e [ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1; } @@ -40,6 +48,7 @@ REQUIRE=( "groupadd" "tail" "tr" + "xz" ) PAS=$'[ \033[32;1mPASS\033[0m ] ' @@ -47,7 +56,7 @@ ERR=$'[ \033[31;1mFAIL\033[0m ] ' INF="[ INFO ] " DEBUG=0 -GNU_URL="https://alpha.gnu.org/gnu/guix/" +GNU_URL="https://ftp.gnu.org/gnu/guix/" OPENPGP_SIGNING_KEY_ID="3CE464558A84FDC69DB40CFB090B11993D9AEBB5" # This script needs to know where root's home directory is. However, we @@ -78,17 +87,13 @@ _debug() chk_require() { # Check that every required command is available. - declare -a cmds declare -a warn - - cmds=(${1}) + local c _debug "--- [ $FUNCNAME ] ---" - for c in ${cmds[@]}; do - command -v "$c" &>/dev/null - [ "$?" -eq "1" ] && - warn+=("$c") + for c in "$@"; do + command -v "$c" &>/dev/null || warn+=("$c") done [ "${#warn}" -ne 0 ] && @@ -96,10 +101,17 @@ chk_require() return 1; } _msg "${PAS}verification of required commands completed" +} - gpg --list-keys ${OPENPGP_SIGNING_KEY_ID} >/dev/null 2>&1 || ( +chk_gpg_keyring() +{ # Check whether the Guix release signing public key is present. + _debug "--- [ $FUNCNAME ] ---" + + # Without --dry-run this command will create a ~/.gnupg owned by root on + # systems where gpg has never been used, causing errors and confusion. + gpg --dry-run --list-keys ${OPENPGP_SIGNING_KEY_ID} >/dev/null 2>&1 || ( _err "${ERR}Missing OpenPGP public key. Fetch it with this command:" - echo " gpg --keyserver pgp.mit.edu --recv-keys ${OPENPGP_SIGNING_KEY_ID}" + echo " wget 'https://sv.gnu.org/people/viewgpg.php?user_id=15145' -qO - | sudo -i gpg --import -" exit 1 ) } @@ -130,7 +142,7 @@ chk_init_sys() _msg "${INF}init system is: upstart" INIT_SYS="upstart" return 0 - elif [[ $(systemctl) =~ -\.mount ]]; then + elif [[ $(systemctl 2>/dev/null) =~ -\.mount ]]; then _msg "${INF}init system is: systemd" INIT_SYS="systemd" return 0 @@ -162,6 +174,9 @@ chk_sys_arch() aarch64) local arch=aarch64 ;; + armv7l) + local arch=armhf + ;; *) _err "${ERR}Unsupported CPU type: ${arch}" exit 1 @@ -268,12 +283,13 @@ sys_create_store() fi _msg "${INF}Linking the root user's profile" - ln -sf /var/guix/profiles/per-user/root/guix-profile \ - "${ROOT_HOME}/.guix-profile" + mkdir -p "${ROOT_HOME}/.config/guix" + ln -sf /var/guix/profiles/per-user/root/current-guix \ + "${ROOT_HOME}/.config/guix/current" - GUIX_PROFILE="${ROOT_HOME}/.guix-profile" + GUIX_PROFILE="${ROOT_HOME}/.config/guix/current" source "${GUIX_PROFILE}/etc/profile" - _msg "${PAS}activated root profile at /root/.guix-profile" + _msg "${PAS}activated root profile at ${ROOT_HOME}/.config/guix/current" } sys_create_build_user() @@ -316,28 +332,61 @@ sys_enable_guix_daemon() info_path="/usr/local/share/info" local_bin="/usr/local/bin" - var_guix="/var/guix/profiles/per-user/root/guix-profile" + var_guix="/var/guix/profiles/per-user/root/current-guix" case "$INIT_SYS" in upstart) { initctl reload-configuration; - cp "${ROOT_HOME}/.guix-profile/lib/upstart/system/guix-daemon.conf" \ + cp "${ROOT_HOME}/.config/guix/current/lib/upstart/system/guix-daemon.conf" \ /etc/init/ && start guix-daemon; } && _msg "${PAS}enabled Guix daemon via upstart" ;; systemd) - { cp "${ROOT_HOME}/.guix-profile/lib/systemd/system/guix-daemon.service" \ + { # systemd .mount units must be named after the target directory. + # Here we assume a hard-coded name of /gnu/store. + # XXX Work around until next release. + if [ -f "${ROOT_HOME}/.config/guix/current/lib/systemd/system/gnu-store.mount" ]; then + cp "${ROOT_HOME}/.config/guix/current/lib/systemd/system/gnu-store.mount" \ + /etc/systemd/system/; + chmod 664 /etc/systemd/system/gnu-store.mount; + systemctl daemon-reload && + systemctl enable gnu-store.mount; + fi + + cp "${ROOT_HOME}/.config/guix/current/lib/systemd/system/guix-daemon.service" \ /etc/systemd/system/; chmod 664 /etc/systemd/system/guix-daemon.service; + + # Work around , present in 1.0.1. + sed -i /etc/systemd/system/guix-daemon.service \ + -e "s/GUIX_LOCPATH='/'GUIX_LOCPATH=/"; + + # Work around , present in 1.0.1. + if ! grep en_US /etc/systemd/system/guix-daemon.service >/dev/null; + then sed -i /etc/systemd/system/guix-daemon.service \ + -e 's/^Environment=\(.*\)$/Environment=\1 LC_ALL=en_US.UTF-8'; + fi; + systemctl daemon-reload && - systemctl start guix-daemon && - systemctl enable guix-daemon; } && + systemctl enable guix-daemon && + systemctl start guix-daemon; } && _msg "${PAS}enabled Guix daemon via systemd" ;; + sysv-init) + { mkdir -p /etc/init.d; + cp "${ROOT_HOME}/.config/guix/current/etc/init.d/guix-daemon" \ + /etc/init.d/guix-daemon; + chmod 775 /etc/init.d/guix-daemon; + + update-rc.d guix-daemon defaults && + update-rc.d guix-daemon enable && + service guix-daemon start; } && + _msg "${PAS}enabled Guix daemon via sysv" + ;; NA|*) _msg "${ERR}unsupported init system; run the daemon manually:" - echo " ${ROOT_HOME}/.guix-profile/bin/guix-daemon --build-users-group=guixbuild" + echo " ${ROOT_HOME}/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild" ;; esac @@ -353,14 +402,12 @@ sys_enable_guix_daemon() } sys_authorize_build_farms() -{ # authorize the public keys of the two build farms +{ # authorize the public key of the build farm while true; do - read -p "Permit downloading pre-built package binaries from the project's build farms? (yes/no) " yn + read -p "Permit downloading pre-built package binaries from the project's build farm? (yes/no) " yn case $yn in - [Yy]*) guix archive --authorize < "${ROOT_HOME}/.guix-profile/share/guix/hydra.gnu.org.pub" && - _msg "${PAS}Authorized public key for hydra.gnu.org"; - guix archive --authorize < "${ROOT_HOME}/.guix-profile/share/guix/berlin.guixsd.org.pub" && - _msg "${PAS}Authorized public key for berlin.guixsd.org"; + [Yy]*) guix archive --authorize < "${ROOT_HOME}/.config/guix/current/share/guix/ci.guix.gnu.org.pub" && + _msg "${PAS}Authorized public key for ci.guix.gnu.org"; break;; [Nn]*) _msg "${INF}Skipped authorizing build farm public keys" break;; @@ -369,6 +416,35 @@ sys_authorize_build_farms() done } +sys_create_init_profile() +{ # Create /etc/profile.d/guix.sh for better desktop integration + # This will not take effect until the next shell or desktop session! + [ -d "/etc/profile.d" ] || mkdir /etc/profile.d # Just in case + cat <<"EOF" > /etc/profile.d/guix.sh +# _GUIX_PROFILE: `guix pull` profile +_GUIX_PROFILE="$HOME/.config/guix/current" +if [ -L $_GUIX_PROFILE ]; then + export PATH="$_GUIX_PROFILE/bin${PATH:+:}$PATH" + # Export INFOPATH so that the updated info pages can be found + # and read by both /usr/bin/info and/or $GUIX_PROFILE/bin/info + # When INFOPATH is unset, add a trailing colon so that Emacs + # searches 'Info-default-directory-list'. + export INFOPATH="$_GUIX_PROFILE/share/info:$INFOPATH" +fi + +# GUIX_PROFILE: User's default profile +GUIX_PROFILE="$HOME/.guix-profile" +[ -L $GUIX_PROFILE ] || return +GUIX_LOCPATH="$GUIX_PROFILE/lib/locale" +export GUIX_PROFILE GUIX_LOCPATH + +[ -f "$GUIX_PROFILE/etc/profile" ] && . "$GUIX_PROFILE/etc/profile" + +# set XDG_DATA_DIRS to include Guix installations +export XDG_DATA_DIRS="$GUIX_PROFILE/share:${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}" +EOF +} + welcome() { cat<<"EOF" @@ -408,12 +484,14 @@ main() _msg "Starting installation ($(date))" chk_term - chk_require "${REQUIRE[*]}" + chk_require "${REQUIRE[@]}" + chk_gpg_keyring chk_init_sys chk_sys_arch _msg "${INF}system is ${ARCH_OS}" + umask 0022 tmp_path="$(mktemp -t -d guix.XXX)" guix_get_bin_list "${GNU_URL}" @@ -423,12 +501,16 @@ main() sys_create_build_user sys_enable_guix_daemon sys_authorize_build_farms + sys_create_init_profile _msg "${INF}cleaning up ${tmp_path}" rm -r "${tmp_path}" _msg "${PAS}Guix has successfully been installed!" _msg "${INF}Run 'info guix' to read the manual." + + # Required to source /etc/profile in desktop environments. + _msg "${INF}Please log out and back in to complete the installation." } main "$@"