Subject: Re: [bug#78210] [PATCH] guix: include store parent dirs in docker layer

From: Ludovic Courtès <[email-masked]>
Date: Sun, 18 May 2025 22:34:23 +0200

Hi Ray,

Ray Miller <[email-masked]> writes:

> This patch adds the /gnu and /gnu/store directories to the Docker layer
> created by `guix pack -f docker ...` which enables the Docker image to be
> used to create an AWS Lambda function. Without the patch, creating the AWS
> Lambda function fails with this error:
>
> "MissingParentDirectory: Parent directory does not exist for file: 
> gnu/store/zic27jikg36d6wjj4cz8hyriyfl3ygiz-info-dir/"
>
> My first attempt to fix this was just to add the /gnu and /gnu/store 
> directories
> to `directives` but the Docker image failed in AWS Lambda with the same 
> error. These
> directories need to appear in the tarball for the layer *before* the 
> packages,
> so the change to the order of the tar arguments is also needed.
>
> * guix/scripts/pack.scm: add /gnu and /gnu/store directories to the
> docker layer.
> * guix/docker.scm: change order of arguments to tar so parent
> directories are added before their contents.
>
> Change-Id: I2b103c59981e828c965564ccc5d2415b00a7e52e

Neat!

Could you include in the commit log a line like:

  Fixes <https://issues.guix.gnu.org/XYZ>.

… so we can keep track of where this was reported and discussed?

> +++ b/guix/scripts/pack.scm
> @@ -580,9 +580,11 @@ (define* (docker-image name profile
>                       (,source -> ,target))))))
>
>              (define directives
> -              ;; Create a /tmp directory, as some programs expect it, and
> -              ;; create SYMLINKS.
> +              ;; Create /tmp, /gnu, and /gnu/store directories, as some
> +              ;; programs expect them, and create SYMLINKS.
>                `((directory "/tmp" ,(getuid) ,(getgid) #o1777)
> +                (directory "/gnu" ,(getuid) ,(getgid) #o755)
> +                (directory "/gnu/store" ,(getuid) ,(getgid) #o755)

It’s a bit trickier, because “/gnu/store” is not hardcoded.

Instead, you need to recurse over the components of (%store-prefix), so
something like:

  `((directory "/tmp" …)
    #$@(map (lambda (component)
              #~(directory #$component …))
            (string-tokenize (%store-prefix)
                             (char-set-complement (char-set #\/)))))

But perhaps this should actually be done in (guix docker) so that ‘guix
system image -t docker’ also benefits from it?

Thanks,
Ludo’.