diff options
-rw-r--r-- | doc/guix.texi | 985 |
1 files changed, 516 insertions, 469 deletions
diff --git a/doc/guix.texi b/doc/guix.texi index dbf0c517a7..cc8214c257 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,473 +4201,6 @@ 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. - -@subsection 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 '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 - -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{}}. - -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. - -If you're curious about the authentication mechanics, read on! - -@subsection Using a Custom Guix Channel - -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: - -@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 - -@noindent -From there on, @command{guix pull} will fetch code from the @code{super-hacks} -branch of the repository at @code{example.org}. - -@subsection Specifying Additional Channels - -@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 What follows stems from discussions at -@c <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22629#134> 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: - -@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. - -@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. - -@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 - -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 - -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 my personal packages to those Guix provides. -(cons (channel - (name 'my-personal-packages) - (url "https://example.org/personal-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 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 - -@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. - -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}). - -@cindex dependencies, channels -@cindex meta-data, channels -@subsection Declaring Channel Dependencies - -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. - -The meta-data file should contain a simple S-expression like this: - -@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 - -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. - -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. - -@cindex subdirectory, channels -@subsection Package Modules in a Sub-directory - -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: - -@lisp -(channel - (version 0) - (directory "guix")) -@end lisp - -@cindex channel authorizations -@subsection Specifying Channel Authorizations - -@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: - -@lisp -;; Example '.guix-authorizations' file. - -(authorizations - (version 0) ;current file format version - - (("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 - -Each fingerprint is followed by optional key/value pairs, as in the -example above. Currently these key/value pairs are ignored. - -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? - -@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. - -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: - -@lisp -(channel - (version 0) - (keyring-reference "my-keyring-branch")) -@end lisp - -To summarize, as the author of a channel, there are three things you have -to do to allow users to authenticate your code: - -@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}). - -@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.) - -@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 - -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: - -@example -guix git authenticate @var{commit} @var{signer} -@end example - -@noindent -where @var{commit} and @var{signer} are your channel introduction. -@xref{Invoking guix git authenticate}, for details. - -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. - -@cindex primary URL, channels -@subsection Primary URL - -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. - -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. - -@cindex news, for channels -@subsection Writing Channel News - -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. - -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. - -To do that, channel authors must first declare the name of the news file -in their @file{.guix-channel} file: - -@lisp -(channel - (version 0) - (news-file "etc/news.txt")) -@end lisp - -The news file itself, @file{etc/news.txt} in this example, must look -something like this: - -@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 - -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 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 @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. - -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 -xgettext -o news.po -l scheme -ken etc/news.txt -@end example - -To sum up, yes, you could use your channel as a blog. But beware, this -is @emph{not quite} what your users might expect. - -@subsection Replicating Guix - -@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 -;; 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 - -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}). - -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. - -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 Invoking guix time-machine @section Invoking @command{guix time-machine} @@ -5121,6 +4666,508 @@ $ wget -O - \ @end table +@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 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 + +@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. + +@node Using a Custom Guix Channel +@section Using a Custom Guix Channel + +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: + +@lisp +;; Tell 'guix pull' to use another repo. +(list (channel + (name 'guix) + (url "https://example.org/another-guix.git") + (branch "super-hacks"))) +@end lisp + +@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}). + +@node Replicating Guix +@section Replicating Guix + +@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 +;; 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 + +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}). + +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. + +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 + +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{}}. + +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. + +If you're curious about the authentication mechanics, read on! + +@cindex primary URL, channels +@node Primary URL +@section Primary URL + +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. + +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. + +@cindex personal packages (channels) +@cindex channels, for personal packages +@node Creating a Channel +@section Creating a Channel + +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 What follows stems from discussions at +@c <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22629#134> 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: + +@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. + +@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. + +@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 + +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 + +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 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. + + +@cindex subdirectory, channels +@node Package Modules in a Sub-directory +@section Package Modules in a Sub-directory + +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: + +@lisp +(channel + (version 0) + (directory "guix")) +@end lisp + +@cindex dependencies, channels +@cindex meta-data, channels +@node Declaring Channel Dependencies +@section Declaring Channel Dependencies + +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. + +The meta-data file should contain a simple S-expression like this: + +@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 + +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. + +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. + +@cindex channel authorizations +@node Specifying Channel Authorizations +@section Specifying Channel Authorizations + +@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: + +@lisp +;; Example '.guix-authorizations' file. + +(authorizations + (version 0) ;current file format version + + (("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 + +Each fingerprint is followed by optional key/value pairs, as in the +example above. Currently these key/value pairs are ignored. + +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? + +@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. + +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: + +@lisp +(channel + (version 0) + (keyring-reference "my-keyring-branch")) +@end lisp + +To summarize, as the author of a channel, there are three things you have +to do to allow users to authenticate your code: + +@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}). + +@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.) + +@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 + +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: + +@example +guix git authenticate @var{commit} @var{signer} +@end example + +@noindent +where @var{commit} and @var{signer} are your channel introduction. +@xref{Invoking guix git authenticate}, for details. + +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. + +@cindex news, for channels +@node Writing Channel News +@section Writing Channel News + +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. + +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. + +To do that, channel authors must first declare the name of the news file +in their @file{.guix-channel} file: + +@lisp +(channel + (version 0) + (news-file "etc/news.txt")) +@end lisp + +The news file itself, @file{etc/news.txt} in this example, must look +something like this: + +@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 + +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 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 @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. + +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 +xgettext -o news.po -l scheme -ken etc/news.txt +@end example + +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 ********************************************************************* @node Development |