all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
blob fa9a5f59052a5095056dace04b248ff7888d7b87 7021 bytes (raw)
name: guix/build/pack.scm 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
 
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021, 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;; This module contains build-side common procedures used by the host-side
;;; (guix scripts pack) module, mostly to allow for code reuse.  Due to making
;;; use of the (guix build store-copy) module, it transitively requires the
;;; sqlite and gcrypt extensions to be available.

;;; Code:

(define-module (guix build pack)
  #:use-module (gnu build install)
  #:use-module (guix build utils)
  #:use-module (guix build store-copy)
  #:use-module ((guix build union) #:select (relative-file-name))
  #:use-module (ice-9 match)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-26)
  #:export (tar-base-options
            populate-profile-root!
            build-self-contained-tarball))

(define* (tar-base-options #:key tar compressor)
  "Return the base GNU tar options required to produce deterministic archives
deterministically.  When TAR, a GNU tar command file name, is provided, the
`--sort' option is used only if supported.  When COMPRESSOR, a command such as
'(\"gzip\" \"-9n\"), is provided, the compressor is explicitly specified via
the `-I' option."
  (define (tar-supports-sort? tar)
    (with-error-to-port (%make-void-port "w")
      (lambda ()
        (zero? (system* tar "cf" "/dev/null" "--files-from=/dev/null"
                        "--sort=name")))))

  `(,@(if compressor
          (list "-I" (string-join compressor))
          '())
    ;; The --sort option was added to GNU tar in version 1.28, released
    ;; 2014-07-28.  For testing, we use the bootstrap tar, which is older
    ;; and doesn't support it.
    ,@(if (and=> tar tar-supports-sort?)
          '("--sort=name")
          '())
    ;; Use GNU format so there's no file name length limitation.
    "--format=gnu"
    "--mtime=@1"
    "--owner=root:0"
    "--group=root:0"
    ;; The 'nlink' of the store item files leads tar to store hard links
    ;; instead of actual copies.  However, the 'nlink' count depends on
    ;; deduplication in the store; it's an "implicit input" to the build
    ;; process.  Use '--hard-dereference' to eliminate it.
    "--hard-dereference"
    "--check-links"))

(define (assert-utf8-locale)
  "Verify the current process is using the en_US.utf8 locale."
  (unless (string=? "unset for tests" (getenv "GUIX_LOCPATH"))
    (unless (false-if-exception (setlocale LC_ALL "en_US.utf8"))
      (error "environment not configured for en_US.utf8 locale"))))

(define* (populate-profile-root! profile
                                 #:key (profile-name "guix-profile")
                                 localstatedir?
                                 store-database
                                 deduplicate?
                                 (symlinks '()))
  "Populate the root profile directory with SYMLINKS and a Guix database, when
LOCALSTATEDIR? is set, and a pre-computed STORE-DATABASE is provided.  The
directory is created as \"root\" in the current working directory.  When
DEDUPLICATE? is true, deduplicate the store items, which relies on hard
links.  It needs to run in an environment where "
  (when localstatedir?
    (unless store-database
      (error "missing STORE-DATABASE argument")))

  (define symlink->directives
    ;; Return "populate directives" to make the given symlink and its
    ;; parent directories.
    (match-lambda
      ((source '-> target)
       (let ((target (string-append profile "/" target))
             (parent (dirname source)))
         ;; Never add a 'directory' directive for "/" so as to
         ;; preserve its ownership when extracting the archive (see
         ;; below), and also because this would lead to adding the
         ;; same entries twice in the tarball.
         `(,@(if (string=? parent "/")
                 '()
                 `((directory ,parent)))
           ;; Use a relative file name for compatibility with
           ;; relocatable packs.
           (,source -> ,(relative-file-name parent target)))))))

  (define directives
    ;; Fully-qualified symlinks.
    (append-map symlink->directives symlinks))

  (define %root "root")

  (assert-utf8-locale)

  ;; Note: there is not much to gain here with deduplication and there
  ;; is the overhead of the '.links' directory, so turn it off by
  ;; default.  Furthermore GNU tar < 1.30 sometimes fails to extract
  ;; tarballs with hard links:
  ;; <http://lists.gnu.org/archive/html/bug-tar/2017-11/msg00009.html>.
  (populate-store (list "profile") %root #:deduplicate? deduplicate?)

  (when localstatedir?
    (install-database-and-gc-roots %root store-database
                                   profile #:profile-name profile-name))

  ;; Create SYMLINKS.
  (for-each (cut evaluate-populate-directive <> %root) directives))

(define* (build-self-contained-tarball profile
                                       tarball-file-name
                                       #:key (profile-name "guix-profile")
                                       target
                                       localstatedir?
                                       store-database
                                       deduplicate?
                                       symlinks
                                       compressor-command
                                       archiver)
  "Create a self-contained tarball TARBALL-FILE-NAME from PROFILE, optionally
compressing it with COMPRESSOR-COMMAND, the complete command-line string to
use for the compressor."
  (assert-utf8-locale)

  (populate-profile-root! profile
                          #:profile-name profile-name
                          #:localstatedir? localstatedir?
                          #:store-database store-database
                          #:deduplicate? deduplicate?
                          #:symlinks symlinks)

  (define tar (string-append archiver "/bin/tar"))

  ;; GNU Tar recurses directories by default.  Simply add the whole root
  ;; directory, which contains all the files to be archived.  This avoids
  ;; creating duplicate files in the archives that would be stored as hard
  ;; links by GNU Tar.
  (apply invoke tar "-cvf" tarball-file-name "-C" "root" "."
         (tar-base-options
          #:tar tar
          #:compressor compressor-command)))

debug log:

solving fa9a5f5905 ...
found fa9a5f5905 in https://yhetil.org/guix/20230304031523.24102-1-maxim.cournoyer@gmail.com/
found 3b73d1b227 in https://git.savannah.gnu.org/cgit/guix.git
preparing index
index prepared:
100644 3b73d1b2272891a1764f10b61786e05da5982d4c	guix/build/pack.scm

applying [1/1] https://yhetil.org/guix/20230304031523.24102-1-maxim.cournoyer@gmail.com/
diff --git a/guix/build/pack.scm b/guix/build/pack.scm
index 3b73d1b227..fa9a5f5905 100644

Checking patch guix/build/pack.scm...
Applied patch guix/build/pack.scm cleanly.

index at:
100644 fa9a5f59052a5095056dace04b248ff7888d7b87	guix/build/pack.scm

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.