diff mbox series

[bug#60068,1/2] guix-install.sh: Add GUIX_ALLOW_OVERWRITE environment variable.

Message ID 20221214155603.29381-1-maxim.cournoyer@gmail.com
State New
Headers show
Series [bug#60068,1/2] guix-install.sh: Add GUIX_ALLOW_OVERWRITE environment variable. | expand

Commit Message

Maxim Cournoyer Dec. 14, 2022, 3:56 p.m. UTC
The need for this use case appeared when attempting to install Guix on a truly
minimal image made with Buildroot, which lacked enough GNU components that I
had to extract a guix pack to /gnu before attempting installation, which would
then refuse to proceed because of the existing /gnu.

* etc/guix-install.sh: Document environment variables.
(REQUIRE): Add missing "useradd" command.
(sys_create_store) [GUIX_ALLOW_OVERWRITE]: Skip pre-existing installation
checks and output a warning.  Extract the tarball directly to /.
---
 etc/guix-install.sh | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)


base-commit: 1b6e251ed1bae7aa2f544e8ccb6b4aaf872e77e6

Comments

Tobias Geerinckx-Rice Dec. 14, 2022, 4:16 p.m. UTC | #1
Hi Maxim,

Nice!  More steps towards world domination.

Maxim Cournoyer 写道:
> +# Environment variables

These sound like they should be command-line arguments.

[…]

Actually, I'm not totally sold on GUIX_ALLOW_OVERWRITE.  It's not 
solving much a problem.

Instead, the error message could be specific about what it 
considers a ‘previous Guix installation’ — which would be a good 
idea regardless — and tell the admin exactly what needs to be 
removed to continue.

>      "groupadd"
> +    "useradd"

Good catch, but separate patch.  (♪)

> -    if [[ -e "/var/guix" || -e "/gnu" ]]; then
> +    if [[ -z $GUIX_ALLOW_OVERWRITE && (-e /var/guix || -e /gnu) 
> ]]; then
>          die "A previous Guix installation was found.  Refusing 
>          to overwrite."
> +    else
> +        _msg "${WAR}Overwriting existing installation!"
>      fi
>  
>      cd "$tmp_path"
> -    tar --extract --file "$pkg" && _msg "${PAS}unpacked 
> archive"
> -
>      _msg "${INF}Installing /var/guix and /gnu..."
> -    mv "${tmp_path}/var/guix" /var/
> -    mv "${tmp_path}/gnu" /
> +    tar --extract --file "$pkg" -C /

I'm still in favour of using something like ‘mktemp -d 
/gnu.XXXXXX’ here if there's no security flaw I missed.  WDYT?

If the overwrite functionality is kept, we should remove the old 
directories before re-populating them.

Kind regards,

T G-R
Maxim Cournoyer Dec. 14, 2022, 6:25 p.m. UTC | #2
Hi Tobias,

Tobias Geerinckx-Rice <me@tobias.gr> writes:

> Hi Maxim,
>
> Nice!  More steps towards world domination.

Eh :-)

> Maxim Cournoyer 写道:
>> +# Environment variables
>
> These sound like they should be command-line arguments.

I agree, but that'd require a loop, or GNU getopt, and I'm not motivated
enough in the moment to re-design it :-).  When we get there, we could
add an --uninstall option too.

> […]
>
> Actually, I'm not totally sold on GUIX_ALLOW_OVERWRITE.  It's not
> solving much a problem.

The problem it solves for me was that I needed to use 'guix pack'd
dependencies such as gpg, glibc for getent, and shadow's
groupadd/useradd, etc. to satisfy the install script dependencies on my
weird target OS (minimal busybox embedded OS); which are needed to be
unpacked under /gnu, thus conflicting with the requirement that /gnu
doesn't exist.

I tried a relocatable pack, but it didn't work, at least for gpg (file
not found error).

> Instead, the error message could be specific about what it considers a
> ‘previous Guix installation’ — which would be a good idea regardless —
> and tell the admin exactly what needs to be removed to continue.
>
>>      "groupadd"
>> +    "useradd"
>
> Good catch, but separate patch.  (♪)

OK!

>> -    if [[ -e "/var/guix" || -e "/gnu" ]]; then
>> +    if [[ -z $GUIX_ALLOW_OVERWRITE && (-e /var/guix || -e /gnu) ]];
>> then
>>          die "A previous Guix installation was found.  Refusing
>> to overwrite."
>> +    else
>> +        _msg "${WAR}Overwriting existing installation!"
>>      fi
>>       cd "$tmp_path"
>> -    tar --extract --file "$pkg" && _msg "${PAS}unpacked archive"
>> -
>>      _msg "${INF}Installing /var/guix and /gnu..."
>> -    mv "${tmp_path}/var/guix" /var/
>> -    mv "${tmp_path}/gnu" /
>> +    tar --extract --file "$pkg" -C /
>
> I'm still in favour of using something like ‘mktemp -d /gnu.XXXXXX’
> here if there's no security flaw I missed.  WDYT?
>
> If the overwrite functionality is kept, we should remove the old
> directories before re-populating them.

Hopefully the reason the above makes more sense is also covered by my
use case explanation above.

Is the use case/change motivation a bit clearer now?
Maxim Cournoyer Feb. 4, 2023, 4:36 a.m. UTC | #3
Hi Tobias and Ludovic,

Had you seen my reply below?  It seems you had perhaps misunderstood the
use case at hand?

Maxim Cournoyer <maxim.cournoyer@gmail.com> writes:

> Hi Tobias,
>
> Tobias Geerinckx-Rice <me@tobias.gr> writes:
>
>> Hi Maxim,
>>
>> Nice!  More steps towards world domination.
>
> Eh :-)
>
>> Maxim Cournoyer 写道:
>>> +# Environment variables
>>
>> These sound like they should be command-line arguments.
>
> I agree, but that'd require a loop, or GNU getopt, and I'm not motivated
> enough in the moment to re-design it :-).  When we get there, we could
> add an --uninstall option too.
>
>> […]
>>
>> Actually, I'm not totally sold on GUIX_ALLOW_OVERWRITE.  It's not
>> solving much a problem.
>
> The problem it solves for me was that I needed to use 'guix pack'd
> dependencies such as gpg, glibc for getent, and shadow's
> groupadd/useradd, etc. to satisfy the install script dependencies on my
> weird target OS (minimal busybox embedded OS); which are needed to be
> unpacked under /gnu, thus conflicting with the requirement that /gnu
> doesn't exist.
>
> I tried a relocatable pack, but it didn't work, at least for gpg (file
> not found error).
diff mbox series

Patch

diff --git a/etc/guix-install.sh b/etc/guix-install.sh
index fb9006b3e2..06730f7e3f 100755
--- a/etc/guix-install.sh
+++ b/etc/guix-install.sh
@@ -29,6 +29,22 @@ 
 
 # 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" "$@"
@@ -53,6 +69,7 @@  REQUIRE=(
     "chmod"
     "uname"
     "groupadd"
+    "useradd"
     "tail"
     "tr"
     "xz"
@@ -337,16 +354,15 @@  sys_create_store()
 
     _debug "--- [ ${FUNCNAME[0]} ] ---"
 
-    if [[ -e "/var/guix" || -e "/gnu" ]]; then
+    if [[ -z $GUIX_ALLOW_OVERWRITE && (-e /var/guix || -e /gnu) ]]; then
         die "A previous Guix installation was found.  Refusing to overwrite."
+    else
+        _msg "${WAR}Overwriting existing installation!"
     fi
 
     cd "$tmp_path"
-    tar --extract --file "$pkg" && _msg "${PAS}unpacked archive"
-
     _msg "${INF}Installing /var/guix and /gnu..."
-    mv "${tmp_path}/var/guix" /var/
-    mv "${tmp_path}/gnu" /
+    tar --extract --file "$pkg" -C /
 
     _msg "${INF}Linking the root user's profile"
     mkdir -p ~root/.config/guix