From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id L6zzMcVMbl94DwAA0tVLHw (envelope-from ) for ; Fri, 25 Sep 2020 20:02:13 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0 with LMTPS id MJljLcVMbl8AWQAA1q6Kng (envelope-from ) for ; Fri, 25 Sep 2020 20:02:13 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 18D5F9403D2 for ; Fri, 25 Sep 2020 20:02:13 +0000 (UTC) Received: from localhost ([::1]:51800 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kLtv1-0002s5-Tk for larch@yhetil.org; Fri, 25 Sep 2020 16:02:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40522) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kLtut-0002rz-0e for guix-patches@gnu.org; Fri, 25 Sep 2020 16:02:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:33858) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kLtus-00011h-NE for guix-patches@gnu.org; Fri, 25 Sep 2020 16:02:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kLtus-0008Oe-LA for guix-patches@gnu.org; Fri, 25 Sep 2020 16:02:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#43482] [PATCH v2 2/2] doc: Promote "Channels" as chapter and reorder. Resent-From: zimoun Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 25 Sep 2020 20:02:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 43482 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 43482@debbugs.gnu.org Cc: ludo@gnu.org, zimoun Received: via spool by 43482-submit@debbugs.gnu.org id=B43482.160106408732222 (code B ref 43482); Fri, 25 Sep 2020 20:02:02 +0000 Received: (at 43482) by debbugs.gnu.org; 25 Sep 2020 20:01:27 +0000 Received: from localhost ([127.0.0.1]:45403 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kLtuG-0008Nb-CD for submit@debbugs.gnu.org; Fri, 25 Sep 2020 16:01:27 -0400 Received: from mail-wm1-f48.google.com ([209.85.128.48]:40599) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kLtuB-0008N9-Iz for 43482@debbugs.gnu.org; Fri, 25 Sep 2020 16:01:23 -0400 Received: by mail-wm1-f48.google.com with SMTP id k18so277886wmj.5 for <43482@debbugs.gnu.org>; Fri, 25 Sep 2020 13:01:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RrjMBZlD5jPiBnSf5m7+qtjdzL7crKMXiAbfq1U32Sk=; b=uV45qR07lzPQNizwGDVsDbR4Lz17+tly5Y2hkiYrwL6BYx8DJJYmOXIZjAdskS1jAj yp7J3K/s55WxtY1V1azUWmaMdtTVkIJTKt3+KdugoKF00U1yZTjVZEJuikNm7sGA415O ey1xBMvtRxGCdMHUfHKOWM767UJ7KHf8/oFAGZ/alluM5OLcQBANDFjsTFoVk3yr8iGT Z5WFE9KTeTHe+X4a/sXpk4bU6RHpizXzK0sdr7DXJUHh0hYq95qPuMKnDahPGsRLfIw9 zYx1n87PLFpxFsVDqwZrNOL2kYfWk8VkRjJ2UKDjuxb0NbMDgWuIarKnHq3KLKuQikv5 uXRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RrjMBZlD5jPiBnSf5m7+qtjdzL7crKMXiAbfq1U32Sk=; b=FpajVEgcY8r8+T8fmEvt8HJVQ6tFrjwXdwWcp/ijYvoCpbnxL6choHt6mHZEXuP/23 PyfQlihaJeTHHrHuUtyhXAt0x6LAsooJ/csOqHPZD+ywLeqKdoP1SgbMNlyTbOidNQ2V 9+00OQTVJkNiVjUEHH9iJg2JWjWKhXP7N+xeqfj3H9+SH/fFi6BQMAAdrjq26YmxB2d1 xAmI1aKm5CyHrwiUsQM0OOOSaj3cx6ZjK5F/vJAlizyN3nnlWUM20uELtBvoWX5p6wCV LPioxntXQ5UPMDTKojupaSB9fiJbT8aoMTXYVxIkMOzg8ebt9dQsmak+VwS12gNo5VpJ nsvQ== X-Gm-Message-State: AOAM533wwbLgxds84d3v9D0LDPQnjYDU63WG0OsenKdIvKJbxXrP0zB+ OKKBImrfoa0LnpVft/TaLyNHHr6lups95g== X-Google-Smtp-Source: ABdhPJx0xEXvE/fT42MrObB0riHA0rKh3CmObZdz5SSK4lfwr36OXAyruYVJqzb7Sz+qUd5N/EgA2A== X-Received: by 2002:a1c:e1d6:: with SMTP id y205mr239619wmg.92.1601064069542; Fri, 25 Sep 2020 13:01:09 -0700 (PDT) Received: from pfiuh02.univ-paris-diderot.fr ([193.48.40.241]) by smtp.gmail.com with ESMTPSA id 76sm99652wma.42.2020.09.25.13.01.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2020 13:01:08 -0700 (PDT) From: zimoun Date: Fri, 25 Sep 2020 22:00:55 +0200 Message-Id: <20200925200055.8908-2-zimon.toutoune@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925200055.8908-1-zimon.toutoune@gmail.com> References: <20200925200055.8908-1-zimon.toutoune@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Spam-Score: -1.0 (-) X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=fail (rsa verify failed) header.d=gmail.com header.s=20161025 header.b=uV45qR07; dmarc=fail reason="SPF not aligned (relaxed)" header.from=gmail.com (policy=none); spf=pass (aspmx1.migadu.com: domain of guix-patches-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=guix-patches-bounces@gnu.org X-Spam-Score: 0.09 X-TUID: qsTarytwQdgL The sectioning becomes: 1. Specifying Additional Channels (was 3.) 2. Using a Custom Guix Channel (was 2.) 3. Replicating Guix (was 9.) 4. Channel Authentication (was 1.) 5. Primary URL (was 7.) 6. Creating a Channel (reworded) 7. Package Modules in a Sub-directory (was 5.) 8. Declaring Channel Dependencies (was 4.) 9. Specifying Channel Authorizations (was 6.) 10. Writing Channel News (was 8.) * doc/guix.texi (Channels): Move section to chapter. Reorder the chapter. Minor tweaks to keep uniformity. Update the master menu. --- doc/guix.texi | 1587 +++++++++++++++++++++++++------------------------ 1 file changed, 817 insertions(+), 770 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index bc72373d80..ef10785316 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -147,6 +147,7 @@ Project}. * System Installation:: Installing the whole operating system. * Getting Started:: Your first steps. * Package Management:: Package installation, upgrade, etc. +* Channels:: Customizing the package collection. * Development:: Guix-aided software development. * Programming Interface:: Using Guix in Scheme. * Utilities:: Package management commands. @@ -212,7 +213,6 @@ Package Management * Packages with Multiple Outputs:: Single source package, multiple outputs. * Invoking guix gc:: Running the garbage collector. * Invoking guix pull:: Fetching the latest Guix and distribution. -* Channels:: Customizing the package collection. * Invoking guix time-machine:: Running an older revision of Guix. * Inferiors:: Interacting with another revision of Guix. * Invoking guix describe:: Display information about your Guix revision. @@ -227,6 +227,19 @@ Substitutes * Substitution Failure:: What happens when substitution fails. * On Trusting Binaries:: How can you trust that binary blob? +Channels + +* Specifying Additional Channels:: Extending the package collection. +* Using a Custom Guix Channel:: Using a customized Guix. +* Replicating Guix:: Running the @emph{exact same} Guix. +* Channel Authentication:: How Guix verifies what it fetches. +* Primary URL:: Distinguishing mirror to original. +* Creating a Channel:: How to write your custom channel. +* Package Modules in a Sub-directory:: Specifying the channel's package modules location. +* Declaring Channel Dependencies:: How to depend on other channels. +* Specifying Channel Authorizations:: Defining channel authors authorizations. +* Writing Channel News:: Communicating information to channel's users. + Development * Invoking guix environment:: Setting up development environments. @@ -2812,7 +2825,6 @@ guix install emacs-guix * Packages with Multiple Outputs:: Single source package, multiple outputs. * Invoking guix gc:: Running the garbage collector. * Invoking guix pull:: Fetching the latest Guix and distribution. -* Channels:: Customizing the package collection. * Invoking guix time-machine:: Running an older revision of Guix. * Inferiors:: Interacting with another revision of Guix. * Invoking guix describe:: Display information about your Guix revision. @@ -4189,937 +4201,972 @@ information. In addition, @command{guix pull} supports all the common build options (@pxref{Common Build Options}). -@node Channels -@section Channels - -@cindex channels -@cindex @file{channels.scm}, configuration file -@cindex configuration file for channels -@cindex @command{guix pull}, configuration file -@cindex configuration of @command{guix pull} -Guix and its package collection are updated by running @command{guix pull} -(@pxref{Invoking guix pull}). By default @command{guix pull} downloads and -deploys Guix itself from the official GNU@tie{}Guix repository. This can be -customized by defining @dfn{channels} in the -@file{~/.config/guix/channels.scm} file. A channel specifies a URL and branch -of a Git repository to be deployed, and @command{guix pull} can be instructed -to pull from one or more channels. In other words, channels can be used -to @emph{customize} and to @emph{extend} Guix, as we will see below. -Before that, some security considerations. +@node Invoking guix time-machine +@section Invoking @command{guix time-machine} -@subsection Channel Authentication +@cindex @command{guix time-machine} +@cindex pinning, channels +@cindex replicating Guix +@cindex reproducibility, of Guix -@anchor{channel-authentication} -@cindex authentication, of channel code -The @command{guix pull} and @command{guix time-machine} commands -@dfn{authenticate} the code retrieved from channels: they make sure each -commit that is fetched is signed by an authorized developer. The goal -is to protect from unauthorized modifications to the channel that would -lead users to run malicious code. +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}). -As a user, you must provide a @dfn{channel introduction} in your -channels file so that Guix knows how to authenticate its first commit. -A channel specification, including its introduction, looks something -along these lines: +The general syntax is: -@lisp -(channel - (name 'my-channel) - (url "https://example.org/my-channel.git") - (introduction - (make-channel-introduction - "6f0d8cc0d88abb59c324b2990bfee2876016bb86" - (openpgp-fingerprint - "CABB A931 C0FF EEC6 900D 0CFB 090B 1199 3D9A EBB5")))) -@end lisp +@example +guix time-machine @var{options}@dots{} -- @var{command} @var {arg}@dots{} +@end example -The specification above shows the name and URL of the channel. The call -to @code{make-channel-introduction} above specifies that authentication -of this channel starts at commit @code{6f0d8cc@dots{}}, which is signed -by the OpenPGP key with fingerprint @code{CABB A931@dots{}}. +where @var{command} and @var{arg}@dots{} are passed unmodified to the +@command{guix} command of the specified revision. The @var{options} that define +this revision are the same as for @command{guix pull} (@pxref{Invoking guix pull}): -For the main channel, called @code{guix}, you automatically get that -information from your Guix installation. For other channels, include -the channel introduction provided by the channel authors in your -@file{channels.scm} file. Make sure you retrieve the channel -introduction from a trusted source since that is the root of your trust. +@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}. -If you're curious about the authentication mechanics, read on! +@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 -@subsection Using a Custom Guix Channel +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 -The channel called @code{guix} specifies where Guix itself---its command-line -tools as well as its package collection---should be downloaded. For instance, -suppose you want to update from your own copy of the Guix repository at -@code{example.org}, and specifically the @code{super-hacks} branch, you can -write in @code{~/.config/guix/channels.scm} this specification: +@example +guix time-machine -- build hello +@end example -@lisp -;; Tell 'guix pull' to use my own repo. -(list (channel - (name 'guix) - (url "https://example.org/my-guix.git") - (branch "super-hacks"))) -@end lisp +will thus build the package @code{hello} as defined in the master branch, +which is in general a newer revision of Guix than you have installed. +Time travel works in both directions! -@noindent -From there on, @command{guix pull} will fetch code from the @code{super-hacks} -branch of the repository at @code{example.org}. +Note that @command{guix time-machine} can trigger builds of channels and +their dependencies, and these are controlled by the standard build +options (@pxref{Common Build Options}). -@subsection Specifying Additional Channels +@node Inferiors +@section Inferiors -@cindex extending the package collection (channels) -@cindex personal packages (channels) -@cindex channels, for personal packages -You can also specify @emph{additional channels} to pull from. Let's say you -have a bunch of custom package variants or personal packages that you think -would make little sense to contribute to the Guix project, but would like to -have these packages transparently available to you at the command line. You -would first write modules containing those package definitions (@pxref{Package -Modules}), maintain them in a Git repository, and then you and anyone else can -use it as an additional channel to get packages from. Neat, no? +@c TODO: Remove this once we're more confident about API stability. +@quotation Note +The functionality described here is a ``technology preview'' as of version +@value{VERSION}. As such, the interface is subject to change. +@end quotation -@c What follows stems from discussions at -@c as well as -@c earlier discussions on guix-devel@gnu.org. -@quotation Warning -Before you, dear user, shout---``woow this is @emph{soooo coool}!''---and -publish your personal channel to the world, we would like to share a few words -of caution: +@cindex inferiors +@cindex composition of Guix revisions +Sometimes you might need to mix packages from the revision of Guix you're +currently running with packages available in a different revision of Guix. +Guix @dfn{inferiors} allow you to achieve that by composing different Guix +revisions in arbitrary ways. -@itemize -@item -Before publishing a channel, please consider contributing your package -definitions to Guix proper (@pxref{Contributing}). Guix as a project is open -to free software of all sorts, and packages in Guix proper are readily -available to all Guix users and benefit from the project's quality assurance -process. +@cindex inferior packages +Technically, an ``inferior'' is essentially a separate Guix process connected +to your main Guix process through a REPL (@pxref{Invoking guix repl}). The +@code{(guix inferior)} module allows you to create inferiors and to +communicate with them. It also provides a high-level interface to browse and +manipulate the packages that an inferior provides---@dfn{inferior packages}. -@item -When you maintain package definitions outside Guix, we, Guix developers, -consider that @emph{the compatibility burden is on you}. Remember that -package modules and package definitions are just Scheme code that uses various -programming interfaces (APIs). We want to remain free to change these APIs to -keep improving Guix, possibly in ways that break your channel. We never -change APIs gratuitously, but we will @emph{not} commit to freezing APIs -either. +When combined with channels (@pxref{Channels}), inferiors provide a simple way +to interact with a separate revision of Guix. For example, let's assume you +want to install in your profile the current @code{guile} package, along with +the @code{guile-json} as it existed in an older revision of Guix---perhaps +because the newer @code{guile-json} has an incompatible API and you want to +run your code against the old API@. To do that, you could write a manifest for +use by @code{guix package --manifest} (@pxref{Invoking guix package}); in that +manifest, you would create an inferior for that old Guix revision you care +about, and you would look up the @code{guile-json} package in the inferior: -@item -Corollary: if you're using an external channel and that channel breaks, please -@emph{report the issue to the channel authors}, not to the Guix project. -@end itemize +@lisp +(use-modules (guix inferior) (guix channels) + (srfi srfi-1)) ;for 'first' -You've been warned! Having said this, we believe external channels are a -practical way to exert your freedom to augment Guix' package collection and to -share your improvements, which are basic tenets of -@uref{https://www.gnu.org/philosophy/free-sw.html, free software}. Please -email us at @email{guix-devel@@gnu.org} if you'd like to discuss this. -@end quotation +(define channels + ;; This is the old revision from which we want to + ;; extract guile-json. + (list (channel + (name 'guix) + (url "https://git.savannah.gnu.org/git/guix.git") + (commit + "65956ad3526ba09e1f7a40722c96c6ef7c0936fe")))) -To use a channel, write @code{~/.config/guix/channels.scm} to instruct -@command{guix pull} to pull from it @emph{in addition} to the default Guix -channel(s): +(define inferior + ;; An inferior representing the above revision. + (inferior-for-channels channels)) -@vindex %default-channels -@lisp -;; Add my personal packages to those Guix provides. -(cons (channel - (name 'my-personal-packages) - (url "https://example.org/personal-packages.git")) - %default-channels) +;; Now create a manifest with the current "guile" package +;; and the old "guile-json" package. +(packages->manifest + (list (first (lookup-inferior-packages inferior "guile-json")) + (specification->package "guile"))) @end lisp -@noindent -Note that the snippet above is (as always!)@: Scheme code; we use @code{cons} to -add a channel the list of channels that the variable @code{%default-channels} -is bound to (@pxref{Pairs, @code{cons} and lists,, guile, GNU Guile Reference -Manual}). With this file in place, @command{guix pull} builds not only Guix -but also the package modules from your own repository. The result in -@file{~/.config/guix/current} is the union of Guix with your own package -modules: +On its first run, @command{guix package --manifest} might have to build the +channel you specified before it can create the inferior; subsequent runs will +be much faster because the Guix revision will be cached. -@example -$ guix pull --list-generations -@dots{} -Generation 19 Aug 27 2018 16:20:48 - guix d894ab8 - repository URL: https://git.savannah.gnu.org/git/guix.git - branch: master - commit: d894ab8e9bfabcefa6c49d9ba2e834dd5a73a300 - my-personal-packages dd3df5e - repository URL: https://example.org/personal-packages.git - branch: master - commit: dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb - 11 new packages: my-gimp, my-emacs-with-cool-features, @dots{} - 4 packages upgraded: emacs-racket-mode@@0.0.2-2.1b78827, @dots{} -@end example +The @code{(guix inferior)} module provides the following procedures to open an +inferior: -@noindent -The output of @command{guix pull} above shows that Generation@tie{}19 includes -both Guix and packages from the @code{my-personal-packages} channel. Among -the new and upgraded packages that are listed, some like @code{my-gimp} and -@code{my-emacs-with-cool-features} might come from -@code{my-personal-packages}, while others come from the Guix default channel. +@deffn {Scheme Procedure} inferior-for-channels @var{channels} @ + [#:cache-directory] [#:ttl] +Return an inferior for @var{channels}, a list of channels. Use the cache at +@var{cache-directory}, where entries can be reclaimed after @var{ttl} seconds. +This procedure opens a new connection to the build daemon. -To create a channel, create a Git repository containing your own package -modules and make it available. The repository can contain anything, but a -useful channel will contain Guile modules that export packages. Once you -start using a channel, Guix will behave as if the root directory of that -channel's Git repository has been added to the Guile load path (@pxref{Load -Paths,,, guile, GNU Guile Reference Manual}). For example, if your channel -contains a file at @file{my-packages/my-tools.scm} that defines a Guile -module, then the module will be available under the name @code{(my-packages -my-tools)}, and you will be able to use it like any other module -(@pxref{Modules,,, guile, GNU Guile Reference Manual}). +As a side effect, this procedure may build or substitute binaries for +@var{channels}, which can take time. +@end deffn -@cindex dependencies, channels -@cindex meta-data, channels -@subsection Declaring Channel Dependencies +@deffn {Scheme Procedure} open-inferior @var{directory} @ + [#:command "bin/guix"] +Open the inferior Guix in @var{directory}, running +@code{@var{directory}/@var{command} repl} or equivalent. Return @code{#f} if +the inferior could not be launched. +@end deffn -Channel authors may decide to augment a package collection provided by other -channels. They can declare their channel to be dependent on other channels in -a meta-data file @file{.guix-channel}, which is to be placed in the root of -the channel repository. +@cindex inferior packages +The procedures listed below allow you to obtain and manipulate inferior +packages. -The meta-data file should contain a simple S-expression like this: +@deffn {Scheme Procedure} inferior-packages @var{inferior} +Return the list of packages known to @var{inferior}. +@end deffn -@lisp -(channel - (version 0) - (dependencies - (channel - (name some-collection) - (url "https://example.org/first-collection.git") - - ;; The 'introduction' bit below is optional: you would - ;; provide it for dependencies that can be authenticated. - (introduction - (channel-introduction - (version 0) - (commit "a8883b58dc82e167c96506cf05095f37c2c2c6cd") - (signer "CABB A931 C0FF EEC6 900D 0CFB 090B 1199 3D9A EBB5")))) - (channel - (name some-other-collection) - (url "https://example.org/second-collection.git") - (branch "testing")))) -@end lisp +@deffn {Scheme Procedure} lookup-inferior-packages @var{inferior} @var{name} @ + [@var{version}] +Return the sorted list of inferior packages matching @var{name} in +@var{inferior}, with highest version numbers first. If @var{version} is true, +return only packages with a version number prefixed by @var{version}. +@end deffn -In the above example this channel is declared to depend on two other channels, -which will both be fetched automatically. The modules provided by the channel -will be compiled in an environment where the modules of all these declared -channels are available. +@deffn {Scheme Procedure} inferior-package? @var{obj} +Return true if @var{obj} is an inferior package. +@end deffn -For the sake of reliability and maintainability, you should avoid dependencies -on channels that you don't control, and you should aim to keep the number of -dependencies to a minimum. +@deffn {Scheme Procedure} inferior-package-name @var{package} +@deffnx {Scheme Procedure} inferior-package-version @var{package} +@deffnx {Scheme Procedure} inferior-package-synopsis @var{package} +@deffnx {Scheme Procedure} inferior-package-description @var{package} +@deffnx {Scheme Procedure} inferior-package-home-page @var{package} +@deffnx {Scheme Procedure} inferior-package-location @var{package} +@deffnx {Scheme Procedure} inferior-package-inputs @var{package} +@deffnx {Scheme Procedure} inferior-package-native-inputs @var{package} +@deffnx {Scheme Procedure} inferior-package-propagated-inputs @var{package} +@deffnx {Scheme Procedure} inferior-package-transitive-propagated-inputs @var{package} +@deffnx {Scheme Procedure} inferior-package-native-search-paths @var{package} +@deffnx {Scheme Procedure} inferior-package-transitive-native-search-paths @var{package} +@deffnx {Scheme Procedure} inferior-package-search-paths @var{package} +These procedures are the counterpart of package record accessors +(@pxref{package Reference}). Most of them work by querying the inferior +@var{package} comes from, so the inferior must still be live when you call +these procedures. +@end deffn -@cindex subdirectory, channels -@subsection Package Modules in a Sub-directory +Inferior packages can be used transparently like any other package or +file-like object in G-expressions (@pxref{G-Expressions}). They are also +transparently handled by the @code{packages->manifest} procedure, which is +commonly use in manifests (@pxref{Invoking guix package, the +@option{--manifest} option of @command{guix package}}). Thus you can insert +an inferior package pretty much anywhere you would insert a regular package: +in manifests, in the @code{packages} field of your @code{operating-system} +declaration, and so on. -As a channel author, you may want to keep your channel modules in a -sub-directory. If your modules are in the sub-directory @file{guix}, you must -add a meta-data file @file{.guix-channel} that contains: +@node Invoking guix describe +@section Invoking @command{guix describe} -@lisp -(channel - (version 0) - (directory "guix")) -@end lisp +@cindex reproducibility +@cindex replicating Guix +Often you may want to answer questions like: ``Which revision of Guix am I +using?'' or ``Which channels am I using?'' This is useful information in many +situations: if you want to @emph{replicate} an environment on a different +machine or user account, if you want to report a bug or to determine what +change in the channels you are using caused it, or if you want to record your +system state for reproducibility purposes. The @command{guix describe} +command answers these questions. -@cindex channel authorizations -@subsection Specifying Channel Authorizations +When run from a @command{guix pull}ed @command{guix}, @command{guix describe} +displays the channel(s) that it was built from, including their repository URL +and commit IDs (@pxref{Channels}): -@anchor{channel-authorizations} -As we saw above, Guix ensures the source code it pulls from channels -comes from authorized developers. As a channel author, you need to -specify the list of authorized developers in the -@file{.guix-authorizations} file in the channel's Git repository. The -authentication rule is simple: each commit must be signed by a key -listed in the @file{.guix-authorizations} file of its parent -commit(s)@footnote{Git commits form a @dfn{directed acyclic graph} -(DAG). Each commit can have zero or more parents; ``regular'' commits -have one parent and merge commits have two parent commits. Read -@uref{https://eagain.net/articles/git-for-computer-scientists/, @i{Git -for Computer Scientists}} for a great overview.} The -@file{.guix-authorizations} file looks like this: +@example +$ guix describe +Generation 10 Sep 03 2018 17:32:44 (current) + guix e0fa68c + repository URL: https://git.savannah.gnu.org/git/guix.git + branch: master + commit: e0fa68c7718fffd33d81af415279d6ddb518f727 +@end example -@lisp -;; Example '.guix-authorizations' file. +If you're familiar with the Git version control system, this is similar in +spirit to @command{git describe}; the output is also similar to that of +@command{guix pull --list-generations}, but limited to the current generation +(@pxref{Invoking guix pull, the @option{--list-generations} option}). Because +the Git commit ID shown above unambiguously refers to a snapshot of Guix, this +information is all it takes to describe the revision of Guix you're using, and +also to replicate it. -(authorizations - (version 0) ;current file format version +To make it easier to replicate Guix, @command{guix describe} can also be asked +to return a list of channels instead of the human-readable description above: - (("AD17 A21E F8AE D8F1 CC02 DBD9 F8AE D8F1 765C 61E3" - (name "alice")) - ("2A39 3FFF 68F4 EF7A 3D29 12AF 68F4 EF7A 22FB B2D5" - (name "bob")) - ("CABB A931 C0FF EEC6 900D 0CFB 090B 1199 3D9A EBB5" - (name "charlie")))) -@end lisp +@example +$ guix describe -f channels +(list (channel + (name 'guix) + (url "https://git.savannah.gnu.org/git/guix.git") + (commit + "e0fa68c7718fffd33d81af415279d6ddb518f727") + (introduction + (make-channel-introduction + "9edb3f66fd807b096b48283debdcddccfea34bad" + (openpgp-fingerprint + "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))) +@end example -Each fingerprint is followed by optional key/value pairs, as in the -example above. Currently these key/value pairs are ignored. +@noindent +You can save this to a file and feed it to @command{guix pull -C} on some +other machine or at a later point in time, which will instantiate @emph{this +exact Guix revision} (@pxref{Invoking guix pull, the @option{-C} option}). +From there on, since you're able to deploy the same revision of Guix, you can +just as well @emph{replicate a complete software environment}. We humbly +think that this is @emph{awesome}, and we hope you'll like it too! -This authentication rule creates a chicken-and-egg issue: how do we -authenticate the first commit? Related to that: how do we deal with -channels whose repository history contains unsigned commits and lack -@file{.guix-authorizations}? And how do we fork existing channels? +The details of the options supported by @command{guix describe} are as +follows: -@cindex channel introduction -Channel introductions answer these questions by describing the first -commit of a channel that should be authenticated. The first time a -channel is fetched with @command{guix pull} or @command{guix -time-machine}, the command looks up the introductory commit and verifies -that it is signed by the specified OpenPGP key. From then on, it -authenticates commits according to the rule above. +@table @code +@item --format=@var{format} +@itemx -f @var{format} +Produce output in the specified @var{format}, one of: -Additionally, your channel must provide all the OpenPGP keys that were -ever mentioned in @file{.guix-authorizations}, stored as @file{.key} -files, which can be either binary or ``ASCII-armored''. By default, -those @file{.key} files are searched for in the branch named -@code{keyring} but you can specify a different branch name in -@code{.guix-channel} like so: +@table @code +@item human +produce human-readable output; +@item channels +produce a list of channel specifications that can be passed to @command{guix +pull -C} or installed as @file{~/.config/guix/channels.scm} (@pxref{Invoking +guix pull}); +@item channels-sans-intro +like @code{channels}, but omit the @code{introduction} field; use it to +produce a channel specification suitable for Guix version 1.1.0 or +earlier---the @code{introduction} field has to do with channel +authentication (@pxref{Channels, Channel Authentication}) and is not +supported by these older versions; +@item json +@cindex JSON +produce a list of channel specifications in JSON format; +@item recutils +produce a list of channel specifications in Recutils format. +@end table -@lisp -(channel - (version 0) - (keyring-reference "my-keyring-branch")) -@end lisp +@item --list-formats +Display available formats for @option{--format} option. -To summarize, as the author of a channel, there are three things you have -to do to allow users to authenticate your code: +@item --profile=@var{profile} +@itemx -p @var{profile} +Display information about @var{profile}. +@end table -@enumerate -@item -Export the OpenPGP keys of past and present committers with @command{gpg ---export} and store them in @file{.key} files, by default in a branch -named @code{keyring} (we recommend making it an @dfn{orphan branch}). +@node Invoking guix archive +@section Invoking @command{guix archive} -@item -Introduce an initial @file{.guix-authorizations} in the channel's -repository. Do that in a signed commit (@pxref{Commit Access}, for -information on how to sign Git commits.) +@cindex @command{guix archive} +@cindex archive +The @command{guix archive} command allows users to @dfn{export} files +from the store into a single archive, and to later @dfn{import} them on +a machine that runs Guix. +In particular, it allows store files to be transferred from one machine +to the store on another machine. -@item -Advertise the channel introduction, for instance on your channel's web -page. The channel introduction, as we saw above, is the commit/key -pair---i.e., the commit that introduced @file{.guix-authorizations}, and -the fingerprint of the OpenPGP used to sign it. -@end enumerate +@quotation Note +If you're looking for a way to produce archives in a format suitable for +tools other than Guix, @pxref{Invoking guix pack}. +@end quotation -Before pushing to your public Git repository, you can run @command{guix -git-authenticate} to verify that you did sign all the commits you are -about to push with an authorized key: +@cindex exporting store items +To export store files as an archive to standard output, run: @example -guix git authenticate @var{commit} @var{signer} +guix archive --export @var{options} @var{specifications}... @end example -@noindent -where @var{commit} and @var{signer} are your channel introduction. -@xref{Invoking guix git authenticate}, for details. +@var{specifications} may be either store file names or package +specifications, as for @command{guix package} (@pxref{Invoking guix +package}). For instance, the following command creates an archive +containing the @code{gui} output of the @code{git} package and the main +output of @code{emacs}: -Publishing a signed channel requires discipline: any mistake, such as an -unsigned commit or a commit signed by an unauthorized key, will prevent -users from pulling from your channel---well, that's the whole point of -authentication! Pay attention to merges in particular: merge commits -are considered authentic if and only if they are signed by a key present -in the @file{.guix-authorizations} file of @emph{both} branches. +@example +guix archive --export git:gui /gnu/store/...-emacs-24.3 > great.nar +@end example -@cindex primary URL, channels -@subsection Primary URL +If the specified packages are not built yet, @command{guix archive} +automatically builds them. The build process may be controlled with the +common build options (@pxref{Common Build Options}). -Channel authors can indicate the primary URL of their channel's Git -repository in the @file{.guix-channel} file, like so: - -@lisp -(channel - (version 0) - (url "https://example.org/guix.git")) -@end lisp - -This allows @command{guix pull} to determine whether it is pulling code -from a mirror of the channel; when that is the case, it warns the user -that the mirror might be stale and displays the primary URL. That way, -users cannot be tricked into fetching code from a stale mirror that does -not receive security updates. +To transfer the @code{emacs} package to a machine connected over SSH, +one would run: -This feature only makes sense for authenticated repositories, such as -the official @code{guix} channel, for which @command{guix pull} ensures -the code it fetches is authentic. +@example +guix archive --export -r emacs | ssh the-machine guix archive --import +@end example -@cindex news, for channels -@subsection Writing Channel News +@noindent +Similarly, a complete user profile may be transferred from one machine +to another like this: -Channel authors may occasionally want to communicate to their users -information about important changes in the channel. You'd send them all -an email, but that's not convenient. +@example +guix archive --export -r $(readlink -f ~/.guix-profile) | \ + ssh the-machine guix archive --import +@end example -Instead, channels can provide a @dfn{news file}; when the channel users -run @command{guix pull}, that news file is automatically read and -@command{guix pull --news} can display the announcements that correspond -to the new commits that have been pulled, if any. +@noindent +However, note that, in both examples, all of @code{emacs} and the +profile as well as all of their dependencies are transferred (due to +@option{-r}), regardless of what is already available in the store on +the target machine. The @option{--missing} option can help figure out +which items are missing from the target store. The @command{guix copy} +command simplifies and optimizes this whole process, so this is probably +what you should use in this case (@pxref{Invoking guix copy}). -To do that, channel authors must first declare the name of the news file -in their @file{.guix-channel} file: +@cindex nar, archive format +@cindex normalized archive (nar) +@cindex nar bundle, archive format +Each store item is written in the @dfn{normalized archive} or @dfn{nar} +format (described below), and the output of @command{guix archive +--export} (and input of @command{guix archive --import}) is a @dfn{nar +bundle}. -@lisp -(channel - (version 0) - (news-file "etc/news.txt")) -@end lisp +The nar format is +comparable in spirit to `tar', but with differences +that make it more appropriate for our purposes. First, rather than +recording all Unix metadata for each file, the nar format only mentions +the file type (regular, directory, or symbolic link); Unix permissions +and owner/group are dismissed. Second, the order in which directory +entries are stored always follows the order of file names according to +the C locale collation order. This makes archive production fully +deterministic. -The news file itself, @file{etc/news.txt} in this example, must look -something like this: +That nar bundle format is essentially the concatenation of zero or more +nars along with metadata for each store item it contains: its file name, +references, corresponding derivation, and a digital signature. -@lisp -(channel-news - (version 0) - (entry (tag "the-bug-fix") - (title (en "Fixed terrible bug") - (fr "Oh la la")) - (body (en "@@emph@{Good news@}! It's fixed!") - (eo "Certe ĝi pli bone funkcias nun!"))) - (entry (commit "bdcabe815cd28144a2d2b4bc3c5057b051fa9906") - (title (en "Added a great package") - (ca "Què vol dir guix?")) - (body (en "Don't miss the @@code@{hello@} package!")))) -@end lisp +When exporting, the daemon digitally signs the contents of the archive, +and that digital signature is appended. When importing, the daemon +verifies the signature and rejects the import in case of an invalid +signature or if the signing key is not authorized. +@c FIXME: Add xref to daemon doc about signatures. -While the news file is using the Scheme syntax, avoid naming it with a -@file{.scm} extension or else it will get picked up when building the -channel and yield an error since it is not a valid module. -Alternatively, you can move the channel module to a subdirectory and -store the news file in another directory. +The main options are: -The file consists of a list of @dfn{news entries}. Each entry is -associated with a commit or tag: it describes changes made in this -commit, possibly in preceding commits as well. Users see entries only -the first time they obtain the commit the entry refers to. +@table @code +@item --export +Export the specified store files or packages (see below). Write the +resulting archive to the standard output. -The @code{title} field should be a one-line summary while @code{body} -can be arbitrarily long, and both can contain Texinfo markup -(@pxref{Overview,,, texinfo, GNU Texinfo}). Both the title and body are -a list of language tag/message tuples, which allows @command{guix pull} -to display news in the language that corresponds to the user's locale. +Dependencies are @emph{not} included in the output, unless +@option{--recursive} is passed. -If you want to translate news using a gettext-based workflow, you can -extract translatable strings with @command{xgettext} (@pxref{xgettext -Invocation,,, gettext, GNU Gettext Utilities}). For example, assuming -you write news entries in English first, the command below creates a PO -file containing the strings to translate: +@item -r +@itemx --recursive +When combined with @option{--export}, this instructs @command{guix archive} +to include dependencies of the given items in the archive. Thus, the +resulting archive is self-contained: it contains the closure of the +exported store items. -@example -xgettext -o news.po -l scheme -ken etc/news.txt -@end example +@item --import +Read an archive from the standard input, and import the files listed +therein into the store. Abort if the archive has an invalid digital +signature, or if it is signed by a public key not among the authorized +keys (see @option{--authorize} below). -To sum up, yes, you could use your channel as a blog. But beware, this -is @emph{not quite} what your users might expect. +@item --missing +Read a list of store file names from the standard input, one per line, +and write on the standard output the subset of these files missing from +the store. -@subsection Replicating Guix +@item --generate-key[=@var{parameters}] +@cindex signing, archives +Generate a new key pair for the daemon. This is a prerequisite before +archives can be exported with @option{--export}. Note that this +operation usually takes time, because it needs to gather enough entropy +to generate the key pair. -@cindex pinning, channels -@cindex replicating Guix -@cindex reproducibility, of Guix -The @command{guix pull --list-generations} output above shows precisely which -commits were used to build this instance of Guix. We can thus replicate it, -say, on another machine, by providing a channel specification in -@file{~/.config/guix/channels.scm} that is ``pinned'' to these commits: +The generated key pair is typically stored under @file{/etc/guix}, in +@file{signing-key.pub} (public key) and @file{signing-key.sec} (private +key, which must be kept secret). When @var{parameters} is omitted, +an ECDSA key using the Ed25519 curve is generated, or, for Libgcrypt +versions before 1.6.0, it is a 4096-bit RSA key. +Alternatively, @var{parameters} can specify +@code{genkey} parameters suitable for Libgcrypt (@pxref{General +public-key related Functions, @code{gcry_pk_genkey},, gcrypt, The +Libgcrypt Reference Manual}). -@lisp -;; Deploy specific commits of my channels of interest. -(list (channel - (name 'guix) - (url "https://git.savannah.gnu.org/git/guix.git") - (commit "6298c3ffd9654d3231a6f25390b056483e8f407c")) - (channel - (name 'my-personal-packages) - (url "https://example.org/personal-packages.git") - (commit "dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb"))) -@end lisp +@item --authorize +@cindex authorizing, archives +Authorize imports signed by the public key passed on standard input. +The public key must be in ``s-expression advanced format''---i.e., the +same format as the @file{signing-key.pub} file. -The @command{guix describe --format=channels} command can even generate this -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}). +The list of authorized keys is kept in the human-editable file +@file{/etc/guix/acl}. The file contains +@url{https://people.csail.mit.edu/rivest/Sexp.txt, ``advanced-format +s-expressions''} and is structured as an access-control list in the +@url{https://theworld.com/~cme/spki.txt, Simple Public-Key Infrastructure +(SPKI)}. -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 -one machine will be exactly the same, bit for bit, as the output of the same -command on the other machine. It also means both machines have access to all -the source code of Guix and, transitively, to all the source code of every -package it defines. +@item --extract=@var{directory} +@itemx -x @var{directory} +Read a single-item archive as served by substitute servers +(@pxref{Substitutes}) and extract it to @var{directory}. This is a +low-level operation needed in only very narrow use cases; see below. -This gives you super powers, allowing you to track the provenance of binary -artifacts with very fine grain, and to reproduce software environments at -will---some sort of ``meta reproducibility'' capabilities, if you will. -@xref{Inferiors}, for another way to take advantage of these super powers. +For example, the following command extracts the substitute for Emacs +served by @code{@value{SUBSTITUTE-SERVER}} to @file{/tmp/emacs}: -@node Invoking guix time-machine -@section Invoking @command{guix time-machine} +@example +$ wget -O - \ + https://@value{SUBSTITUTE-SERVER}/nar/gzip/@dots{}-emacs-24.5 \ + | gunzip | guix archive -x /tmp/emacs +@end example -@cindex @command{guix time-machine} -@cindex pinning, channels -@cindex replicating Guix -@cindex reproducibility, of Guix +Single-item archives are different from multiple-item archives produced +by @command{guix archive --export}; they contain a single store item, +and they do @emph{not} embed a signature. Thus this operation does +@emph{no} signature verification and its output should be considered +unsafe. -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 primary purpose of this operation is to facilitate inspection of +archive contents coming from possibly untrusted substitute servers +(@pxref{Invoking guix challenge}). -The general syntax is: +@item --list +@itemx -t +Read a single-item archive as served by substitute servers +(@pxref{Substitutes}) and print the list of files it contains, as in +this example: @example -guix time-machine @var{options}@dots{} -- @var{command} @var {arg}@dots{} +$ wget -O - \ + https://@value{SUBSTITUTE-SERVER}/nar/lzip/@dots{}-emacs-26.3 \ + | lzip -d | guix archive -t @end example -where @var{command} and @var{arg}@dots{} are passed unmodified to the -@command{guix} command of 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 +@c ********************************************************************* +@node Channels +@chapter Channels + +@cindex channels +@cindex @file{channels.scm}, configuration file +@cindex configuration file for channels +@cindex @command{guix pull}, configuration file +@cindex configuration of @command{guix pull} +Guix and its package collection are updated by running @command{guix pull} +(@pxref{Invoking guix pull}). By default @command{guix pull} downloads and +deploys Guix itself from the official GNU@tie{}Guix repository. This can be +customized by defining @dfn{channels} in the +@file{~/.config/guix/channels.scm} file. A channel specifies a URL and branch +of a Git repository to be deployed, and @command{guix pull} can be instructed +to pull from one or more channels. In other words, channels can be used +to @emph{customize} and to @emph{extend} Guix, as we will see below. +Guix is able to take into account security concerns and deal with authenticated +updates. + +@menu +* Specifying Additional Channels:: Extending the package collection. +* Using a Custom Guix Channel:: Using a customized Guix. +* Replicating Guix:: Running the @emph{exact same} Guix. +* Channel Authentication:: How Guix verifies what it fetches. +* Primary URL:: Distinguishing mirror to original. +* Creating a Channel:: How to write your custom channel. +* Package Modules in a Sub-directory:: Specifying the channel's package modules location. +* Declaring Channel Dependencies:: How to depend on other channels. +* Specifying Channel Authorizations:: Defining channel authors authorizations. +* Writing Channel News:: Communicating information to channel's users. +@end menu + +@node Specifying Additional Channels +@section Specifying Additional Channels + +@cindex extending the package collection (channels) +@cindex variant packages (channels) +You can specify @emph{additional channels} to pull from. To use a channel, write +@code{~/.config/guix/channels.scm} to instruct @command{guix pull} to pull from it +@emph{in addition} to the default Guix channel(s): + +@vindex %default-channels +@lisp +;; Add variant packages to those Guix provides. +(cons (channel + (name 'variant-packages) + (url "https://example.org/variant-packages.git")) + %default-channels) +@end lisp + +@noindent +Note that the snippet above is (as always!)@: Scheme code; we use @code{cons} to +add a channel the list of channels that the variable @code{%default-channels} +is bound to (@pxref{Pairs, @code{cons} and lists,, guile, GNU Guile Reference +Manual}). With this file in place, @command{guix pull} builds not only Guix +but also the package modules from your own repository. The result in +@file{~/.config/guix/current} is the union of Guix with your own package +modules: @example -guix time-machine -- build hello +$ guix pull --list-generations +@dots{} +Generation 19 Aug 27 2018 16:20:48 + guix d894ab8 + repository URL: https://git.savannah.gnu.org/git/guix.git + branch: master + commit: d894ab8e9bfabcefa6c49d9ba2e834dd5a73a300 + variant-packages dd3df5e + repository URL: https://example.org/variant-packages.git + branch: master + commit: dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb + 11 new packages: variant-gimp, variant-emacs-with-cool-features, @dots{} + 4 packages upgraded: emacs-racket-mode@@0.0.2-2.1b78827, @dots{} @end example -will thus build the package @code{hello} as defined in the master branch, -which is in general a newer revision of Guix than you have installed. -Time travel works in both directions! +@noindent +The output of @command{guix pull} above shows that Generation@tie{}19 includes +both Guix and packages from the @code{variant-personal-packages} channel. Among +the new and upgraded packages that are listed, some like @code{variant-gimp} and +@code{variant-emacs-with-cool-features} might come from +@code{variant-packages}, while others come from the Guix default channel. -Note that @command{guix time-machine} can trigger builds of channels and -their dependencies, and these are controlled by the standard build -options (@pxref{Common Build Options}). +@node Using a Custom Guix Channel +@section Using a Custom Guix Channel -@node Inferiors -@section Inferiors +The channel called @code{guix} specifies where Guix itself---its command-line +tools as well as its package collection---should be downloaded. For instance, +suppose you want to update from another copy of the Guix repository at +@code{example.org}, and specifically the @code{super-hacks} branch, you can +write in @code{~/.config/guix/channels.scm} this specification: -@c TODO: Remove this once we're more confident about API stability. -@quotation Note -The functionality described here is a ``technology preview'' as of version -@value{VERSION}. As such, the interface is subject to change. -@end quotation +@lisp +;; Tell 'guix pull' to use another repo. +(list (channel + (name 'guix) + (url "https://example.org/another-guix.git") + (branch "super-hacks"))) +@end lisp -@cindex inferiors -@cindex composition of Guix revisions -Sometimes you might need to mix packages from the revision of Guix you're -currently running with packages available in a different revision of Guix. -Guix @dfn{inferiors} allow you to achieve that by composing different Guix -revisions in arbitrary ways. +@noindent +From there on, @command{guix pull} will fetch code from the @code{super-hacks} +branch of the repository at @code{example.org}. The authentication concern is +addressed below ((@pxref{Channel Authentication}). -@cindex inferior packages -Technically, an ``inferior'' is essentially a separate Guix process connected -to your main Guix process through a REPL (@pxref{Invoking guix repl}). The -@code{(guix inferior)} module allows you to create inferiors and to -communicate with them. It also provides a high-level interface to browse and -manipulate the packages that an inferior provides---@dfn{inferior packages}. +@node Replicating Guix +@section Replicating Guix -When combined with channels (@pxref{Channels}), inferiors provide a simple way -to interact with a separate revision of Guix. For example, let's assume you -want to install in your profile the current @code{guile} package, along with -the @code{guile-json} as it existed in an older revision of Guix---perhaps -because the newer @code{guile-json} has an incompatible API and you want to -run your code against the old API@. To do that, you could write a manifest for -use by @code{guix package --manifest} (@pxref{Invoking guix package}); in that -manifest, you would create an inferior for that old Guix revision you care -about, and you would look up the @code{guile-json} package in the inferior: +@cindex pinning, channels +@cindex replicating Guix +@cindex reproducibility, of Guix +The @command{guix pull --list-generations} output above shows precisely which +commits were used to build this instance of Guix. We can thus replicate it, +say, on another machine, by providing a channel specification in +@file{~/.config/guix/channels.scm} that is ``pinned'' to these commits: @lisp -(use-modules (guix inferior) (guix channels) - (srfi srfi-1)) ;for 'first' +;; Deploy specific commits of my channels of interest. +(list (channel + (name 'guix) + (url "https://git.savannah.gnu.org/git/guix.git") + (commit "6298c3ffd9654d3231a6f25390b056483e8f407c")) + (channel + (name 'variant-packages) + (url "https://example.org/variant-packages.git") + (commit "dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb"))) +@end lisp -(define channels - ;; This is the old revision from which we want to - ;; extract guile-json. - (list (channel - (name 'guix) - (url "https://git.savannah.gnu.org/git/guix.git") - (commit - "65956ad3526ba09e1f7a40722c96c6ef7c0936fe")))) +The @command{guix describe --format=channels} command can even generate this +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}). -(define inferior - ;; An inferior representing the above revision. - (inferior-for-channels channels)) +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 +one machine will be exactly the same, bit for bit, as the output of the same +command on the other machine. It also means both machines have access to all +the source code of Guix and, transitively, to all the source code of every +package it defines. -;; Now create a manifest with the current "guile" package -;; and the old "guile-json" package. -(packages->manifest - (list (first (lookup-inferior-packages inferior "guile-json")) - (specification->package "guile"))) +This gives you super powers, allowing you to track the provenance of binary +artifacts with very fine grain, and to reproduce software environments at +will---some sort of ``meta reproducibility'' capabilities, if you will. +@xref{Inferiors}, for another way to take advantage of these super powers. + +@node Channel Authentication +@section Channel Authentication + +@anchor{channel-authentication} +@cindex authentication, of channel code +The @command{guix pull} and @command{guix time-machine} commands +@dfn{authenticate} the code retrieved from channels: they make sure each +commit that is fetched is signed by an authorized developer. The goal +is to protect from unauthorized modifications to the channel that would +lead users to run malicious code. + +As a user, you must provide a @dfn{channel introduction} in your +channels file so that Guix knows how to authenticate its first commit. +A channel specification, including its introduction, looks something +along these lines: + +@lisp +(channel + (name 'some-channel) + (url "https://example.org/some-channel.git") + (introduction + (make-channel-introduction + "6f0d8cc0d88abb59c324b2990bfee2876016bb86" + (openpgp-fingerprint + "CABB A931 C0FF EEC6 900D 0CFB 090B 1199 3D9A EBB5")))) @end lisp -On its first run, @command{guix package --manifest} might have to build the -channel you specified before it can create the inferior; subsequent runs will -be much faster because the Guix revision will be cached. +The specification above shows the name and URL of the channel. The call +to @code{make-channel-introduction} above specifies that authentication +of this channel starts at commit @code{6f0d8cc@dots{}}, which is signed +by the OpenPGP key with fingerprint @code{CABB A931@dots{}}. -The @code{(guix inferior)} module provides the following procedures to open an -inferior: +For the main channel, called @code{guix}, you automatically get that +information from your Guix installation. For other channels, include +the channel introduction provided by the channel authors in your +@file{channels.scm} file. Make sure you retrieve the channel +introduction from a trusted source since that is the root of your trust. -@deffn {Scheme Procedure} inferior-for-channels @var{channels} @ - [#:cache-directory] [#:ttl] -Return an inferior for @var{channels}, a list of channels. Use the cache at -@var{cache-directory}, where entries can be reclaimed after @var{ttl} seconds. -This procedure opens a new connection to the build daemon. +If you're curious about the authentication mechanics, read on! -As a side effect, this procedure may build or substitute binaries for -@var{channels}, which can take time. -@end deffn +@cindex primary URL, channels +@node Primary URL +@section Primary URL -@deffn {Scheme Procedure} open-inferior @var{directory} @ - [#:command "bin/guix"] -Open the inferior Guix in @var{directory}, running -@code{@var{directory}/@var{command} repl} or equivalent. Return @code{#f} if -the inferior could not be launched. -@end deffn +Channel authors can indicate the primary URL of their channel's Git +repository in the @file{.guix-channel} file, like so: -@cindex inferior packages -The procedures listed below allow you to obtain and manipulate inferior -packages. +@lisp +(channel + (version 0) + (url "https://example.org/guix.git")) +@end lisp -@deffn {Scheme Procedure} inferior-packages @var{inferior} -Return the list of packages known to @var{inferior}. -@end deffn +This allows @command{guix pull} to determine whether it is pulling code +from a mirror of the channel; when that is the case, it warns the user +that the mirror might be stale and displays the primary URL. That way, +users cannot be tricked into fetching code from a stale mirror that does +not receive security updates. -@deffn {Scheme Procedure} lookup-inferior-packages @var{inferior} @var{name} @ - [@var{version}] -Return the sorted list of inferior packages matching @var{name} in -@var{inferior}, with highest version numbers first. If @var{version} is true, -return only packages with a version number prefixed by @var{version}. -@end deffn +This feature only makes sense for authenticated repositories, such as +the official @code{guix} channel, for which @command{guix pull} ensures +the code it fetches is authentic. -@deffn {Scheme Procedure} inferior-package? @var{obj} -Return true if @var{obj} is an inferior package. -@end deffn +@cindex personal packages (channels) +@cindex channels, for personal packages +@node Creating a Channel +@section Creating a Channel -@deffn {Scheme Procedure} inferior-package-name @var{package} -@deffnx {Scheme Procedure} inferior-package-version @var{package} -@deffnx {Scheme Procedure} inferior-package-synopsis @var{package} -@deffnx {Scheme Procedure} inferior-package-description @var{package} -@deffnx {Scheme Procedure} inferior-package-home-page @var{package} -@deffnx {Scheme Procedure} inferior-package-location @var{package} -@deffnx {Scheme Procedure} inferior-package-inputs @var{package} -@deffnx {Scheme Procedure} inferior-package-native-inputs @var{package} -@deffnx {Scheme Procedure} inferior-package-propagated-inputs @var{package} -@deffnx {Scheme Procedure} inferior-package-transitive-propagated-inputs @var{package} -@deffnx {Scheme Procedure} inferior-package-native-search-paths @var{package} -@deffnx {Scheme Procedure} inferior-package-transitive-native-search-paths @var{package} -@deffnx {Scheme Procedure} inferior-package-search-paths @var{package} -These procedures are the counterpart of package record accessors -(@pxref{package Reference}). Most of them work by querying the inferior -@var{package} comes from, so the inferior must still be live when you call -these procedures. -@end deffn +Let's say you have a bunch of custom package variants or personal packages +that you think would make little sense to contribute to the Guix project, but +would like to have these packages transparently available to you at the +command line. You would first write modules containing those package +definitions (@pxref{Package Modules}), maintain them in a Git repository, and +then you and anyone else can use it as an additional channel to get packages +from. Neat, no? -Inferior packages can be used transparently like any other package or -file-like object in G-expressions (@pxref{G-Expressions}). They are also -transparently handled by the @code{packages->manifest} procedure, which is -commonly use in manifests (@pxref{Invoking guix package, the -@option{--manifest} option of @command{guix package}}). Thus you can insert -an inferior package pretty much anywhere you would insert a regular package: -in manifests, in the @code{packages} field of your @code{operating-system} -declaration, and so on. +@c What follows stems from discussions at +@c as well as +@c earlier discussions on guix-devel@gnu.org. +@quotation Warning +Before you, dear user, shout---``woow this is @emph{soooo coool}!''---and +publish your personal channel to the world, we would like to share a few words +of caution: -@node Invoking guix describe -@section Invoking @command{guix describe} +@itemize +@item +Before publishing a channel, please consider contributing your package +definitions to Guix proper (@pxref{Contributing}). Guix as a project is open +to free software of all sorts, and packages in Guix proper are readily +available to all Guix users and benefit from the project's quality assurance +process. -@cindex reproducibility -@cindex replicating Guix -Often you may want to answer questions like: ``Which revision of Guix am I -using?'' or ``Which channels am I using?'' This is useful information in many -situations: if you want to @emph{replicate} an environment on a different -machine or user account, if you want to report a bug or to determine what -change in the channels you are using caused it, or if you want to record your -system state for reproducibility purposes. The @command{guix describe} -command answers these questions. +@item +When you maintain package definitions outside Guix, we, Guix developers, +consider that @emph{the compatibility burden is on you}. Remember that +package modules and package definitions are just Scheme code that uses various +programming interfaces (APIs). We want to remain free to change these APIs to +keep improving Guix, possibly in ways that break your channel. We never +change APIs gratuitously, but we will @emph{not} commit to freezing APIs +either. -When run from a @command{guix pull}ed @command{guix}, @command{guix describe} -displays the channel(s) that it was built from, including their repository URL -and commit IDs (@pxref{Channels}): +@item +Corollary: if you're using an external channel and that channel breaks, please +@emph{report the issue to the channel authors}, not to the Guix project. +@end itemize -@example -$ guix describe -Generation 10 Sep 03 2018 17:32:44 (current) - guix e0fa68c - repository URL: https://git.savannah.gnu.org/git/guix.git - branch: master - commit: e0fa68c7718fffd33d81af415279d6ddb518f727 -@end example +You've been warned! Having said this, we believe external channels are a +practical way to exert your freedom to augment Guix' package collection and to +share your improvements, which are basic tenets of +@uref{https://www.gnu.org/philosophy/free-sw.html, free software}. Please +email us at @email{guix-devel@@gnu.org} if you'd like to discuss this. +@end quotation -If you're familiar with the Git version control system, this is similar in -spirit to @command{git describe}; the output is also similar to that of -@command{guix pull --list-generations}, but limited to the current generation -(@pxref{Invoking guix pull, the @option{--list-generations} option}). Because -the Git commit ID shown above unambiguously refers to a snapshot of Guix, this -information is all it takes to describe the revision of Guix you're using, and -also to replicate it. +To create a channel, create a Git repository containing your own package +modules and make it available. The repository can contain anything, but a +useful channel will contain Guile modules that export packages. Once you +start using a channel, Guix will behave as if the root directory of that +channel's Git repository has been added to the Guile load path (@pxref{Load +Paths,,, guile, GNU Guile Reference Manual}). For example, if your channel +contains a file at @file{my-packages/my-tools.scm} that defines a Guile +module, then the module will be available under the name @code{(my-packages +my-tools)}, and you will be able to use it like any other module +(@pxref{Modules,,, guile, GNU Guile Reference Manual}). -To make it easier to replicate Guix, @command{guix describe} can also be asked -to return a list of channels instead of the human-readable description above: +As a channel author, consider bundling authentication material with your +channel so that users can authenticate it. @xref{Channel +Authentication}, and @ref{Specifying Channel Authorizations}, for info +on how to do it. -@example -$ guix describe -f channels -(list (channel - (name 'guix) - (url "https://git.savannah.gnu.org/git/guix.git") - (commit - "e0fa68c7718fffd33d81af415279d6ddb518f727") - (introduction - (make-channel-introduction - "9edb3f66fd807b096b48283debdcddccfea34bad" - (openpgp-fingerprint - "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))) -@end example -@noindent -You can save this to a file and feed it to @command{guix pull -C} on some -other machine or at a later point in time, which will instantiate @emph{this -exact Guix revision} (@pxref{Invoking guix pull, the @option{-C} option}). -From there on, since you're able to deploy the same revision of Guix, you can -just as well @emph{replicate a complete software environment}. We humbly -think that this is @emph{awesome}, and we hope you'll like it too! +@cindex subdirectory, channels +@node Package Modules in a Sub-directory +@section Package Modules in a Sub-directory -The details of the options supported by @command{guix describe} are as -follows: +As a channel author, you may want to keep your channel modules in a +sub-directory. If your modules are in the sub-directory @file{guix}, you must +add a meta-data file @file{.guix-channel} that contains: -@table @code -@item --format=@var{format} -@itemx -f @var{format} -Produce output in the specified @var{format}, one of: +@lisp +(channel + (version 0) + (directory "guix")) +@end lisp -@table @code -@item human -produce human-readable output; -@item channels -produce a list of channel specifications that can be passed to @command{guix -pull -C} or installed as @file{~/.config/guix/channels.scm} (@pxref{Invoking -guix pull}); -@item channels-sans-intro -like @code{channels}, but omit the @code{introduction} field; use it to -produce a channel specification suitable for Guix version 1.1.0 or -earlier---the @code{introduction} field has to do with channel -authentication (@pxref{Channels, Channel Authentication}) and is not -supported by these older versions; -@item json -@cindex JSON -produce a list of channel specifications in JSON format; -@item recutils -produce a list of channel specifications in Recutils format. -@end table +@cindex dependencies, channels +@cindex meta-data, channels +@node Declaring Channel Dependencies +@section Declaring Channel Dependencies -@item --list-formats -Display available formats for @option{--format} option. +Channel authors may decide to augment a package collection provided by other +channels. They can declare their channel to be dependent on other channels in +a meta-data file @file{.guix-channel}, which is to be placed in the root of +the channel repository. -@item --profile=@var{profile} -@itemx -p @var{profile} -Display information about @var{profile}. -@end table +The meta-data file should contain a simple S-expression like this: -@node Invoking guix archive -@section Invoking @command{guix archive} +@lisp +(channel + (version 0) + (dependencies + (channel + (name 'some-collection) + (url "https://example.org/first-collection.git") -@cindex @command{guix archive} -@cindex archive -The @command{guix archive} command allows users to @dfn{export} files -from the store into a single archive, and to later @dfn{import} them on -a machine that runs Guix. -In particular, it allows store files to be transferred from one machine -to the store on another machine. + ;; The 'introduction' bit below is optional: you would + ;; provide it for dependencies that can be authenticated. + (introduction + (channel-introduction + (version 0) + (commit "a8883b58dc82e167c96506cf05095f37c2c2c6cd") + (signer "CABB A931 C0FF EEC6 900D 0CFB 090B 1199 3D9A EBB5")))) + (channel + (name 'some-other-collection) + (url "https://example.org/second-collection.git") + (branch "testing")))) +@end lisp -@quotation Note -If you're looking for a way to produce archives in a format suitable for -tools other than Guix, @pxref{Invoking guix pack}. -@end quotation +In the above example this channel is declared to depend on two other channels, +which will both be fetched automatically. The modules provided by the channel +will be compiled in an environment where the modules of all these declared +channels are available. -@cindex exporting store items -To export store files as an archive to standard output, run: +For the sake of reliability and maintainability, you should avoid dependencies +on channels that you don't control, and you should aim to keep the number of +dependencies to a minimum. -@example -guix archive --export @var{options} @var{specifications}... -@end example +@cindex channel authorizations +@node Specifying Channel Authorizations +@section Specifying Channel Authorizations -@var{specifications} may be either store file names or package -specifications, as for @command{guix package} (@pxref{Invoking guix -package}). For instance, the following command creates an archive -containing the @code{gui} output of the @code{git} package and the main -output of @code{emacs}: +@anchor{channel-authorizations} +As we saw above, Guix ensures the source code it pulls from channels +comes from authorized developers. As a channel author, you need to +specify the list of authorized developers in the +@file{.guix-authorizations} file in the channel's Git repository. The +authentication rule is simple: each commit must be signed by a key +listed in the @file{.guix-authorizations} file of its parent +commit(s)@footnote{Git commits form a @dfn{directed acyclic graph} +(DAG). Each commit can have zero or more parents; ``regular'' commits +have one parent and merge commits have two parent commits. Read +@uref{https://eagain.net/articles/git-for-computer-scientists/, @i{Git +for Computer Scientists}} for a great overview.} The +@file{.guix-authorizations} file looks like this: -@example -guix archive --export git:gui /gnu/store/...-emacs-24.3 > great.nar -@end example +@lisp +;; Example '.guix-authorizations' file. -If the specified packages are not built yet, @command{guix archive} -automatically builds them. The build process may be controlled with the -common build options (@pxref{Common Build Options}). +(authorizations + (version 0) ;current file format version -To transfer the @code{emacs} package to a machine connected over SSH, -one would run: + (("AD17 A21E F8AE D8F1 CC02 DBD9 F8AE D8F1 765C 61E3" + (name "alice")) + ("2A39 3FFF 68F4 EF7A 3D29 12AF 68F4 EF7A 22FB B2D5" + (name "bob")) + ("CABB A931 C0FF EEC6 900D 0CFB 090B 1199 3D9A EBB5" + (name "charlie")))) +@end lisp -@example -guix archive --export -r emacs | ssh the-machine guix archive --import -@end example +Each fingerprint is followed by optional key/value pairs, as in the +example above. Currently these key/value pairs are ignored. -@noindent -Similarly, a complete user profile may be transferred from one machine -to another like this: +This authentication rule creates a chicken-and-egg issue: how do we +authenticate the first commit? Related to that: how do we deal with +channels whose repository history contains unsigned commits and lack +@file{.guix-authorizations}? And how do we fork existing channels? -@example -guix archive --export -r $(readlink -f ~/.guix-profile) | \ - ssh the-machine guix archive --import -@end example +@cindex channel introduction +Channel introductions answer these questions by describing the first +commit of a channel that should be authenticated. The first time a +channel is fetched with @command{guix pull} or @command{guix +time-machine}, the command looks up the introductory commit and verifies +that it is signed by the specified OpenPGP key. From then on, it +authenticates commits according to the rule above. -@noindent -However, note that, in both examples, all of @code{emacs} and the -profile as well as all of their dependencies are transferred (due to -@option{-r}), regardless of what is already available in the store on -the target machine. The @option{--missing} option can help figure out -which items are missing from the target store. The @command{guix copy} -command simplifies and optimizes this whole process, so this is probably -what you should use in this case (@pxref{Invoking guix copy}). +Additionally, your channel must provide all the OpenPGP keys that were +ever mentioned in @file{.guix-authorizations}, stored as @file{.key} +files, which can be either binary or ``ASCII-armored''. By default, +those @file{.key} files are searched for in the branch named +@code{keyring} but you can specify a different branch name in +@code{.guix-channel} like so: -@cindex nar, archive format -@cindex normalized archive (nar) -@cindex nar bundle, archive format -Each store item is written in the @dfn{normalized archive} or @dfn{nar} -format (described below), and the output of @command{guix archive ---export} (and input of @command{guix archive --import}) is a @dfn{nar -bundle}. +@lisp +(channel + (version 0) + (keyring-reference "my-keyring-branch")) +@end lisp -The nar format is -comparable in spirit to `tar', but with differences -that make it more appropriate for our purposes. First, rather than -recording all Unix metadata for each file, the nar format only mentions -the file type (regular, directory, or symbolic link); Unix permissions -and owner/group are dismissed. Second, the order in which directory -entries are stored always follows the order of file names according to -the C locale collation order. This makes archive production fully -deterministic. +To summarize, as the author of a channel, there are three things you have +to do to allow users to authenticate your code: -That nar bundle format is essentially the concatenation of zero or more -nars along with metadata for each store item it contains: its file name, -references, corresponding derivation, and a digital signature. +@enumerate +@item +Export the OpenPGP keys of past and present committers with @command{gpg +--export} and store them in @file{.key} files, by default in a branch +named @code{keyring} (we recommend making it an @dfn{orphan branch}). -When exporting, the daemon digitally signs the contents of the archive, -and that digital signature is appended. When importing, the daemon -verifies the signature and rejects the import in case of an invalid -signature or if the signing key is not authorized. -@c FIXME: Add xref to daemon doc about signatures. +@item +Introduce an initial @file{.guix-authorizations} in the channel's +repository. Do that in a signed commit (@pxref{Commit Access}, for +information on how to sign Git commits.) -The main options are: +@item +Advertise the channel introduction, for instance on your channel's web +page. The channel introduction, as we saw above, is the commit/key +pair---i.e., the commit that introduced @file{.guix-authorizations}, and +the fingerprint of the OpenPGP used to sign it. +@end enumerate -@table @code -@item --export -Export the specified store files or packages (see below). Write the -resulting archive to the standard output. +Before pushing to your public Git repository, you can run @command{guix +git-authenticate} to verify that you did sign all the commits you are +about to push with an authorized key: -Dependencies are @emph{not} included in the output, unless -@option{--recursive} is passed. +@example +guix git authenticate @var{commit} @var{signer} +@end example -@item -r -@itemx --recursive -When combined with @option{--export}, this instructs @command{guix archive} -to include dependencies of the given items in the archive. Thus, the -resulting archive is self-contained: it contains the closure of the -exported store items. +@noindent +where @var{commit} and @var{signer} are your channel introduction. +@xref{Invoking guix git authenticate}, for details. -@item --import -Read an archive from the standard input, and import the files listed -therein into the store. Abort if the archive has an invalid digital -signature, or if it is signed by a public key not among the authorized -keys (see @option{--authorize} below). +Publishing a signed channel requires discipline: any mistake, such as an +unsigned commit or a commit signed by an unauthorized key, will prevent +users from pulling from your channel---well, that's the whole point of +authentication! Pay attention to merges in particular: merge commits +are considered authentic if and only if they are signed by a key present +in the @file{.guix-authorizations} file of @emph{both} branches. -@item --missing -Read a list of store file names from the standard input, one per line, -and write on the standard output the subset of these files missing from -the store. +@cindex news, for channels +@node Writing Channel News +@section Writing Channel News -@item --generate-key[=@var{parameters}] -@cindex signing, archives -Generate a new key pair for the daemon. This is a prerequisite before -archives can be exported with @option{--export}. Note that this -operation usually takes time, because it needs to gather enough entropy -to generate the key pair. +Channel authors may occasionally want to communicate to their users +information about important changes in the channel. You'd send them all +an email, but that's not convenient. -The generated key pair is typically stored under @file{/etc/guix}, in -@file{signing-key.pub} (public key) and @file{signing-key.sec} (private -key, which must be kept secret). When @var{parameters} is omitted, -an ECDSA key using the Ed25519 curve is generated, or, for Libgcrypt -versions before 1.6.0, it is a 4096-bit RSA key. -Alternatively, @var{parameters} can specify -@code{genkey} parameters suitable for Libgcrypt (@pxref{General -public-key related Functions, @code{gcry_pk_genkey},, gcrypt, The -Libgcrypt Reference Manual}). +Instead, channels can provide a @dfn{news file}; when the channel users +run @command{guix pull}, that news file is automatically read and +@command{guix pull --news} can display the announcements that correspond +to the new commits that have been pulled, if any. -@item --authorize -@cindex authorizing, archives -Authorize imports signed by the public key passed on standard input. -The public key must be in ``s-expression advanced format''---i.e., the -same format as the @file{signing-key.pub} file. +To do that, channel authors must first declare the name of the news file +in their @file{.guix-channel} file: -The list of authorized keys is kept in the human-editable file -@file{/etc/guix/acl}. The file contains -@url{https://people.csail.mit.edu/rivest/Sexp.txt, ``advanced-format -s-expressions''} and is structured as an access-control list in the -@url{https://theworld.com/~cme/spki.txt, Simple Public-Key Infrastructure -(SPKI)}. +@lisp +(channel + (version 0) + (news-file "etc/news.txt")) +@end lisp -@item --extract=@var{directory} -@itemx -x @var{directory} -Read a single-item archive as served by substitute servers -(@pxref{Substitutes}) and extract it to @var{directory}. This is a -low-level operation needed in only very narrow use cases; see below. +The news file itself, @file{etc/news.txt} in this example, must look +something like this: -For example, the following command extracts the substitute for Emacs -served by @code{@value{SUBSTITUTE-SERVER}} to @file{/tmp/emacs}: +@lisp +(channel-news + (version 0) + (entry (tag "the-bug-fix") + (title (en "Fixed terrible bug") + (fr "Oh la la")) + (body (en "@@emph@{Good news@}! It's fixed!") + (eo "Certe ĝi pli bone funkcias nun!"))) + (entry (commit "bdcabe815cd28144a2d2b4bc3c5057b051fa9906") + (title (en "Added a great package") + (ca "Què vol dir guix?")) + (body (en "Don't miss the @@code@{hello@} package!")))) +@end lisp -@example -$ wget -O - \ - https://@value{SUBSTITUTE-SERVER}/nar/gzip/@dots{}-emacs-24.5 \ - | gunzip | guix archive -x /tmp/emacs -@end example +While the news file is using the Scheme syntax, avoid naming it with a +@file{.scm} extension or else it will get picked up when building the +channel and yield an error since it is not a valid module. +Alternatively, you can move the channel module to a subdirectory and +store the news file in another directory. -Single-item archives are different from multiple-item archives produced -by @command{guix archive --export}; they contain a single store item, -and they do @emph{not} embed a signature. Thus this operation does -@emph{no} signature verification and its output should be considered -unsafe. +The file consists of a list of @dfn{news entries}. Each entry is +associated with a commit or tag: it describes changes made in this +commit, possibly in preceding commits as well. Users see entries only +the first time they obtain the commit the entry refers to. -The primary purpose of this operation is to facilitate inspection of -archive contents coming from possibly untrusted substitute servers -(@pxref{Invoking guix challenge}). +The @code{title} field should be a one-line summary while @code{body} +can be arbitrarily long, and both can contain Texinfo markup +(@pxref{Overview,,, texinfo, GNU Texinfo}). Both the title and body are +a list of language tag/message tuples, which allows @command{guix pull} +to display news in the language that corresponds to the user's locale. -@item --list -@itemx -t -Read a single-item archive as served by substitute servers -(@pxref{Substitutes}) and print the list of files it contains, as in -this example: +If you want to translate news using a gettext-based workflow, you can +extract translatable strings with @command{xgettext} (@pxref{xgettext +Invocation,,, gettext, GNU Gettext Utilities}). For example, assuming +you write news entries in English first, the command below creates a PO +file containing the strings to translate: @example -$ wget -O - \ - https://@value{SUBSTITUTE-SERVER}/nar/lzip/@dots{}-emacs-26.3 \ - | lzip -d | guix archive -t +xgettext -o news.po -l scheme -ken etc/news.txt @end example -@end table +To sum up, yes, you could use your channel as a blog. But beware, this +is @emph{not quite} what your users might expect. @c ********************************************************************* -- 2.28.0