scripts: pull: Add options for generation management

* guix/scripts/pull.scm (%options) Add --roll-back, --switch-generation,
--delete-generations
(process-generation-change): New function
(guix-pull): Execute generation management operations

* doc/guix.texi: Document the generation management operations

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Konrad Hinsen 2019-09-18 09:52:18 +02:00 committed by Ludovic Courtès
parent ee25048e51
commit da55110712
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
2 changed files with 85 additions and 3 deletions

View File

@ -3673,11 +3673,20 @@ Generation 3 Jun 13 2018 23:31:07 (current)
@xref{Invoking guix describe, @command{guix describe}}, for other ways to @xref{Invoking guix describe, @command{guix describe}}, for other ways to
describe the current status of Guix. describe the current status of Guix.
This @code{~/.config/guix/current} profile works like any other profile This @code{~/.config/guix/current} profile works exactly like the profiles
created by @command{guix package} (@pxref{Invoking guix package}). That created by @command{guix package} (@pxref{Invoking guix package}). That
is, you can list generations, roll back to the previous is, you can list generations, roll back to the previous
generation---i.e., the previous Guix---and so on: generation---i.e., the previous Guix---and so on:
@example
$ guix pull --roll-back
switched from generation 3 to 2
$ guix pull --delete-generations=1
deleting /var/guix/profiles/per-user/charlie/current-guix-1-link
@end example
You can also use @command{guix package} (@pxref{Invoking guix package})
to manage the profile by naming it explicitly:
@example @example
$ guix package -p ~/.config/guix/current --roll-back $ guix package -p ~/.config/guix/current --roll-back
switched from generation 3 to 2 switched from generation 3 to 2
@ -3724,6 +3733,40 @@ is provided, the subset of generations that match @var{pattern}.
The syntax of @var{pattern} is the same as with @code{guix package The syntax of @var{pattern} is the same as with @code{guix package
--list-generations} (@pxref{Invoking guix package}). --list-generations} (@pxref{Invoking guix package}).
@item --roll-back
@cindex rolling back
@cindex undoing transactions
@cindex transactions, undoing
Roll back to the previous @dfn{generation} of @file{~/.config/guix/current}---i.e.,
undo the last transaction.
@item --switch-generation=@var{pattern}
@itemx -S @var{pattern}
@cindex generations
Switch to a particular generation defined by @var{pattern}.
@var{pattern} may be either a generation number or a number prefixed
with ``+'' or ``-''. The latter means: move forward/backward by a
specified number of generations. For example, if you want to return to
the latest generation after @code{--roll-back}, use
@code{--switch-generation=+1}.
@item --delete-generations[=@var{pattern}]
@itemx -d [@var{pattern}]
When @var{pattern} is omitted, delete all generations except the current
one.
This command accepts the same patterns as @option{--list-generations}.
When @var{pattern} is specified, delete the matching generations. When
@var{pattern} specifies a duration, generations @emph{older} than the
specified duration match. For instance, @code{--delete-generations=1m}
deletes generations that are more than one month old.
If the current generation matches, it is @emph{not} deleted.
Note that deleting generations prevents rolling back to them.
Consequently, this command must be used with care.
@xref{Invoking guix describe}, for a way to display information about the @xref{Invoking guix describe}, for a way to display information about the
current generation only. current generation only.

View File

@ -38,7 +38,8 @@
#:use-module (guix git) #:use-module (guix git)
#:use-module (git) #:use-module (git)
#:use-module (gnu packages) #:use-module (gnu packages)
#:use-module ((guix scripts package) #:select (build-and-use-profile)) #:use-module ((guix scripts package) #:select (build-and-use-profile
delete-matching-generations))
#:use-module ((gnu packages base) #:select (canonical-package)) #:use-module ((gnu packages base) #:select (canonical-package))
#:use-module (gnu packages guile) #:use-module (gnu packages guile)
#:use-module ((gnu packages bootstrap) #:use-module ((gnu packages bootstrap)
@ -91,6 +92,14 @@ Download and deploy the latest version of Guix.\n"))
(display (G_ " (display (G_ "
-l, --list-generations[=PATTERN] -l, --list-generations[=PATTERN]
list generations matching PATTERN")) list generations matching PATTERN"))
(display (G_ "
--roll-back roll back to the previous generation"))
(display (G_ "
-d, --delete-generations[=PATTERN]
delete generations matching PATTERN"))
(display (G_ "
-S, --switch-generation=PATTERN
switch to a generation matching PATTERN"))
(display (G_ " (display (G_ "
-p, --profile=PROFILE use PROFILE instead of ~/.config/guix/current")) -p, --profile=PROFILE use PROFILE instead of ~/.config/guix/current"))
(display (G_ " (display (G_ "
@ -120,6 +129,18 @@ Download and deploy the latest version of Guix.\n"))
(lambda (opt name arg result) (lambda (opt name arg result)
(cons `(query list-generations ,arg) (cons `(query list-generations ,arg)
result))) result)))
(option '("roll-back") #f #f
(lambda (opt name arg result)
(cons '(generation roll-back)
result)))
(option '(#\S "switch-generation") #t #f
(lambda (opt name arg result)
(cons `(generation switch ,arg)
result)))
(option '(#\d "delete-generations") #f #t
(lambda (opt name arg result)
(cons `(generation delete ,arg)
result)))
(option '(#\N "news") #f #f (option '(#\N "news") #f #f
(lambda (opt name arg result) (lambda (opt name arg result)
(cons '(query display-news) result))) (cons '(query display-news) result)))
@ -505,6 +526,22 @@ list of package changes.")))))
(display-profile-news profile (display-profile-news profile
#:current-is-newer? #t)))) #:current-is-newer? #t))))
(define (process-generation-change opts profile)
"Process a request to change the current generation (roll-back, switch, delete)."
(unless (assoc-ref opts 'dry-run?)
(match (assoc-ref opts 'generation)
(('roll-back)
(with-store store
(roll-back* store profile)))
(('switch pattern)
(let ((number (relative-generation-spec->number profile pattern)))
(if number
(switch-to-generation* profile number)
(leave (G_ "cannot switch to generation '~a'~%") pattern))))
(('delete pattern)
(with-store store
(delete-matching-generations store profile pattern))))))
(define (channel-list opts) (define (channel-list opts)
"Return the list of channels to use. If OPTS specify a channel file, "Return the list of channels to use. If OPTS specify a channel file,
channels are read from there; otherwise, if ~/.config/guix/channels.scm channels are read from there; otherwise, if ~/.config/guix/channels.scm
@ -572,6 +609,8 @@ Use '~/.config/guix/channels.scm' instead."))
(profile (or (assoc-ref opts 'profile) %current-profile))) (profile (or (assoc-ref opts 'profile) %current-profile)))
(cond ((assoc-ref opts 'query) (cond ((assoc-ref opts 'query)
(process-query opts profile)) (process-query opts profile))
((assoc-ref opts 'generation)
(process-generation-change opts profile))
(else (else
(with-store store (with-store store
(ensure-default-profile) (ensure-default-profile)