[PATCH 0/5] Record operating system provenance info

DoneSubmitted by Ludovic Courtès.
L
Ludovic Courtès wrote on Sat Nov 30 23:30:13+0100 2019
(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
Ludovic Courtès wrote on Sat Nov 30 23:31:44+0100 2019
[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(+)

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
Ludovic Courtès wrote on Sat Nov 30 23:31:45+0100 2019
[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(-)

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
Ludovic Courtès wrote on Sat Nov 30 23:31:46+0100 2019
[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(-)

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
Ludovic Courtès wrote on Sat Nov 30 23:31:47+0100 2019
[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(-)

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
Ludovic Courtès wrote on Sat Nov 30 23:31:48+0100 2019
[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(-)

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
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:

[...]

> Thoughts?

Really cool!

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


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

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

> 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:

> 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

Comments via the web interface are not currently supported. To comment on this conversation send email to 38441@debbugs.gnu.org

2 participants
  • Ludovic Courtès
  • zimoun
Owner
unassigned
Severity
normal
Status
Done