mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-11-07 07:26:13 -05:00
Add 'guix time-machine'.
* guix/scripts/time-machine.scm: New file. * Makefile.am: (MODULES): Add it. * guix/scripts/pull.scm (channel-list): Export. * guix/inferior.scm (cached-channel-instance): New procedure. (inferior-for-channels): Use it. * doc/guix.texi (Invoking guix time-machine): New section. (Channels): Cross-reference it. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
parent
1edcfda81b
commit
f675f8dec7
5 changed files with 187 additions and 14 deletions
|
@ -278,6 +278,7 @@ MODULES = \
|
||||||
guix/scripts/container.scm \
|
guix/scripts/container.scm \
|
||||||
guix/scripts/container/exec.scm \
|
guix/scripts/container/exec.scm \
|
||||||
guix/scripts/deploy.scm \
|
guix/scripts/deploy.scm \
|
||||||
|
guix/scripts/time-machine.scm \
|
||||||
guix.scm \
|
guix.scm \
|
||||||
$(GNU_SYSTEM_MODULES)
|
$(GNU_SYSTEM_MODULES)
|
||||||
|
|
||||||
|
|
|
@ -198,6 +198,7 @@ Package Management
|
||||||
* Invoking guix gc:: Running the garbage collector.
|
* Invoking guix gc:: Running the garbage collector.
|
||||||
* Invoking guix pull:: Fetching the latest Guix and distribution.
|
* Invoking guix pull:: Fetching the latest Guix and distribution.
|
||||||
* Channels:: Customizing the package collection.
|
* Channels:: Customizing the package collection.
|
||||||
|
* Invoking guix time-machine:: Running an older revision of Guix.
|
||||||
* Inferiors:: Interacting with another revision of Guix.
|
* Inferiors:: Interacting with another revision of Guix.
|
||||||
* Invoking guix describe:: Display information about your Guix revision.
|
* Invoking guix describe:: Display information about your Guix revision.
|
||||||
* Invoking guix archive:: Exporting and importing store files.
|
* Invoking guix archive:: Exporting and importing store files.
|
||||||
|
@ -2550,6 +2551,7 @@ guix install emacs-guix
|
||||||
* Invoking guix gc:: Running the garbage collector.
|
* Invoking guix gc:: Running the garbage collector.
|
||||||
* Invoking guix pull:: Fetching the latest Guix and distribution.
|
* Invoking guix pull:: Fetching the latest Guix and distribution.
|
||||||
* Channels:: Customizing the package collection.
|
* Channels:: Customizing the package collection.
|
||||||
|
* Invoking guix time-machine:: Running an older revision of Guix.
|
||||||
* Inferiors:: Interacting with another revision of Guix.
|
* Inferiors:: Interacting with another revision of Guix.
|
||||||
* Invoking guix describe:: Display information about your Guix revision.
|
* Invoking guix describe:: Display information about your Guix revision.
|
||||||
* Invoking guix archive:: Exporting and importing store files.
|
* Invoking guix archive:: Exporting and importing store files.
|
||||||
|
@ -4152,7 +4154,10 @@ say, on another machine, by providing a channel specification in
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
The @command{guix describe --format=channels} command can even generate this
|
The @command{guix describe --format=channels} command can even generate this
|
||||||
list of channels directly (@pxref{Invoking guix describe}).
|
list of channels directly (@pxref{Invoking guix describe}). The resulting
|
||||||
|
file can be used with the -C options of @command{guix pull}
|
||||||
|
(@pxref{Invoking guix pull}) or @command{guix time-machine}
|
||||||
|
(@pxref{Invoking guix time-machine}).
|
||||||
|
|
||||||
At this point the two machines run the @emph{exact same Guix}, with access to
|
At this point the two machines run the @emph{exact same Guix}, with access to
|
||||||
the @emph{exact same packages}. The output of @command{guix build gimp} on
|
the @emph{exact same packages}. The output of @command{guix build gimp} on
|
||||||
|
@ -4166,6 +4171,57 @@ artifacts with very fine grain, and to reproduce software environments at
|
||||||
will---some sort of ``meta reproducibility'' capabilities, if you will.
|
will---some sort of ``meta reproducibility'' capabilities, if you will.
|
||||||
@xref{Inferiors}, for another way to take advantage of these super powers.
|
@xref{Inferiors}, for another way to take advantage of these super powers.
|
||||||
|
|
||||||
|
@node Invoking guix time-machine
|
||||||
|
@section Invoking @command{guix time-machine}
|
||||||
|
|
||||||
|
@cindex @command{guix time-machine}
|
||||||
|
@cindex pinning, channels
|
||||||
|
@cindex replicating Guix
|
||||||
|
@cindex reproducibility, of Guix
|
||||||
|
|
||||||
|
The @command{guix time-machine} command provides access to other
|
||||||
|
revisions of Guix, for example to install older versions of packages,
|
||||||
|
or to reproduce a computation in an identical environment. The revision
|
||||||
|
of Guix to be used is defined by a commit or by a channel
|
||||||
|
description file created by @command{guix describe}
|
||||||
|
(@pxref{Invoking guix describe}).
|
||||||
|
|
||||||
|
The general syntax is:
|
||||||
|
|
||||||
|
@example
|
||||||
|
guix time-machine @var{options}@dots{} -- @var{command} @var {arg}@dots{}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
where @var{command} and @var{arg}@dots{} are passed unmodified to the
|
||||||
|
@command{guix} command if the specified revision. The @var{options} that define
|
||||||
|
this revision are the same as for @command{guix pull} (@pxref{Invoking guix pull}):
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item --url=@var{url}
|
||||||
|
@itemx --commit=@var{commit}
|
||||||
|
@itemx --branch=@var{branch}
|
||||||
|
Use the @code{guix} channel from the specified @var{url}, at the
|
||||||
|
given @var{commit} (a valid Git commit ID represented as a hexadecimal
|
||||||
|
string), or @var{branch}.
|
||||||
|
|
||||||
|
@item --channels=@var{file}
|
||||||
|
@itemx -C @var{file}
|
||||||
|
Read the list of channels from @var{file}. @var{file} must contain
|
||||||
|
Scheme code that evaluates to a list of channel objects.
|
||||||
|
@xref{Channels} for more information.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
As for @command{guix pull}, the absence of any options means that the
|
||||||
|
the latest commit on the master branch will be used. The command
|
||||||
|
|
||||||
|
@example
|
||||||
|
guix time-machine -- build hello
|
||||||
|
@end example
|
||||||
|
|
||||||
|
will thus build the package @code{hello} as defined in the master branch,
|
||||||
|
which is in general a newer revison of Guix than you have installed.
|
||||||
|
Time travel works in both directions!
|
||||||
|
|
||||||
@node Inferiors
|
@node Inferiors
|
||||||
@section Inferiors
|
@section Inferiors
|
||||||
|
|
||||||
|
@ -10589,7 +10645,6 @@ ClientPID: 19419
|
||||||
ClientCommand: cuirass --cache-directory /var/cache/cuirass @dots{}
|
ClientCommand: cuirass --cache-directory /var/cache/cuirass @dots{}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
|
||||||
@node System Configuration
|
@node System Configuration
|
||||||
@chapter System Configuration
|
@chapter System Configuration
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ (define-module (guix inferior)
|
||||||
gexp->derivation-in-inferior
|
gexp->derivation-in-inferior
|
||||||
|
|
||||||
%inferior-cache-directory
|
%inferior-cache-directory
|
||||||
|
cached-channel-instance
|
||||||
inferior-for-channels))
|
inferior-for-channels))
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
@ -635,16 +636,13 @@ (define %inferior-cache-directory
|
||||||
(make-parameter (string-append (cache-directory #:ensure? #f)
|
(make-parameter (string-append (cache-directory #:ensure? #f)
|
||||||
"/inferiors")))
|
"/inferiors")))
|
||||||
|
|
||||||
(define* (inferior-for-channels channels
|
(define* (cached-channel-instance channels
|
||||||
#:key
|
#:key
|
||||||
(cache-directory (%inferior-cache-directory))
|
(cache-directory (%inferior-cache-directory))
|
||||||
(ttl (* 3600 24 30)))
|
(ttl (* 3600 24 30)))
|
||||||
"Return an inferior for CHANNELS, a list of channels. Use the cache at
|
"Return a directory containing a guix filetree defined by CHANNELS, a list of channels.
|
||||||
CACHE-DIRECTORY, where entries can be reclaimed after TTL seconds. This
|
The directory is a subdirectory of CACHE-DIRECTORY, where entries can be reclaimed after TTL seconds.
|
||||||
procedure opens a new connection to the build daemon.
|
This procedure opens a new connection to the build daemon."
|
||||||
|
|
||||||
This is a convenience procedure that people may use in manifests passed to
|
|
||||||
'guix package -m', for instance."
|
|
||||||
(with-store store
|
(with-store store
|
||||||
(let ()
|
(let ()
|
||||||
(define instances
|
(define instances
|
||||||
|
@ -680,7 +678,7 @@ (define add-indirect-root*
|
||||||
(file-expiration-time ttl))
|
(file-expiration-time ttl))
|
||||||
|
|
||||||
(if (file-exists? cached)
|
(if (file-exists? cached)
|
||||||
(open-inferior cached)
|
cached
|
||||||
(run-with-store store
|
(run-with-store store
|
||||||
(mlet %store-monad ((profile
|
(mlet %store-monad ((profile
|
||||||
(channel-instances->derivation instances)))
|
(channel-instances->derivation instances)))
|
||||||
|
@ -689,4 +687,20 @@ (define add-indirect-root*
|
||||||
(built-derivations (list profile))
|
(built-derivations (list profile))
|
||||||
(symlink* (derivation->output-path profile) cached)
|
(symlink* (derivation->output-path profile) cached)
|
||||||
(add-indirect-root* cached)
|
(add-indirect-root* cached)
|
||||||
(return (open-inferior cached)))))))))
|
(return cached))))))))
|
||||||
|
|
||||||
|
(define* (inferior-for-channels channels
|
||||||
|
#:key
|
||||||
|
(cache-directory (%inferior-cache-directory))
|
||||||
|
(ttl (* 3600 24 30)))
|
||||||
|
"Return an inferior for CHANNELS, a list of channels. Use the cache at
|
||||||
|
CACHE-DIRECTORY, where entries can be reclaimed after TTL seconds. This
|
||||||
|
procedure opens a new connection to the build daemon.
|
||||||
|
|
||||||
|
This is a convenience procedure that people may use in manifests passed to
|
||||||
|
'guix package -m', for instance."
|
||||||
|
(define cached
|
||||||
|
(cached-channel-instance channels
|
||||||
|
#:cache-directory cache-directory
|
||||||
|
#:ttl ttl))
|
||||||
|
(open-inferior cached))
|
||||||
|
|
|
@ -56,6 +56,7 @@ (define-module (guix scripts pull)
|
||||||
#:use-module (ice-9 vlist)
|
#:use-module (ice-9 vlist)
|
||||||
#:use-module (ice-9 format)
|
#:use-module (ice-9 format)
|
||||||
#:export (display-profile-content
|
#:export (display-profile-content
|
||||||
|
channel-list
|
||||||
guix-pull))
|
guix-pull))
|
||||||
|
|
||||||
|
|
||||||
|
|
102
guix/scripts/time-machine.scm
Normal file
102
guix/scripts/time-machine.scm
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
|
;;; Copyright © 2019 Konrad Hinsen <konrad.hinsen@fastmail.net>
|
||||||
|
;;;
|
||||||
|
;;; 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/>.
|
||||||
|
|
||||||
|
(define-module (guix scripts time-machine)
|
||||||
|
#:use-module (guix ui)
|
||||||
|
#:use-module (guix scripts)
|
||||||
|
#:use-module (guix inferior)
|
||||||
|
#:use-module (guix channels)
|
||||||
|
#:use-module ((guix scripts pull) #:select (channel-list))
|
||||||
|
#:use-module (ice-9 match)
|
||||||
|
#:use-module (srfi srfi-1)
|
||||||
|
#:use-module (srfi srfi-11)
|
||||||
|
#:use-module (srfi srfi-26)
|
||||||
|
#:use-module (srfi srfi-37)
|
||||||
|
#:export (guix-time-machine))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Command-line options.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define (show-help)
|
||||||
|
(display (G_ "Usage: guix time-machine [OPTION] -- COMMAND ARGS...
|
||||||
|
Execute COMMAND ARGS... in an older version of Guix.\n"))
|
||||||
|
(display (G_ "
|
||||||
|
-C, --channels=FILE deploy the channels defined in FILE"))
|
||||||
|
(display (G_ "
|
||||||
|
--url=URL use the Git repository at URL"))
|
||||||
|
(display (G_ "
|
||||||
|
--commit=COMMIT use the specified COMMIT"))
|
||||||
|
(display (G_ "
|
||||||
|
--branch=BRANCH use the tip of the specified BRANCH"))
|
||||||
|
(display (G_ "
|
||||||
|
-h, --help display this help and exit"))
|
||||||
|
(display (G_ "
|
||||||
|
-V, --version display version information and exit"))
|
||||||
|
(newline)
|
||||||
|
(show-bug-report-information))
|
||||||
|
|
||||||
|
(define %options
|
||||||
|
;; Specifications of the command-line options.
|
||||||
|
(list (option '(#\C "channels") #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'channel-file arg result)))
|
||||||
|
(option '("url") #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'repository-url arg
|
||||||
|
(alist-delete 'repository-url result))))
|
||||||
|
(option '("commit") #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'ref `(commit . ,arg) result)))
|
||||||
|
(option '("branch") #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'ref `(branch . ,arg) result)))
|
||||||
|
(option '(#\h "help") #f #f
|
||||||
|
(lambda args
|
||||||
|
(show-help)
|
||||||
|
(exit 0)))
|
||||||
|
(option '(#\V "version") #f #f
|
||||||
|
(lambda args
|
||||||
|
(show-version-and-exit "guix time-machine")))))
|
||||||
|
|
||||||
|
(define (parse-args args)
|
||||||
|
"Parse the list of command line arguments ARGS."
|
||||||
|
;; The '--' token is used to separate the command to run from the rest of
|
||||||
|
;; the operands.
|
||||||
|
(let-values (((args command) (break (cut string=? "--" <>) args)))
|
||||||
|
(let ((opts (parse-command-line args %options '(()) #:build-options? #f)))
|
||||||
|
(match command
|
||||||
|
(() opts)
|
||||||
|
(("--") opts)
|
||||||
|
(("--" command ...) (alist-cons 'exec command opts))))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Entry point.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define (guix-time-machine . args)
|
||||||
|
(with-error-handling
|
||||||
|
(let* ((opts (parse-args args))
|
||||||
|
(channels (channel-list opts))
|
||||||
|
(command-line (assoc-ref opts 'exec)))
|
||||||
|
(when command-line
|
||||||
|
(let* ((directory (cached-channel-instance channels))
|
||||||
|
(executable (string-append directory "/bin/guix")))
|
||||||
|
(apply execl (cons* executable executable command-line)))))))
|
Loading…
Reference in a new issue