mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-24 21:38:07 -05:00
guix: package: lock profiles when processing them.
* guix/scripts/package.scm (process-actions): Get a per-profile lock to prevent concurrent actions on profiles. * tests/guix-package.sh: Add test.
This commit is contained in:
parent
f49e913188
commit
b1fb663404
2 changed files with 46 additions and 28 deletions
|
@ -42,6 +42,8 @@ (define-module (guix scripts package)
|
||||||
#:autoload (guix store roots) (gc-roots)
|
#:autoload (guix store roots) (gc-roots)
|
||||||
#:use-module ((guix build utils)
|
#:use-module ((guix build utils)
|
||||||
#:select (directory-exists? mkdir-p))
|
#:select (directory-exists? mkdir-p))
|
||||||
|
#:use-module ((guix build syscalls)
|
||||||
|
#:select (with-file-lock/no-wait))
|
||||||
#:use-module (ice-9 format)
|
#:use-module (ice-9 format)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (ice-9 regex)
|
#:use-module (ice-9 regex)
|
||||||
|
@ -876,36 +878,44 @@ (define (transform-entry entry)
|
||||||
(package-version item)
|
(package-version item)
|
||||||
(manifest-entry-version entry))))))
|
(manifest-entry-version entry))))))
|
||||||
|
|
||||||
;; First, process roll-backs, generation removals, etc.
|
|
||||||
(for-each (match-lambda
|
|
||||||
((key . arg)
|
|
||||||
(and=> (assoc-ref %actions key)
|
|
||||||
(lambda (proc)
|
|
||||||
(proc store profile arg opts
|
|
||||||
#:dry-run? dry-run?)))))
|
|
||||||
opts)
|
|
||||||
|
|
||||||
;; Then, process normal package removal/installation/upgrade.
|
;; First, acquire a lock on the profile, to ensure only one guix process
|
||||||
(let* ((manifest (profile-manifest profile))
|
;; is modifying it at a time.
|
||||||
(step1 (options->removable opts manifest
|
(with-file-lock/no-wait (string-append profile ".lock")
|
||||||
(manifest-transaction)))
|
(lambda (key . args)
|
||||||
(step2 (options->installable opts manifest step1))
|
(leave (G_ "profile ~a is locked by another process~%")
|
||||||
(step3 (manifest-transaction
|
profile))
|
||||||
(inherit step2)
|
|
||||||
(install (map transform-entry
|
|
||||||
(manifest-transaction-install step2)))))
|
|
||||||
(new (manifest-perform-transaction manifest step3)))
|
|
||||||
|
|
||||||
(warn-about-old-distro)
|
;; Then, process roll-backs, generation removals, etc.
|
||||||
|
(for-each (match-lambda
|
||||||
|
((key . arg)
|
||||||
|
(and=> (assoc-ref %actions key)
|
||||||
|
(lambda (proc)
|
||||||
|
(proc store profile arg opts
|
||||||
|
#:dry-run? dry-run?)))))
|
||||||
|
opts)
|
||||||
|
|
||||||
(unless (manifest-transaction-null? step3)
|
;; Then, process normal package removal/installation/upgrade.
|
||||||
(show-manifest-transaction store manifest step3
|
(let* ((manifest (profile-manifest profile))
|
||||||
#:dry-run? dry-run?)
|
(step1 (options->removable opts manifest
|
||||||
(build-and-use-profile store profile new
|
(manifest-transaction)))
|
||||||
#:allow-collisions? allow-collisions?
|
(step2 (options->installable opts manifest step1))
|
||||||
#:bootstrap? bootstrap?
|
(step3 (manifest-transaction
|
||||||
#:use-substitutes? substitutes?
|
(inherit step2)
|
||||||
#:dry-run? dry-run?))))
|
(install (map transform-entry
|
||||||
|
(manifest-transaction-install step2)))))
|
||||||
|
(new (manifest-perform-transaction manifest step3)))
|
||||||
|
|
||||||
|
(warn-about-old-distro)
|
||||||
|
|
||||||
|
(unless (manifest-transaction-null? step3)
|
||||||
|
(show-manifest-transaction store manifest step3
|
||||||
|
#:dry-run? dry-run?)
|
||||||
|
(build-and-use-profile store profile new
|
||||||
|
#:allow-collisions? allow-collisions?
|
||||||
|
#:bootstrap? bootstrap?
|
||||||
|
#:use-substitutes? substitutes?
|
||||||
|
#:dry-run? dry-run?)))))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
|
|
@ -33,7 +33,7 @@ profile="t-profile-$$"
|
||||||
tmpfile="t-guix-package-file-$$"
|
tmpfile="t-guix-package-file-$$"
|
||||||
rm -f "$profile" "$tmpfile"
|
rm -f "$profile" "$tmpfile"
|
||||||
|
|
||||||
trap 'rm -f "$profile" "$profile-"[0-9]* "$tmpfile"; rm -rf "$module_dir" t-home-'"$$" EXIT
|
trap 'rm -f "$profile" "$profile.lock" "$profile-"[0-9]* "$tmpfile"; rm -rf "$module_dir" t-home-'"$$" EXIT
|
||||||
|
|
||||||
# Use `-e' with a non-package expression.
|
# Use `-e' with a non-package expression.
|
||||||
if guix package --bootstrap -e +;
|
if guix package --bootstrap -e +;
|
||||||
|
@ -452,3 +452,11 @@ rm -rf "$module_dir"
|
||||||
# Make sure we can see user profiles.
|
# Make sure we can see user profiles.
|
||||||
guix package --list-profiles | grep "$profile"
|
guix package --list-profiles | grep "$profile"
|
||||||
guix package --list-profiles | grep '\.guix-profile'
|
guix package --list-profiles | grep '\.guix-profile'
|
||||||
|
|
||||||
|
# Make sure we can properly lock a profile.
|
||||||
|
mkdir "$module_dir"
|
||||||
|
echo '(sleep 60)' > "$module_dir/manifest.scm"
|
||||||
|
guix package -m "$module_dir/manifest.scm" -p "$module_dir/profile" &
|
||||||
|
pid=$!
|
||||||
|
if guix install emacs -p "$module_dir/profile"; then kill $pid; false; else true; fi
|
||||||
|
kill $pid
|
||||||
|
|
Loading…
Reference in a new issue