summaryrefslogtreecommitdiff
path: root/guix/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'guix/scripts')
-rw-r--r--guix/scripts/build.scm84
-rw-r--r--guix/scripts/offload.scm54
-rwxr-xr-xguix/scripts/substitute.scm2
-rw-r--r--guix/scripts/system/reconfigure.scm34
-rw-r--r--guix/scripts/upgrade.scm2
5 files changed, 139 insertions, 37 deletions
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index 72a5d46347..e59e0ee67f 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -26,6 +26,7 @@
#:use-module (guix store)
#:use-module (guix derivations)
#:use-module (guix packages)
+ #:use-module (guix memoization)
#:use-module (guix grafts)
#:use-module (guix utils)
@@ -396,6 +397,83 @@ a checkout of the Git repository at the given URL."
(rewrite obj)
obj)))
+(define (package-dependents/spec top bottom)
+ "Return the list of dependents of BOTTOM, a spec string, that are also
+dependencies of TOP, a package."
+ (define-values (name version)
+ (package-name->name+version bottom))
+
+ (define dependent?
+ (mlambda (p)
+ (and (package? p)
+ (or (and (string=? name (package-name p))
+ (or (not version)
+ (version-prefix? version (package-version p))))
+ (match (bag-direct-inputs (package->bag p))
+ (((labels dependencies . _) ...)
+ (any dependent? dependencies)))))))
+
+ (filter dependent? (package-closure (list top))))
+
+(define (package-toolchain-rewriting p bottom toolchain)
+ "Return a procedure that, when passed a package that's either BOTTOM or one
+of its dependents up to P so, changes it so it is built with TOOLCHAIN.
+TOOLCHAIN must be an input list."
+ (define rewriting-property
+ (gensym " package-toolchain-rewriting"))
+
+ (match (package-dependents/spec p bottom)
+ (() ;P does not depend on BOTTOM
+ identity)
+ (set
+ ;; SET is the list of packages "between" P and BOTTOM (included) whose
+ ;; toolchain needs to be changed.
+ (package-mapping (lambda (p)
+ (if (or (assq rewriting-property
+ (package-properties p))
+ (not (memq p set)))
+ p
+ (let ((p (package-with-c-toolchain p toolchain)))
+ (package/inherit p
+ (properties `((,rewriting-property . #t)
+ ,@(package-properties p)))))))
+ (lambda (p)
+ (or (assq rewriting-property (package-properties p))
+ (not (memq p set))))
+ #:deep? #t))))
+
+(define (transform-package-toolchain replacement-specs)
+ "Return a procedure that, when passed a package, changes its toolchain or
+that of its dependencies according to REPLACEMENT-SPECS. REPLACEMENT-SPECS is
+a list of strings like \"fftw=gcc-toolchain@10\" meaning that the package to
+the left of the equal sign must be built with the toolchain to the right of
+the equal sign."
+ (define split-on-commas
+ (cute string-tokenize <> (char-set-complement (char-set #\,))))
+
+ (define (specification->input spec)
+ (let ((package (specification->package spec)))
+ (list (package-name package) package)))
+
+ (define replacements
+ (map (lambda (spec)
+ (match (string-tokenize spec %not-equal)
+ ((spec (= split-on-commas toolchain))
+ (cons spec (map specification->input toolchain)))
+ (_
+ (leave (G_ "~a: invalid toolchain replacement specification~%")
+ spec))))
+ replacement-specs))
+
+ (lambda (store obj)
+ (if (package? obj)
+ (or (any (match-lambda
+ ((bottom . toolchain)
+ ((package-toolchain-rewriting obj bottom toolchain) obj)))
+ replacements)
+ obj)
+ obj)))
+
(define (transform-package-tests specs)
"Return a procedure that, when passed a package, sets #:tests? #f in its
'arguments' field."
@@ -426,6 +504,7 @@ a checkout of the Git repository at the given URL."
(with-branch . ,transform-package-source-branch)
(with-commit . ,transform-package-source-commit)
(with-git-url . ,transform-package-source-git-url)
+ (with-c-toolchain . ,transform-package-toolchain)
(without-tests . ,transform-package-tests)))
(define (transformation-procedure key)
@@ -455,6 +534,8 @@ a checkout of the Git repository at the given URL."
(parser 'with-commit))
(option '("with-git-url") #t #f
(parser 'with-git-url))
+ (option '("with-c-toolchain") #t #f
+ (parser 'with-c-toolchain))
(option '("without-tests") #t #f
(parser 'without-tests)))))
@@ -478,6 +559,9 @@ a checkout of the Git repository at the given URL."
--with-git-url=PACKAGE=URL
build PACKAGE from the repository at URL"))
(display (G_ "
+ --with-c-toolchain=PACKAGE=TOOLCHAIN
+ build PACKAGE and its dependents with TOOLCHAIN"))
+ (display (G_ "
--without-tests=PACKAGE
build PACKAGE without running its tests")))
diff --git a/guix/scripts/offload.scm b/guix/scripts/offload.scm
index 3dc8ccefcb..a5fe98b675 100644
--- a/guix/scripts/offload.scm
+++ b/guix/scripts/offload.scm
@@ -88,6 +88,10 @@
(default 3))
(daemon-socket build-machine-daemon-socket ; string
(default "/var/guix/daemon-socket/socket"))
+ ;; A #f value tells the offload scheduler to disregard the load of the build
+ ;; machine when selecting the best offload machine.
+ (overload-threshold build-machine-overload-threshold ; inexact real between
+ (default 0.6)) ; 0.0 and 1.0 | #f
(parallel-builds build-machine-parallel-builds ; number
(default 1))
(speed build-machine-speed ; inexact real
@@ -391,30 +395,34 @@ of free disk space on '~a'~%")
(* 100 (expt 2 20))) ;100 MiB
(define (node-load node)
- "Return the load on NODE. Return +∞ if NODE is misbehaving."
+ "Return the load on NODE, a normalized value between 0.0 and 1.0. The value
+is derived from /proc/loadavg and normalized according to the number of
+logical cores available, to give a rough estimation of CPU usage. Return
+1.0 (fully loaded) if NODE is misbehaving."
(let ((line (inferior-eval '(begin
(use-modules (ice-9 rdelim))
(call-with-input-file "/proc/loadavg"
read-string))
- node)))
- (if (eof-object? line)
- +inf.0 ;MACHINE does not respond, so assume it is infinitely loaded
+ node))
+ (ncores (inferior-eval '(begin
+ (use-modules (ice-9 threads))
+ (current-processor-count))
+ node)))
+ (if (or (eof-object? line) (eof-object? ncores))
+ 1.0 ;MACHINE does not respond, so assume it is fully loaded
(match (string-tokenize line)
((one five fifteen . x)
- (string->number one))
+ (let ((load (/ (string->number one) ncores)))
+ (if (> load 1.0)
+ 1.0
+ load)))
(x
- +inf.0)))))
-
-(define (normalized-load machine load)
- "Divide LOAD by the number of parallel builds of MACHINE."
- (if (rational? load)
- (let* ((jobs (build-machine-parallel-builds machine))
- (normalized (/ load jobs)))
- (format (current-error-port) "load on machine '~a' is ~s\
- (normalized: ~s)~%"
- (build-machine-name machine) load normalized)
- normalized)
- load))
+ 1.0)))))
+
+(define (report-load machine load)
+ (format (current-error-port)
+ "normalized load on machine '~a' is ~,2f~%"
+ (build-machine-name machine) load))
(define (random-seed)
(logxor (getpid) (car (gettimeofday))))
@@ -472,11 +480,15 @@ slot (which must later be released with 'release-build-slot'), or #f and #f."
(let* ((session (false-if-exception (open-ssh-session best
%short-timeout)))
(node (and session (remote-inferior session)))
- (load (and node (normalized-load best (node-load node))))
+ (load (and node (node-load node)))
+ (threshold (build-machine-overload-threshold best))
(space (and node (node-free-disk-space node))))
+ (when load (report-load best load))
(when node (close-inferior node))
(when session (disconnect! session))
- (if (and node (< load 2.) (>= space %minimum-disk-space))
+ (if (and node
+ (or (not threshold) (< load threshold))
+ (>= space %minimum-disk-space))
(match others
(((machines slots) ...)
;; Release slots from the uninteresting machines.
@@ -708,13 +720,13 @@ machine."
(free (node-free-disk-space inferior)))
(close-inferior inferior)
(format #t "~a~% kernel: ~a ~a~% architecture: ~a~%\
- host name: ~a~% normalized load: ~a~% free disk space: ~,2f MiB~%\
+ host name: ~a~% normalized load: ~,2f~% free disk space: ~,2f MiB~%\
time difference: ~a s~%"
(build-machine-name machine)
(utsname:sysname uts) (utsname:release uts)
(utsname:machine uts)
(utsname:nodename uts)
- (normalized-load machine load)
+ load
(/ free (expt 2 20) 1.)
(- time now))))))))
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index 26613df68f..7ec170b08a 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -137,7 +137,7 @@ disabled!~%"))
(define %narinfo-negative-ttl
;; Likewise, but for negative lookups---i.e., cached lookup failures (404).
- (* 3 3600))
+ (* 1 3600))
(define %narinfo-transient-error-ttl
;; Likewise, but for transient errors such as 504 ("Gateway timeout").
diff --git a/guix/scripts/system/reconfigure.scm b/guix/scripts/system/reconfigure.scm
index 45bb1d5d3b..d89caf80fc 100644
--- a/guix/scripts/system/reconfigure.scm
+++ b/guix/scripts/system/reconfigure.scm
@@ -126,22 +126,25 @@ return the <live-service> objects that are currently running on MACHINE."
(define exp
(with-imported-modules '((gnu services herd))
#~(begin
- (use-modules (gnu services herd))
+ (use-modules (gnu services herd)
+ (ice-9 match))
+
(let ((services (current-services)))
(and services
- ;; 'live-service-running' is ignored, as we can't necessarily
- ;; serialize arbitrary objects. This should be fine for now,
- ;; since 'machine-current-services' is not exposed publicly,
- ;; and the resultant <live-service> objects are only used for
- ;; resolving service dependencies.
(map (lambda (service)
(list (live-service-provision service)
- (live-service-requirement service)))
+ (live-service-requirement service)
+ (match (live-service-running service)
+ (#f #f)
+ (#t #t)
+ ((? number? pid) pid)
+ (_ #t)))) ;not serializable
services))))))
+
(mlet %store-monad ((services (eval exp)))
(return (map (match-lambda
- ((provision requirement)
- (live-service provision requirement #f)))
+ ((provision requirement running)
+ (live-service provision requirement running)))
services))))
;; XXX: Currently, this does NOT attempt to restart running services. See
@@ -181,13 +184,14 @@ services as defined by OS."
(mlet* %store-monad ((live-services (running-services eval)))
(let*-values (((to-unload to-restart)
(shepherd-service-upgrade live-services target-services)))
- (let* ((to-unload (map live-service-canonical-name to-unload))
+ (let* ((to-unload (map live-service-canonical-name to-unload))
(to-restart (map shepherd-service-canonical-name to-restart))
- (to-start (lset-difference eqv?
- (map shepherd-service-canonical-name
- target-services)
- (map live-service-canonical-name
- live-services)))
+ (running (map live-service-canonical-name
+ (filter live-service-running live-services)))
+ (to-start (lset-difference eqv?
+ (map shepherd-service-canonical-name
+ target-services)
+ running))
(service-files (map shepherd-service-file target-services)))
(eval #~(parameterize ((current-warning-port (%make-void-port "w")))
(primitive-load #$(upgrade-services-program service-files
diff --git a/guix/scripts/upgrade.scm b/guix/scripts/upgrade.scm
index 8c7abd133a..5ec844328e 100644
--- a/guix/scripts/upgrade.scm
+++ b/guix/scripts/upgrade.scm
@@ -36,6 +36,8 @@ This is an alias for 'guix package -u'.\n"))
-p, --profile=PROFILE use PROFILE instead of the user's default profile"))
(display (G_ "
-v, --verbosity=LEVEL use the given verbosity LEVEL"))
+ (display (G_ "
+ --do-not-upgrade[=REGEXP] do not upgrade any packages matching REGEXP"))
(newline)
(show-build-options-help)
(newline)