[PATCH 0/5] Record operating system provenance info

DoneSubmitted by Ludovic Courtès.
Details
2 participants
  • Ludovic Courtès
  • zimoun
Owner
unassigned
Severity
normal
L
L
Ludovic Courtès wrote on 30 Nov 2019 23:30
(address . guix-patches@gnu.org)(name . Ludovic Courtès)(address . ludo@gnu.org)
20191130223013.14257-1-ludo@gnu.org
Hello Guix!

This patch series allows ‘guix system’ to record provenance info
about a system in its output: the system itself (e.g.,
/run/current-system) now contains three more files: “channels.scm”,
“configuration.scm”, and “provenance” (a summary of the first two
files.)

That means you can always inspect a deployed system to find its own
“source”. In some cases, you can even run something like:

guix time-machine \
-C /var/guix/profiles/system-N-link/channels.scm -- \
system reconfigure \
/var/guix/profiles/system-N-link/configuration.scm

to rebuild generation N of your system. Pretty cool, no? :-)

Otherwise you can simply run:

guix system describe

to see where your OS comes from.

Provenance tracking is implemented as a service. The service is
automatically added by ‘guix system init’, ‘reconfigure’, and by
‘guix deploy’. For other commands, one can pass ‘--save-provenance’
to turn it on.

This was long overdue!

This has interesting implications on trustworthiness: you can
distribute a VM/Docker image with provenance info, and anyone
can reproduce it and ensure they obtain the same bits (well, ideally,
because I guess a few steps may still not be bit-reproducible).

Thoughts?

Thanks,
Ludo’.

Ludovic Courtès (5):
services: Add 'provenance-service-type'.
guix system: Use 'provenance-service-type', add "--save-provenance".
machine: Add provenance tracking to each machine operating system.
guix system: "list-generations" displays provenance info.
guix system: Add "describe" action.

doc/guix.texi | 109 +++++++++++++++++++++++++++++++++++++---
gnu/machine.scm | 7 ++-
gnu/services.scm | 87 ++++++++++++++++++++++++++++++++
gnu/system.scm | 10 ++++
guix/scripts/pull.scm | 1 +
guix/scripts/system.scm | 107 ++++++++++++++++++++++++++++++++-------
6 files changed, 293 insertions(+), 28 deletions(-)

--
2.24.0
L
L
Ludovic Courtès wrote on 30 Nov 2019 23:31
[PATCH 1/5] services: Add 'provenance-service-type'.
(address . 38441@debbugs.gnu.org)(name . Ludovic Courtès)(address . ludo@gnu.org)
20191130223148.14336-1-ludo@gnu.org
* gnu/services.scm (object->pretty-string)
(channel->code, channel->sexp, provenance-file)
(provenance-entry): New procedures.
(provenance-service-type): New variable.
* gnu/system.scm (operating-system-with-provenance): New procedure.
* doc/guix.texi (Service Reference): Document 'provenance-service-type'.
---
doc/guix.texi | 44 ++++++++++++++++++++++++
gnu/services.scm | 87 ++++++++++++++++++++++++++++++++++++++++++++++++
gnu/system.scm | 10 ++++++
3 files changed, 141 insertions(+)

Toggle diff (204 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 661aa41785..fd40b6535f 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -26970,6 +26970,50 @@ programs under @file{/run/current-system/profile}.  Other services can
 extend it by passing it lists of packages to add to the system profile.
 @end defvr
 
+@cindex provenance tracking, of the operating system
+@defvr {Scheme Variable} provenance-service-type
+This is the type of the service that records @dfn{provenance meta-data}
+in the system itself.  It creates several files under
+@file{/run/current-system}:
+
+@table @file
+@item channels.scm
+This is a ``channel file'' that can be passed to @command{guix pull -C}
+or @command{guix time-machine -C}, and which describes the channels used
+to build the system, if that information was available
+(@pxref{Channels}).
+
+@item configuration.scm
+This is the file that was passed as the value for this
+@code{provenance-service-type} service.  By default, @command{guix
+system reconfigure} automatically passes the OS configuration file it
+received on the command line.
+
+@item provenance
+This contains the same information as the two other files but in a
+format that is more readily processable.
+@end table
+
+In general, these two pieces of information (channels and configuration
+file) are enough to reproduce the operating system ``from source''.
+
+@quotation Caveats
+This information is necessary to rebuild your operating system, but it
+is not always sufficient.  In particular, @file{configuration.scm}
+itself is insufficient if it is not self-contained---if it refers to
+external Guile modules or to extra files.  If you want
+@file{configuration.scm} to be self-contained, we recommend that modules
+or files it refers to be part of a channel.
+
+Besides, provenance meta-data is ``silent'' in the sense that it does
+not change the bits contained in your system, @emph{except for the
+meta-data bits themselves}.  Two different OS configurations or sets of
+channels can lead to the same system, bit-for-bit; when
+@code{provenance-service-type} is used, these two systems will have
+different meta-data and thus different store file names, which makes
+comparison less trivial.
+@end quotation
+@end defvr
 
 @node Shepherd Services
 @subsection Shepherd Services
diff --git a/gnu/services.scm b/gnu/services.scm
index 394470ba7d..e7a3a95e43 100644
--- a/gnu/services.scm
+++ b/gnu/services.scm
@@ -25,6 +25,8 @@
   #:use-module (guix profiles)
   #:use-module (guix discovery)
   #:use-module (guix combinators)
+  #:use-module (guix channels)
+  #:use-module (guix describe)
   #:use-module (guix sets)
   #:use-module (guix ui)
   #:use-module ((guix utils) #:select (source-properties->location))
@@ -39,6 +41,7 @@
   #:use-module (srfi srfi-35)
   #:use-module (ice-9 vlist)
   #:use-module (ice-9 match)
+  #:autoload   (ice-9 pretty-print) (pretty-print)
   #:export (service-extension
             service-extension?
             service-extension-target
@@ -82,6 +85,7 @@
             ambiguous-target-service-error-target-type
 
             system-service-type
+            provenance-service-type
             boot-service-type
             cleanup-service-type
             activation-service-type
@@ -370,6 +374,89 @@ by the initrd once the root file system is mounted.")))
   ;; The service that produces the boot script.
   (service boot-service-type #t))
 
+
+;;;
+;;; Provenance tracking.
+;;;
+
+(define (object->pretty-string obj)
+  "Like 'object->string', but using 'pretty-print'."
+  (call-with-output-string
+    (lambda (port)
+      (pretty-print obj port))))
+
+(define (channel->code channel)
+  "Return code to build CHANNEL, ready to be dropped in a 'channels.scm'
+file."
+  `(channel (name ',(channel-name channel))
+            (url ,(channel-url channel))
+            (branch ,(channel-branch channel))
+            (commit ,(channel-commit channel))))
+
+(define (channel->sexp channel)
+  "Return an sexp describing CHANNEL.  The sexp is _not_ code and is meant to
+be parsed by tools; it's potentially more future-proof than code."
+  `(channel (name ,(channel-name channel))
+            (url ,(channel-url channel))
+            (branch ,(channel-branch channel))
+            (commit ,(channel-commit channel))))
+
+(define (provenance-file channels config-file)
+  "Return a 'provenance' file describing CHANNELS, a list of channels, and
+CONFIG-FILE, which can be either #f or a <local-file> containing the OS
+configuration being used."
+  (scheme-file "provenance"
+               #~(provenance
+                  (version 0)
+                  (channels #+@(if channels
+                                   (map channel->sexp channels)
+                                   '()))
+                  (configuration-file #+config-file))))
+
+(define (provenance-entry config-file)
+  "Return system entries describing the operating system provenance: the
+channels in use and CONFIG-FILE, if it is true."
+  (define profile
+    (current-profile))
+
+  (define channels
+    (and=> profile profile-channels))
+
+  (mbegin %store-monad
+    (let ((config-file (cond ((string? config-file)
+                              (local-file config-file "configuration.scm"))
+                             ((not config-file)
+                              #f)
+                             (else
+                              config-file))))
+      (return `(("provenance" ,(provenance-file channels config-file))
+                ,@(if channels
+                      `(("channels.scm"
+                         ,(plain-file "channels.scm"
+                                      (object->pretty-string
+                                       `(list
+                                         ,@(map channel->code channels))))))
+                      '())
+                ,@(if config-file
+                      `(("configuration.scm" ,config-file))
+                      '()))))))
+
+(define provenance-service-type
+  (service-type (name 'provenance)
+                (extensions
+                 (list (service-extension system-service-type
+                                          provenance-entry)))
+                (default-value #f)                ;the OS config file
+                (description
+                 "Store provenance information about the system in the system
+itself: the channels used when building the system, and its configuration
+file, when available.")))
+
+
+;;;
+;;; Cleanup.
+;;;
+
 (define (cleanup-gexp _)
   "Return a gexp to clean up /tmp and similar places upon boot."
   (with-imported-modules '((guix build utils))
diff --git a/gnu/system.scm b/gnu/system.scm
index a353b1a5c8..525b1a171d 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -110,6 +110,7 @@
 
             system-linux-image-file-name
             operating-system-with-gc-roots
+            operating-system-with-provenance
 
             boot-parameters
             boot-parameters?
@@ -539,6 +540,15 @@ bookkeeping."
                                     gc-root-service-type roots)
                     (operating-system-user-services os)))))
 
+(define* (operating-system-with-provenance os #:optional config-file)
+  "Return a variant of OS that stores its own provenance information,
+including CONFIG-FILE, if available.  This is achieved by adding an instance
+of PROVENANCE-SERVICE-TYPE to its services."
+  (operating-system
+    (inherit os)
+    (services (cons (service provenance-service-type config-file)
+                    (operating-system-user-services os)))))
+
 
 ;;;
 ;;; /etc.
-- 
2.24.0
L
L
Ludovic Courtès wrote on 30 Nov 2019 23:31
[PATCH 2/5] guix system: Use 'provenance-service-type', add "--save-provenance".
(address . 38441@debbugs.gnu.org)(name . Ludovic Courtès)(address . ludo@gnu.org)
20191130223148.14336-2-ludo@gnu.org
* guix/scripts/system.scm (show-help, %options): Add "--save-provenance".
(process-action): Define 'save-provenance?' and 'transform'; call
'transform' on the OS.
* doc/guix.texi (Invoking guix system): Document it under 'reconfigure'.
(Service Reference): Mention that 'provenance-service-type' is
automatically added by 'reconfigure' & 'init'.
---
doc/guix.texi | 61 +++++++++++++++++++++++++++++++++++------
guix/scripts/system.scm | 47 ++++++++++++++++++++-----------
2 files changed, 84 insertions(+), 24 deletions(-)

Toggle diff (187 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index fd40b6535f..3dc2fd1318 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -25839,6 +25839,15 @@ switch to it@footnote{This action (and the related actions
 @code{switch-generation} and @code{roll-back}) are usable only on
 systems already running Guix System.}.
 
+@quotation Note
+@c The paragraph below refers to the problem discussed at
+@c <https://lists.gnu.org/archive/html/guix-devel/2014-08/msg00057.html>.
+It is highly recommended to run @command{guix pull} once before you run
+@command{guix system reconfigure} for the first time (@pxref{Invoking
+guix pull}).  Failing to do that you would see an older version of Guix
+once @command{reconfigure} has completed.
+@end quotation
+
 This effects all the configuration specified in @var{file}: user
 accounts, system services, global package list, setuid programs, etc.
 The command starts system services specified in @var{file} that are not
@@ -25857,14 +25866,27 @@ It also adds a bootloader menu entry for the new OS configuration,
 entries for older configurations to a submenu, allowing you to choose
 an older system generation at boot time should you need it.
 
-@quotation Note
-@c The paragraph below refers to the problem discussed at
-@c <https://lists.gnu.org/archive/html/guix-devel/2014-08/msg00057.html>.
-It is highly recommended to run @command{guix pull} once before you run
-@command{guix system reconfigure} for the first time (@pxref{Invoking
-guix pull}).  Failing to do that you would see an older version of Guix
-once @command{reconfigure} has completed.
-@end quotation
+@cindex provenance tracking, of the operating system
+Upon completion, the new system is deployed under
+@file{/run/current-system}.  This directory contains @dfn{provenance
+meta-data}: the list of channels in use (@pxref{Channels}) and
+@var{file} itself, when available.  This information is useful should
+you later want to inspect how this particular generation was built.
+
+In fact, assuming @var{file} is self-contained, you can later rebuild
+generation @var{n} of your operating system with:
+
+@example
+guix time-machine \
+  -C /var/guix/profiles/system-@var{n}-link/channels.scm -- \
+  system reconfigure \
+  /var/guix/profiles/system-@var{n}-link/configuration.scm
+@end example
+
+You can think of it as some sort of built-in version control!  Your
+system is not just a binary artifact: @emph{it carries its own source}.
+@xref{Service Reference, @code{provenance-service-type}}, for more
+information on provenance tracking.
 
 @item switch-generation
 @cindex generations
@@ -26126,6 +26148,25 @@ This works as per @command{guix build} (@pxref{Invoking guix build}).
 Return the derivation file name of the given operating system without
 building anything.
 
+@cindex provenance tracking, of the operating system
+@item --save-provenance
+As discussed above, @command{guix system init} and @command{guix system
+reconfigure} always save provenance information @i{via} a dedicated
+service (@pxref{Service Reference, @code{provenance-service-type}}).
+However, other commands don't do that by default.  If you wish to, say,
+create a virtual machine image that contains provenance information, you
+can run:
+
+@example
+guix system vm-image --save-provenance config.scm
+@end example
+
+That way, the resulting image will effectively ``embed its own source''
+in the form of meta-data in @file{/run/current-system}.  With that
+information, one can rebuild the image to make sure it really contains
+what it pretends to contain; or they could use that to derive a variant
+of the image.
+
 @item --file-system-type=@var{type}
 @itemx -t @var{type}
 For the @code{disk-image} action, create a file system of the given
@@ -27013,6 +27054,10 @@ channels can lead to the same system, bit-for-bit; when
 different meta-data and thus different store file names, which makes
 comparison less trivial.
 @end quotation
+
+This service is automatically added to your operating system
+configuration when you use @command{guix system reconfigure} or
+@command{guix system init}.
 @end defvr
 
 @node Shepherd Services
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index e49c9d36b9..b22945658e 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -722,7 +722,9 @@ and TARGET arguments."
      (return (primitive-eval (lowered-gexp-sexp lowered))))))
 
 (define* (perform-action action os
-                         #:key skip-safety-checks?
+                         #:key
+                         save-provenance?
+                         skip-safety-checks?
                          install-bootloader?
                          dry-run? derivations-only?
                          use-substitutes? bootloader-target target
@@ -917,16 +919,18 @@ Some ACTIONS support additional ARGS.\n"))
       --image-size=SIZE  for 'vm-image', produce an image of SIZE"))
   (display (G_ "
       --no-bootloader    for 'init', do not install a bootloader"))
+  (display (G_ "
+      --save-provenance  save provenance information"))
   (display (G_ "
       --share=SPEC       for 'vm', share host file system according to SPEC"))
+  (display (G_ "
+      --expose=SPEC      for 'vm', expose host file system according to SPEC"))
   (display (G_ "
   -N, --network          for 'container', allow containers to access the network"))
   (display (G_ "
   -r, --root=FILE        for 'vm', 'vm-image', 'disk-image', 'container',
                          and 'build', make FILE a symlink to the result, and
                          register it as a garbage collector root"))
-  (display (G_ "
-      --expose=SPEC      for 'vm', expose host file system according to SPEC"))
   (display (G_ "
       --full-boot        for 'vm', make a full boot sequence"))
   (display (G_ "
@@ -977,6 +981,9 @@ Some ACTIONS support additional ARGS.\n"))
          (option '("full-boot") #f #f
                  (lambda (opt name arg result)
                    (alist-cons 'full-boot? #t result)))
+         (option '("save-provenance") #f #f
+                 (lambda (opt name arg result)
+                   (alist-cons 'save-provenance? #t result)))
          (option '("skip-checks") #f #f
                  (lambda (opt name arg result)
                    (alist-cons 'skip-safety-checks? #t result)))
@@ -1040,24 +1047,32 @@ resulting from command-line parsing."
              file-or-exp))
     obj)
 
+  (define save-provenance?
+    (or (assoc-ref opts 'save-provenance?)
+        (memq action '(init reconfigure))))
+
   (let* ((file        (match args
                         (() #f)
                         ((x . _) x)))
          (expr        (assoc-ref opts 'expression))
          (system      (assoc-ref opts 'system))
-         (os          (ensure-operating-system
-                       (or file expr)
-                       (cond
-                        ((and expr file)
-                         (leave
-                          (G_ "both file and expression cannot be specified~%")))
-                        (expr
-                         (read/eval expr))
-                        (file
-                         (load* file %user-module
-                                #:on-error (assoc-ref opts 'on-error)))
-                        (else
-                         (leave (G_ "no configuration specified~%"))))))
+         (transform   (if save-provenance?
+                          (cut operating-system-with-provenance <> file)
+                          identity))
+         (os          (transform
+                       (ensure-operating-system
+                        (or file expr)
+                        (cond
+                         ((and expr file)
+                          (leave
+                           (G_ "both file and expression cannot be specified~%")))
+                         (expr
+                          (read/eval expr))
+                         (file
+                          (load* file %user-module
+                                 #:on-error (assoc-ref opts 'on-error)))
+                         (else
+                          (leave (G_ "no configuration specified~%")))))))
 
          (dry?        (assoc-ref opts 'dry-run?))
          (bootloader? (assoc-ref opts 'install-bootloader?))
-- 
2.24.0
L
L
Ludovic Courtès wrote on 30 Nov 2019 23:31
[PATCH 3/5] machine: Add provenance tracking to each machine operating system.
(address . 38441@debbugs.gnu.org)(name . Ludovic Courtès)(address . ludo@gnu.org)
20191130223148.14336-3-ludo@gnu.org
* gnu/machine.scm (<machine>): Rename accessor to
'%machine-operating-system'.
(machine-operating-system): New procedure.
* doc/guix.texi (Service Reference): Mention it.
---
doc/guix.texi | 4 ++--
gnu/machine.scm | 7 ++++++-
2 files changed, 8 insertions(+), 3 deletions(-)

Toggle diff (39 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 3dc2fd1318..198792c54a 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -27056,8 +27056,8 @@ comparison less trivial.
 @end quotation
 
 This service is automatically added to your operating system
-configuration when you use @command{guix system reconfigure} or
-@command{guix system init}.
+configuration when you use @command{guix system reconfigure},
+@command{guix system init}, or @command{guix deploy}.
 @end defvr
 
 @node Shepherd Services
diff --git a/gnu/machine.scm b/gnu/machine.scm
index 05b03b21d4..b342fe2144 100644
--- a/gnu/machine.scm
+++ b/gnu/machine.scm
@@ -93,11 +93,16 @@
   make-machine
   machine?
   this-machine
-  (operating-system machine-operating-system) ; <operating-system>
+  (operating-system %machine-operating-system); <operating-system>
   (environment      machine-environment)      ; symbol
   (configuration    machine-configuration     ; configuration object
                     (default #f)))            ; specific to environment
 
+(define (machine-operating-system machine)
+  "Return the operating system of MACHINE."
+  (operating-system-with-provenance
+   (%machine-operating-system machine)))
+
 (define (machine-display-name machine)
   "Return the host-name identifying MACHINE."
   (operating-system-host-name (machine-operating-system machine)))
-- 
2.24.0
L
L
Ludovic Courtès wrote on 30 Nov 2019 23:31
[PATCH 4/5] guix system: "list-generations" displays provenance info.
(address . 38441@debbugs.gnu.org)(name . Ludovic Courtès)(address . ludo@gnu.org)
20191130223148.14336-4-ludo@gnu.org
* guix/scripts/pull.scm (channel-commit-hyperlink): Export.
* guix/scripts/system.scm (display-system-generation)
[display-channel]: New procedure.
Read the "provenance" file of GENERATION and display channel info and
the configuration file name when available.
---
guix/scripts/pull.scm | 1 +
guix/scripts/system.scm | 49 +++++++++++++++++++++++++++++++++++++++--
2 files changed, 48 insertions(+), 2 deletions(-)

Toggle diff (101 lines)
diff --git a/guix/scripts/pull.scm b/guix/scripts/pull.scm
index 19410ad141..04cc51829d 100644
--- a/guix/scripts/pull.scm
+++ b/guix/scripts/pull.scm
@@ -60,6 +60,7 @@
   #:use-module (ice-9 format)
   #:export (display-profile-content
             channel-list
+            channel-commit-hyperlink
             with-git-error-handling
             guix-pull))
 
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index b22945658e..0ddb40a03c 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -36,9 +36,11 @@
   #:use-module (guix records)
   #:use-module (guix profiles)
   #:use-module (guix scripts)
+  #:use-module (guix channels)
   #:use-module (guix scripts build)
   #:autoload   (guix scripts package) (delete-generations
                                        delete-matching-generations)
+  #:autoload   (guix scripts pull) (channel-commit-hyperlink)
   #:use-module (guix graph)
   #:use-module (guix scripts graph)
   #:use-module (guix scripts system reconfigure)
@@ -456,9 +458,30 @@ list of services."
 ;;; Generations.
 ;;;
 
+(define (sexp->channel sexp)
+  "Return the channel corresponding to SEXP, an sexp as found in the
+\"provenance\" file produced by 'provenance-service-type'."
+  (match sexp
+    (('channel ('name name)
+               ('url url)
+               ('branch branch)
+               ('commit commit))
+     (channel (name name) (url url)
+              (branch branch) (commit commit)))))
+
 (define* (display-system-generation number
                                     #:optional (profile %system-profile))
   "Display a summary of system generation NUMBER in a human-readable format."
+  (define (display-channel channel)
+    (format #t     "    ~a:~%" (channel-name channel))
+    (format #t (G_ "      repository URL: ~a~%") (channel-url channel))
+    (when (channel-branch channel)
+      (format #t (G_ "      branch: ~a~%") (channel-branch channel)))
+    (format #t (G_ "      commit: ~a~%")
+            (if (supports-hyperlinks?)
+                (channel-commit-hyperlink channel)
+                (channel-commit channel))))
+
   (unless (zero? number)
     (let* ((generation  (generation-file-name profile number))
            (params      (read-boot-parameters-file generation))
@@ -468,7 +491,13 @@ list of services."
            (root-device (if (bytevector? root)
                             (uuid->string root)
                             root))
-           (kernel      (boot-parameters-kernel params)))
+           (kernel      (boot-parameters-kernel params))
+           (provenance  (catch 'system-error
+                          (lambda ()
+                            (call-with-input-file
+                                (string-append generation "/provenance")
+                              read))
+                          (const #f))))
       (display-generation profile number)
       (format #t (G_ "  file name: ~a~%") generation)
       (format #t (G_ "  canonical file name: ~a~%") (readlink* generation))
@@ -495,7 +524,23 @@ list of services."
                     (else
                      root-device)))
 
-      (format #t (G_ "  kernel: ~a~%") kernel))))
+      (format #t (G_ "  kernel: ~a~%") kernel)
+
+      (match provenance
+        (#f #t)
+        (('provenance ('version 0)
+                      ('channels channels ...)
+                      ('configuration-file config-file))
+         (unless (null? channels)
+           ;; TRANSLATORS: Here "channel" is the same terminology as used in
+           ;; "guix describe" and "guix pull --channels".
+           (format #t (G_ "  channels:~%"))
+           (for-each display-channel (map sexp->channel channels)))
+         (when config-file
+           (format #t (G_ "  configuration file: ~a~%")
+                   (if (supports-hyperlinks?)
+                       (file-hyperlink config-file)
+                       config-file))))))))
 
 (define* (list-generations pattern #:optional (profile %system-profile))
   "Display in a human-readable format all the system generations matching
-- 
2.24.0
L
L
Ludovic Courtès wrote on 30 Nov 2019 23:31
[PATCH 5/5] guix system: Add "describe" action.
(address . 38441@debbugs.gnu.org)(name . Ludovic Courtès)(address . ludo@gnu.org)
20191130223148.14336-5-ludo@gnu.org
* guix/scripts/system.scm (show-help): Add "describe".
(process-command): Handle it.
(guix-system): Likewise.
* doc/guix.texi (Invoking guix system): Document it.
---
doc/guix.texi | 4 ++++
guix/scripts/system.scm | 11 ++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)

Toggle diff (53 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 198792c54a..cb4b0b45e7 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -26240,6 +26240,10 @@ bootloader boot menu:
 
 @table @code
 
+@item describe
+Describe the current system generation: its file name, the kernel and
+bootloader used, etc., as well as provenance information when available.
+
 @item list-generations
 List a summary of each generation of the operating system available on
 disk, in a human-readable way.  This is similar to the
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index 0ddb40a03c..ccff68f1ab 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -921,6 +921,8 @@ Some ACTIONS support additional ARGS.\n"))
    reconfigure      switch to a new operating system configuration\n"))
   (display (G_ "\
    roll-back        switch to the previous operating system configuration\n"))
+  (display (G_ "\
+   describe         describe the current system\n"))
   (display (G_ "\
    list-generations list the system generations\n"))
   (display (G_ "\
@@ -1187,6 +1189,12 @@ argument list and OPTS is the option alist."
                       ((pattern) pattern)
                       (x (leave (G_ "wrong number of arguments~%"))))))
        (list-generations pattern)))
+    ((describe)
+     (match (generation-number %system-profile)
+       (0
+        (error (G_ "no system generation, nothing to describe~%")))
+       (generation
+        (display-system-generation generation))))
     ((search)
      (apply (resolve-subcommand "search") args))
     ;; The following commands need to use the store, but they do not need an
@@ -1226,7 +1234,8 @@ argument list and OPTS is the option alist."
           (case action
             ((build container vm vm-image disk-image reconfigure init
               extension-graph shepherd-graph
-              list-generations delete-generations roll-back
+              list-generations describe
+              delete-generations roll-back
               switch-generation search docker-image)
              (alist-cons 'action action result))
             (else (leave (G_ "~a: unknown action~%") action))))))
-- 
2.24.0
Z
Z
zimoun wrote on 2 Dec 2019 13:12
Re: [bug#38441] [PATCH 0/5] Record operating system provenance info
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 38441@debbugs.gnu.org)
CAJ3okZ10-BS3HJ+2_C2T+fN8ybCNuaKNgvfzROi0Sdpm7=_w-Q@mail.gmail.com
Hi Ludo,

On Sat, 30 Nov 2019 at 23:31, Ludovic Courtès <ludo@gnu.org> wrote:

[...]

Toggle quote (2 lines)
> Thoughts?

Really cool!

This is a killer feature IMHO compared to the Dockerfile approach. Let
spread the world. ;-)


Cheers,
simon
L
L
Ludovic Courtès wrote on 7 Dec 2019 01:03
(address . 38441-done@debbugs.gnu.org)
877e3980il.fsf@gnu.org
Hello!

Ludovic Courtès <ludo@gnu.org> skribis:

Toggle quote (6 lines)
> services: Add 'provenance-service-type'.
> guix system: Use 'provenance-service-type', add "--save-provenance".
> machine: Add provenance tracking to each machine operating system.
> guix system: "list-generations" displays provenance info.
> guix system: Add "describe" action.

Pushed!

zimoun <zimon.toutoune@gmail.com> skribis:

Toggle quote (5 lines)
> Really cool!
>
> This is a killer feature IMHO compared to the Dockerfile approach. Let
> spread the world. ;-)

Glad you like it, thanks for your feedback! :-)

Ludo’.
Closed
?
Your comment

This issue is archived.

To comment on this conversation send email to 38441@debbugs.gnu.org