diff mbox series

[bug#58576] system: image: Define correct docker image arch when cross building

Message ID 20221017012843.29975-1-bauermann@kolabnow.com
State New
Headers show
Series [bug#58576] system: image: Define correct docker image arch when cross building | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git-branch success View Git branch
cbaines/applying patch success View Laminar job
cbaines/issue success View issue

Commit Message

Thiago Jung Bauermann Oct. 17, 2022, 1:28 a.m. UTC
From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>

Cross-building a docker image with:

  $ guix system image --image-type=docker --target=aarch64-linux-gnu os.scm

results in an image where the architecture declared in its config.json is
the host architecture rather than the target one.  The binaries are
correctly cross-compiled, so the image can be loaded and used despite the
warning message shown by docker:

  $ docker load -i vcal7bvsqcijchifhqdvprpd1niqh8sk-docker-image.tar.gz
  Loaded image: guix:latest
  $ docker create guix:latest
  WARNING: The requested image's platform (linux/amd64) does not match the
  detected host platform (linux/arm64/v8) and no specific platform was
  requested
  40f06aa869ed690489c4a3824a7f7721bd4bf453b85f25ac7199266939fe2fba
  $ echo $?
  0

This is fixed by passing the correct triplet to the build-docker-image
function.

* gnu/system/image.scm (system-docker-image) Add ‘image-target’ variable.
[builder]: Pass ‘#:system’ argument to ‘build-docker-image’.
---
 gnu/system/image.scm | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Mathieu Othacehe Oct. 17, 2022, 7:54 a.m. UTC | #1
Hello Thiago,

Thanks for this patch!

> +         (image-target (or (%current-target-system)
> +                           (and=> (image-platform image) platform-target)
> +                           (nix-system->gnu-triplet)))

There's the following snippet in "system-image" that is trying to do the
right thing (and it is not easy) with the "target" value.

--8<---------------cut here---------------start------------->8---
  ;; The image platform definition may provide the appropriate "system"
  ;; architecture for the image.  If we are already running on this system,
  ;; the image can be built natively.  If we are running on a different
  ;; system, then we need to cross-compile, using the "target" provided by the
  ;; image definition.
  (define system (and=> platform platform-system))
  (define target (cond
                  ;; No defined platform, let's use the user defined
                  ;; system/target parameters.
                  ((not platform)
                   (%current-target-system))
                  ;; The current system is the same as the platform system, no
                  ;; need to cross-compile.
                  ((and system
                        (string=? system (%current-system)))
                   #f)
                  ;; If there is a user defined target let's override the
                  ;; platform target. Otherwise, we can cross-compile to the
                  ;; platform target.
                  (else
                   (or (%current-target-system)
                       (and=> platform platform-target)))))
--8<---------------cut here---------------end--------------->8---

The rationale is that the user supplied %current-target-system is always
overriding the image platform field. Then, %current-target-system is set
to the "target" value defined above.

It makes me think that you could use %current-target-system directly as
the "image-target" value. WDYT?

Mathieu
Thiago Jung Bauermann Oct. 26, 2022, 11:47 p.m. UTC | #2
Hello Mathieu,

Thank you for reviewing my patch! Sorry for the delay, I've been
traveling.

Mathieu Othacehe <othacehe@gnu.org> writes:

> Hello Thiago,
>
> Thanks for this patch!
>
>> +         (image-target (or (%current-target-system)
>> +                           (and=> (image-platform image) platform-target)
>> +                           (nix-system->gnu-triplet)))
>
> There's the following snippet in "system-image" that is trying to do the
> right thing (and it is not easy) with the "target" value.
>
>   ;; The image platform definition may provide the appropriate "system"
>   ;; architecture for the image.  If we are already running on this system,
>   ;; the image can be built natively.  If we are running on a different
>   ;; system, then we need to cross-compile, using the "target" provided by the
>   ;; image definition.
>   (define system (and=> platform platform-system))
>   (define target (cond
>                   ;; No defined platform, let's use the user defined
>                   ;; system/target parameters.
>                   ((not platform)
>                    (%current-target-system))
>                   ;; The current system is the same as the platform system, no
>                   ;; need to cross-compile.
>                   ((and system
>                         (string=? system (%current-system)))
>                    #f)
>                   ;; If there is a user defined target let's override the
>                   ;; platform target. Otherwise, we can cross-compile to the
>                   ;; platform target.
>                   (else
>                    (or (%current-target-system)
>                        (and=> platform platform-target)))))
>
> The rationale is that the user supplied %current-target-system is always
> overriding the image platform field. Then, %current-target-system is set
> to the "target" value defined above.
>
> It makes me think that you could use %current-target-system directly as
> the "image-target" value. WDYT?

I don't think “%current-target-system” can be used directly as the
“image-target” value because for native builds it will be #f and my
understanding is that “build-docker-image” would throw an error when
receiving #f for the “#:system” argument.

So I still need the or expression above, but I can drop the middle
expression that calls “platform-target” because it's redundant with the
snippet you posted above. Thank you for pointing it out.

I'll send a v2 with the change.
diff mbox series

Patch

diff --git a/gnu/system/image.scm b/gnu/system/image.scm
index 5fc0d55d9a14..c6d7d13f6daf 100644
--- a/gnu/system/image.scm
+++ b/gnu/system/image.scm
@@ -652,6 +652,9 @@  (define shared-network?
                shared-network?)
               (list boot-program)))
          (substitutable? (image-substitutable? image))
+         (image-target (or (%current-target-system)
+                           (and=> (image-platform image) platform-target)
+                           (nix-system->gnu-triplet)))
          (register-closures? (has-guix-service-type? os))
          (schema (and register-closures?
                       (local-file (search-path %load-path
@@ -705,6 +708,7 @@  (define builder
                  #:entry-point '(#$boot-program #$os)
                  #:compressor '(#+(file-append gzip "/bin/gzip") "-9n")
                  #:creation-time (make-time time-utc 0 1)
+                 #:system #$image-target
                  #:transformations `((,image-root -> ""))))))))
 
     (computed-file name builder