X-Git-Url: https://git.hcoop.net/jackhill/guix/guix.git/blobdiff_plain/f30830b2e67d973f2363903dbe5b27269da1901a..af4c633bbb96e6c5311248970efbab5f98790900:/etc/guix-install.sh diff --git a/etc/guix-install.sh b/etc/guix-install.sh index 8eb5214049..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,14 +87,12 @@ _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 + for c in "$@"; do command -v "$c" &>/dev/null || warn+=("$c") done @@ -94,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 pool.sks-keyservers.net --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 ) } @@ -128,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 @@ -329,14 +343,47 @@ sys_enable_guix_daemon() _msg "${PAS}enabled Guix daemon via upstart" ;; systemd) - { cp "${ROOT_HOME}/.config/guix/current/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}/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild" @@ -355,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}/.config/guix/current/share/guix/hydra.gnu.org.pub" && - _msg "${PAS}Authorized public key for hydra.gnu.org"; - guix archive --authorize < "${ROOT_HOME}/.config/guix/current/share/guix/ci.guix.info.pub" && - _msg "${PAS}Authorized public key for ci.guix.info"; + [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;; @@ -371,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" @@ -410,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}" @@ -425,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 "$@"