Commit afe9f409 authored by Mark H Weaver's avatar Mark H Weaver
Browse files

Merge branch 'master' into core-updates

parents bb8afbf5 1348185a
......@@ -164,11 +164,6 @@ endif BUILD_DAEMON_OFFLOAD
# Internal module with test suite support.
dist_noinst_DATA = guix/tests.scm
# Because of the autoload hack in (guix build download), we must build it
# first to avoid errors on systems where (gnutls) is unavailable.
guix/scripts/download.go: guix/build/download.go
guix/download.go: guix/build/download.go
# Linux-Libre configurations.
KCONFIGS = \
gnu/packages/linux-libre-i686.conf \
......@@ -325,6 +320,7 @@ EXTRA_DIST = \
CODE-OF-CONDUCT \
.dir-locals.el \
build-aux/build-self.scm \
build-aux/compile-all.scm \
build-aux/hydra/gnu-system.scm \
build-aux/hydra/demo-os.scm \
build-aux/hydra/guix.scm \
......@@ -364,31 +360,21 @@ CLEANFILES = \
$(GOBJECTS) \
$(SCM_TESTS:tests/%.scm=%.log)
AM_V_GUILEC = $(AM_V_GUILEC_$(V))
AM_V_GUILEC_ = $(AM_V_GUILEC_$(AM_DEFAULT_VERBOSITY))
AM_V_GUILEC_0 = @echo " GUILEC" $@;
# Flags passed to 'guild compile'.
GUILD_COMPILE_FLAGS = \
-Wformat -Wunbound-variable -Warity-mismatch
# Unset 'GUILE_LOAD_COMPILED_PATH' altogether while compiling. Otherwise, if
# $GUILE_LOAD_COMPILED_PATH contains $(moduledir), we may find .go files in
# there that are newer than the local .scm files (for instance because the
# user ran 'make install' recently). When that happens, we end up loading
# those previously-installed .go files, which may be stale, thereby breaking
# the whole thing.
#
# XXX: Use the C locale for when Guile lacks
# <http://git.sv.gnu.org/cgit/guile.git/commit/?h=stable-2.0&id=e2c6bf3866d1186c60bacfbd4fe5037087ee5e3f>.
.scm.go:
$(AM_V_GUILEC)$(MKDIR_P) `dirname "$@"` ; \
%.go: make-go ; @:
make-go: $(MODULES) guix/config.scm guix/tests.scm
$(AM_V_at)echo "Compiling Scheme modules..." ; \
unset GUILE_LOAD_COMPILED_PATH ; \
LC_ALL=C \
host=$(host) srcdir="$(top_srcdir)" \
$(top_builddir)/pre-inst-env \
$(GUILD) compile -L "$(top_builddir)" -L "$(top_srcdir)" \
$(GUILD_COMPILE_FLAGS) --target="$(host)" \
-o "$@" "$<"
$(GUILE) -L "$(top_builddir)" -L "$(top_srcdir)" \
--no-auto-compile \
-s "$(top_srcdir)"/build-aux/compile-all.scm $^
SUFFIXES = .go
......@@ -480,6 +466,6 @@ assert-final-inputs-self-contained:
$(top_builddir)/pre-inst-env "$(GUILE)" \
"$(top_srcdir)/build-aux/check-final-inputs-self-contained.scm"
.PHONY: sync-descriptions gen-ChangeLog gen-AUTHORS clean-go
.PHONY: sync-descriptions gen-ChangeLog gen-AUTHORS clean-go make-go
.PHONY: assert-no-store-file-names assert-binaries-available
.PHONY: assert-final-inputs-self-contained
......@@ -14,6 +14,7 @@ Please send Guix bug reports to bug-guix@gnu.org.
** Package management
*** Emacs interface for system generations
*** Emacs interface for hydra.gnu.org
*** Changes in Emacs interface variables
In the following names, BUFFER-TYPE means "info" or "list";
......
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
;;;
;;; 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/>.
(use-modules (system base target)
(ice-9 match)
(ice-9 threads)
(guix build utils))
(define compile-options '(format unbound-variable arity-mismatch))
(define host (getenv "host"))
(define srcdir (getenv "srcdir"))
(define (relative-file file)
(if (string-prefix? (string-append srcdir "/") file)
(string-drop file (+ 1 (string-length srcdir)))
file))
(define (file-mtime<? f1 f2)
(< (stat:mtime (stat f1))
(stat:mtime (stat f2))))
(define (scm->go file)
(let* ((relative (relative-file file))
(without-extension (string-drop-right relative 4)))
(string-append without-extension ".go")))
(define (file-needs-compilation? file)
(let ((go (scm->go file)))
(or (not (file-exists? go))
(file-mtime<? go file))))
(define (file->module file)
(let* ((relative (relative-file file))
(module-path (string-drop-right relative 4)))
(map string->symbol
(string-split module-path #\/))))
;;; To work around <http://bugs.gnu.org/15602> (FIXME), we want to load all
;;; files to be compiled first. We do this via resolve-interface so that the
;;; top-level of each file (module) is only executed once.
(define (load-module-file file)
(let ((module (file->module file)))
(format #t " LOAD ~a~%" module)
(resolve-interface module)))
(define (compile-file* file output-mutex)
(let ((go (scm->go file)))
(with-mutex output-mutex
(format #t " GUILEC ~a~%" go)
(force-output))
(mkdir-p (dirname go))
(with-target host
(lambda ()
(compile-file file
#:output-file go
#:opts compile-options)))))
(match (command-line)
((_ . files)
(let ((files (filter file-needs-compilation? files)))
(for-each load-module-file files)
(let ((mutex (make-mutex)))
(par-for-each (lambda (file)
(compile-file* file mutex))
files)))))
......@@ -155,7 +155,7 @@ Display all installed packages.
Display obsolete packages (the packages that are installed in a profile
but cannot be found among available packages).
@item M-x guix-search-by-name
@item M-x guix-packages-by-name
Display package(s) with the specified name.
@item M-x guix-search-by-regexp
......@@ -163,6 +163,11 @@ Search for packages by a specified regexp. By default ``name'',
``synopsis'' and ``description'' of the packages will be searched. This
can be changed by modifying @code{guix-package-search-params} variable.
@item M-x guix-search-by-name
Search for packages with names matching a specified regexp. This
command is the same as @code{guix-search-by-regexp}, except only a
package ``name'' is searched.
@end table
By default, these commands display each output on a separate line. If
......@@ -191,6 +196,14 @@ date/time prompt,,, org, The Org Manual}).
@end table
Analogously on GuixSD you can also display system generations:
@table @kbd
@item M-x guix-system-generations
@item M-x guix-last-system-generations
@item M-x guix-system-generations-by-time
@end table
You can also invoke the @command{guix pull} command (@pxref{Invoking
guix pull}) from Emacs using:
......
......@@ -502,6 +502,13 @@ on a recent machine; subsequent runs will be faster because the store
that is created for test purposes will already have various things in
cache.
It is also possible to run a subset of the tests by defining the
@code{TESTS} makefile variable as in this example:
@example
make check TESTS="tests/store.scm tests/cpio.scm"
@end example
Upon failure, please email @email{bug-guix@@gnu.org} and attach the
@file{test-suite.log} file. When @file{tests/@var{something}.scm}
fails, please also attach the @file{@var{something}.log} file available
......@@ -627,6 +634,11 @@ This way, the value of @code{TMPDIR} does not leak inside build
environments, which avoids discrepancies in cases where build processes
capture the name of their build tree.
@vindex http_proxy
The daemon also honors the @code{http_proxy} environment variable for
HTTP downloads it performs, be it for fixed-output derivations
(@pxref{Derivations}) or for substitutes (@pxref{Substitutes}).
If you are installing Guix as an unprivileged user, it is still possible
to run @command{guix-daemon} provided you pass @code{--disable-chroot}.
However, build processes will not be isolated from one another, and not
......@@ -1678,6 +1690,14 @@ Guix ignores substitutes that are not signed, or that are not signed by
one of the keys listed in the ACL. It also detects and raises an error
when attempting to use a substitute that has been tampered with.
@vindex http_proxy
Substitutes are downloaded over HTTP. The @code{http_proxy} environment
variable can be set in the environment of @command{guix-daemon} and is
honored for downloads of substitutes. Note that the value of
@code{http_proxy} in the environment where @command{guix build},
@command{guix package}, and other client commands are run has
@emph{absolutely no effect}.
The substitute mechanism can be disabled globally by running
@code{guix-daemon} with @code{--no-substitutes} (@pxref{Invoking
guix-daemon}). It can also be disabled temporarily by passing the
......@@ -8842,6 +8862,50 @@ The @code{base-initrd} procedure also handles common use cases that
involves using the system as a QEMU guest, or as a ``live'' system whose
root file system is volatile.
The initial RAM disk produced by @code{base-initrd} honors several
options passed on the Linux kernel command line (that is, arguments
passed @i{via} GRUB's @code{linux} command, or with QEMU's
@code{-append} option), notably:
@table @code
@item --load=@var{boot}
Tell the initial RAM disk to load @var{boot}, a file containing a Scheme
program, once it has mounted the root file system.
GuixSD uses this option to yield control to a boot program that runs the
service activation programs and then spawns GNU@tie{}dmd, the
initialization system.
@item --root=@var{root}
Mount @var{root} as the root file system. @var{root} can be a device
device name like @code{/dev/sda1}, a partition label, or a partition
UUID.
@item --system=@var{system}
Have @file{/run/booted-system} and @file{/run/current-system} point to
@var{system}.
@item modprobe.blacklist=@var{modules}@dots{}
@cindex module, black-listing
@cindex black list, of kernel modules
Instruct the initial RAM disk as well as the @command{modprobe} command
(from the kmod package) to refuse to load @var{modules}. @var{modules}
must be a comma-separated list of module names---e.g.,
@code{usbkbd,9pnet}.
@item --repl
Start a read-eval-print loop (REPL) from the initial RAM disk before it
tries to load kernel modules and to mount the root file system. Our
marketing team calls it @dfn{boot-to-Guile}. The Schemer in you will
love it. @xref{Using Guile Interactively,,, guile, GNU Guile Reference
Manual}, for more information on Guile's REPL.
@end table
Now that you know all the features that initial RAM disks produced by
@code{base-initrd} provide, here is how to use it and customize it
further.
@deffn {Monadic Procedure} base-initrd @var{file-systems} @
[#:qemu-networking? #f] [#:virtio? #f] [#:volatile-root? #f] @
[#:extra-modules '()] [#:mapped-devices '()]
......
......@@ -47,6 +47,7 @@ ELFILES = \
emacs/guix-ui.el \
emacs/guix-ui-package.el \
emacs/guix-ui-generation.el \
emacs/guix-ui-system-generation.el \
emacs/guix-utils.el
if HAVE_EMACS
......
;;; guix-base.el --- Common definitions -*- lexical-binding: t -*-
;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
;; This file is part of GNU Guix.
......@@ -91,14 +91,25 @@ For the meaning of location, see `guix-find-location'."
"Return the file name of a PROFILE's GENERATION."
(format "%s-%s-link" profile generation))
(defun guix-manifest-file (profile &optional generation)
(defun guix-packages-profile (profile &optional generation system?)
"Return a directory where packages are installed for the
PROFILE's GENERATION.
If SYSTEM? is non-nil, then PROFILE is considered to be a system
profile. Unlike usual profiles, for a system profile, packages
are placed in 'profile' subdirectory."
(let ((profile (if generation
(guix-generation-file profile generation)
profile)))
(if system?
(expand-file-name "profile" profile)
profile)))
(defun guix-manifest-file (profile &optional generation system?)
"Return the file name of a PROFILE's manifest.
If GENERATION number is specified, return manifest file name for
this generation."
See `guix-packages-profile'."
(expand-file-name "manifest"
(if generation
(guix-generation-file profile generation)
profile)))
(guix-packages-profile profile generation system?)))
;;;###autoload
(defun guix-edit (id-or-name)
......
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
;;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
......@@ -61,7 +61,8 @@
(guix scripts lint)
(guix scripts package)
(guix scripts pull)
(gnu packages))
(gnu packages)
(gnu system))
(define-syntax-rule (first-or-false lst)
(and (not (null? lst))
......@@ -137,28 +138,26 @@ (define (manifest-entry->package-specification entry)
(define (manifest-entries->package-specifications entries)
(map manifest-entry->package-specification entries))
(define (generation-package-specifications profile number)
"Return a list of package specifications for generation NUMBER."
(let ((manifest (profile-manifest
(generation-file-name profile number))))
(define (profile-package-specifications profile)
"Return a list of package specifications for PROFILE."
(let ((manifest (profile-manifest profile)))
(manifest-entries->package-specifications
(manifest-entries manifest))))
(define (generation-package-specifications+paths profile number)
"Return a list of package specifications and paths for generation NUMBER.
(define (profile->specifications+paths profile)
"Return a list of package specifications and paths for PROFILE.
Each element of the list is a list of the package specification and its path."
(let ((manifest (profile-manifest
(generation-file-name profile number))))
(let ((manifest (profile-manifest profile)))
(map (lambda (entry)
(list (manifest-entry->package-specification entry)
(manifest-entry-item entry)))
(manifest-entries manifest))))
(define (generation-difference profile number1 number2)
"Return a list of package specifications for outputs installed in generation
NUMBER1 and not installed in generation NUMBER2."
(let ((specs1 (generation-package-specifications profile number1))
(specs2 (generation-package-specifications profile number2)))
(define (profile-difference profile1 profile2)
"Return a list of package specifications for outputs installed in PROFILE1
and not installed in PROFILE2."
(let ((specs1 (profile-package-specifications profile1))
(specs2 (profile-package-specifications profile2)))
(lset-difference string=? specs1 specs2)))
(define (manifest-entries->hash-table entries)
......@@ -670,7 +669,6 @@ (define %patterns-makers
(id . ,(apply-to-rest ids->package-patterns))
(name . ,(apply-to-rest specifications->package-patterns))
(installed . ,manifest-package-proc)
(generation . ,manifest-package-proc)
(obsolete . ,(apply-to-first obsolete-package-patterns))
(regexp . ,regexp-proc)
(all-available . ,all-proc)
......@@ -679,7 +677,6 @@ (define %patterns-makers
(id . ,(apply-to-rest ids->output-patterns))
(name . ,(apply-to-rest specifications->output-patterns))
(installed . ,manifest-output-proc)
(generation . ,manifest-output-proc)
(obsolete . ,(apply-to-first obsolete-output-patterns))
(regexp . ,regexp-proc)
(all-available . ,all-proc)
......@@ -694,16 +691,13 @@ (define (package/output-sexps profile params entry-type
search-type search-vals)
"Return information about packages or package outputs.
See 'entry-sexps' for details."
(let* ((profile (if (eq? search-type 'generation)
(generation-file-name profile (car search-vals))
profile))
(manifest (profile-manifest profile))
(let* ((manifest (profile-manifest profile))
(patterns (if (and (eq? entry-type 'output)
(eq? search-type 'generation-diff))
(eq? search-type 'profile-diff))
(match search-vals
((g1 g2)
((p1 p2)
(map specification->output-pattern
(generation-difference profile g1 g2)))
(profile-difference p1 p2)))
(_ '()))
(apply (patterns-maker entry-type search-type)
manifest search-vals)))
......@@ -765,6 +759,38 @@ (define (generation-sexps profile params search-type search-vals)
params)))
(map ->sexp generations)))
(define system-generation-boot-parameters
(memoize
(lambda (profile generation)
"Return boot parameters for PROFILE's system GENERATION."
(let* ((gen-file (generation-file-name profile generation))
(param-file (string-append gen-file "/parameters")))
(call-with-input-file param-file read-boot-parameters)))))
(define (system-generation-param-alist profile)
"Return an alist of system generation parameters and procedures for
PROFILE."
(append (generation-param-alist profile)
`((label . ,(lambda (gen)
(boot-parameters-label
(system-generation-boot-parameters
profile gen))))
(root-device . ,(lambda (gen)
(boot-parameters-root-device
(system-generation-boot-parameters
profile gen))))
(kernel . ,(lambda (gen)
(boot-parameters-kernel
(system-generation-boot-parameters
profile gen)))))))
(define (system-generation-sexps profile params search-type search-vals)
"Return an alist with information about system generations."
(let ((generations (find-generations profile search-type search-vals))
(->sexp (object-transformer (system-generation-param-alist profile)
params)))
(map ->sexp generations)))
;;; Getting package/output/generation entries (alists).
......@@ -809,6 +835,9 @@ (define (entries profile params entry-type search-type search-vals)
((generation)
(generation-sexps profile params
search-type search-vals))
((system-generation)
(system-generation-sexps profile params
search-type search-vals))
(else (entry-type-error entry-type))))
......
......@@ -55,14 +55,7 @@
(obsolete
(0 "No obsolete packages in profile '%s'." profile)
(1 "A single obsolete package in profile '%s'." profile)
(many "%d obsolete packages in profile '%s'." count profile))
(generation
(0 "No packages installed in generation %d of profile '%s'."
val profile)
(1 "A single package installed in generation %d of profile '%s'."
val profile)
(many "%d packages installed in generation %d of profile '%s'."
count val profile)))
(many "%d obsolete packages in profile '%s'." count profile)))
(output
(id
......@@ -91,14 +84,7 @@
(0 "No obsolete package outputs in profile '%s'." profile)
(1 "A single obsolete package output in profile '%s'." profile)
(many "%d obsolete package outputs in profile '%s'." count profile))
(generation
(0 "No package outputs installed in generation %d of profile '%s'."
val profile)
(1 "A single package output installed in generation %d of profile '%s'."
val profile)
(many "%d package outputs installed in generation %d of profile '%s'."
count val profile))
(generation-diff
(profile-diff
guix-message-outputs-by-diff))
(generation
......@@ -183,25 +169,27 @@ Try \"M-x guix-search-by-name\"."
"matching time period '%s' - '%s'.")
str-beg profile time-beg time-end)))
(defun guix-message-outputs-by-diff (profile entries generations)
"Display a message for outputs searched by GENERATIONS difference."
(defun guix-message-outputs-by-diff (_ entries profiles)
"Display a message for outputs searched by PROFILES difference."
(let* ((count (length entries))
(str-beg (guix-message-string-entries count 'output))
(gen1 (car generations))
(gen2 (cadr generations)))
(profile1 (car profiles))
(profile2 (cadr profiles)))
(cl-multiple-value-bind (new old str-action)
(if (> gen1 gen2)
(list gen1 gen2 "added to")
(list gen2 gen1 "removed from"))
(message (concat "%s %s generation %d comparing with "
"generation %d of profile '%s'.")
str-beg str-action new old profile))))
(if (string-lessp profile2 profile1)
(list profile1 profile2 "added to")
(list profile2 profile1 "removed from"))
(message "%s %s profile '%s' comparing with profile '%s'."
str-beg str-action new old))))
(defun guix-result-message (profile entries entry-type
search-type search-vals)
"Display an appropriate message after displaying ENTRIES."
(let* ((type-spec (guix-assq-value guix-messages
entry-type search-type))
(if (eq entry-type 'system-generation)
'generation
entry-type)
search-type))
(fun-or-count-spec (car type-spec)))
(if (functionp fun-or-count-spec)
(funcall fun-or-count-spec profile entries search-vals)
......
;;; guix-profiles.el --- Guix profiles
;; Copyright © 2014 Alex Kost <alezost@gmail.com>
;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
;; Copyright © 2015 Mathieu Lirzin <mthl@openmailbox.org>
;; This file is part of GNU Guix.
......@@ -25,6 +26,10 @@
(expand-file-name "~/.guix-profile")
"User profile.")
(defvar guix-system-profile
(concat guix-config-state-directory "/profiles/system")
"System profile.")
(defvar guix-default-profile
(concat guix-config-state-directory
"/profiles/per-user/"
......
;;; guix-ui-generation.el --- Interface for displaying generations -*- lexical-binding: t -*-
;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
;; This file is part of GNU Guix.
......@@ -78,6 +78,18 @@ Each element from GENERATIONS is a generation number."
'switch-to-generation* profile generation)
operation-buffer)))
(defun guix-system-generation? ()
"Return non-nil, if current generation is a system one."
(eq (guix-buffer-current-entry-type)
'system-generation))
(defun guix-generation-current-packages-profile (&optional generation)
"Return a directory where packages are installed for the
current profile's GENERATION."
(guix-packages-profile (guix-ui-current-profile)
generation
(guix-system-generation?)))
;;; Generation 'info'
......@@ -115,8 +127,9 @@ Each element from GENERATIONS is a generation number."
(lambda (btn)
(guix-buffer-get-display-entries
'list guix-package-list-type
(list (guix-ui-current-profile)
'generation (button-get btn 'number))
(list (guix-generation-current-packages-profile
(button-get btn 'number))
'installed)
'add))
"Show installed packages for this generation"
'number number)
......@@ -190,8 +203,8 @@ VAL is a boolean value."
"List installed packages for the generation at point."
(interactive)
(guix-package-get-display
(guix-ui-current-profile)
'generation (guix-list-current-id)))
(guix-generation-current-packages-profile (guix-list-current-id))
'installed))
(defun guix-generation-list-generations-to-compare ()
"Return a sorted list of 2 marked generations for comparing."
......@@ -200,6 +213,11 @@ VAL is a boolean value."
(user-error "2 generations should be marked for comparing")
(sort numbers #'<))))
(defun guix-generation-list-profiles-to-compare ()
"Return a sorted list of 2 marked generation profiles for comparing."
(mapcar #'guix-generation-current-packages-profile
(guix-generation-list-generations-to-compare)))
(defun guix-generation-list-show-added-packages ()
"List package outputs added to the latest marked generation.
If 2 generations are marked with \\[guix-list-mark], display