gnu: r-wgcna: Move to (gnu packages bioconductor).
[jackhill/guix/guix.git] / doc / guix-cookbook.texi
index 8651bc4..a783c0a 100644 (file)
@@ -14,6 +14,9 @@ Copyright @copyright{} 2019 Pierre Neidhardt@*
 Copyright @copyright{} 2020 Oleg Pykhalov@*
 Copyright @copyright{} 2020 Matthew Brooks@*
 Copyright @copyright{} 2020 Marcin Karpezo@*
+Copyright @copyright{} 2020 Brice Waegeneire@*
+Copyright @copyright{} 2020 André Batista@*
+Copyright @copyright{} 2020 Christopher Lemmer Webber
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -62,6 +65,7 @@ Translation Project}.
 * Packaging::                   Packaging tutorials
 * System Configuration::        Customizing the GNU System
 * Advanced package management:: Power to the users!
+* Environment management::      Control environment
 
 * Acknowledgments::             Thanks!
 * GNU Free Documentation License::  The license of this document.
@@ -108,8 +112,8 @@ Let's get started!
 
 Guix uses the Guile implementation of Scheme.  To start playing with the
 language, install it with @code{guix install guile} and start a
-@uref{https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop,
-REPL} by running @code{guile} from the command line.
+@dfn{REPL}---short for @uref{https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop,
+@dfn{read-eval-print loop}}---by running @code{guile} from the command line.
 
 Alternatively you can also run @code{guix environment --ad-hoc guile -- guile}
 if you'd rather not have Guile installed in your user profile.
@@ -117,7 +121,7 @@ if you'd rather not have Guile installed in your user profile.
 In the following examples, lines show what you would type at the REPL;
 lines starting with ``@result{}'' show evaluation results, while lines
 starting with ``@print{}'' show things that get printed.  @xref{Using Guile
-Interactively,,, guile, GNU Guile Reference Manual}), for more details on the
+Interactively,,, guile, GNU Guile Reference Manual}, for more details on the
 REPL.
 
 @itemize
@@ -327,7 +331,7 @@ package definitions.
 @item
 Inheritance makes it easy to customize a package by inheriting from it and
 modifying only what is needed.
+
 @item
 Batch processing: the whole package collection can be parsed, filtered and
 processed.  Building a headless server with all graphical interfaces stripped
@@ -842,12 +846,32 @@ tags, so if the @code{version} is tagged, then it can be used directly.  Sometim
 the tag is prefixed with a @code{v}, in which case you'd use @code{(commit (string-append
 "v" version))}.
 
-To ensure that the source code from the Git repository is stored in a unique
-directory with a readable name we use @code{(file-name (git-file-name name
+To ensure that the source code from the Git repository is stored in a
+directory with a descriptive name, we use @code{(file-name (git-file-name name
 version))}.
 
-Note that there is also a @code{git-version} procedure that can be used to derive the
-version when packaging programs for a specific commit.
+The @code{git-version} procedure can be used to derive the
+version when packaging programs for a specific commit, following the
+Guix contributor guidelines (@pxref{Version Numbers,,, guix, GNU Guix
+Reference Manual}).
+
+How does one obtain the @code{sha256} hash that's in there, you ask?  By
+invoking @command{guix hash} on a checkout of the desired commit, along
+these lines:
+
+@example
+git clone https://github.com/libgit2/libgit2/
+cd libgit2
+git checkout v0.26.6
+guix hash -rx .
+@end example
+
+@command{guix hash -rx} computes a SHA256 hash over the whole directory,
+excluding the @file{.git} sub-directory (@pxref{Invoking guix hash,,,
+guix, GNU Guix Reference Manual}).
+
+In the future, @command{guix download} will hopefully be able to do
+these steps for you, just like it does for regular downloads.
 
 @subsubsection Snippets
 
@@ -1266,7 +1290,7 @@ version or compilation options.
 @subsection Getting help
 
 Sadly, some applications can be tough to package.  Sometimes they need a patch to
-work with the non-standard filesystem hierarchy enforced by the store.
+work with the non-standard file system hierarchy enforced by the store.
 Sometimes the tests won't run properly.  (They can be skipped but this is not
 recommended.)  Other times the resulting package won't be reproducible.
 
@@ -1323,8 +1347,11 @@ reference.
 
 @menu
 * Customizing the Kernel::       Creating and using a custom Linux kernel on Guix System.
+* Connecting to Wireguard VPN::  Connecting to a Wireguard VPN.
 * Customizing a Window Manager:: Handle customization of a Window manager on Guix System.
+* Running Guix on a Linode Server:: Running Guix on a Linode Server
 * Setting up a bind mount:: Setting up a bind mount in the file-systems definition.
+* Getting substitutes from Tor:: Configuring Guix daemon to get substitutes through Tor.
 @end menu
 
 @node Customizing the Kernel
@@ -1477,7 +1504,7 @@ custom kernel:
 @lisp
 (define %macbook41-full-config
   (append %macbook41-config-options
-          %filesystems
+          %file-systems
           %efi-support
           %emulation
           (@@@@ (gnu packages linux) %default-extra-linux-options)))
@@ -1493,8 +1520,8 @@ custom kernel:
                       #:extra-options %macbook41-config-options))
 @end lisp
 
-In the above example @code{%filesystems} is a collection of flags enabling
-different filesystem support, @code{%efi-support} enables EFI support and
+In the above example @code{%file-systems} is a collection of flags enabling
+different file system support, @code{%efi-support} enables EFI support and
 @code{%emulation} enables a x86_64-linux machine to act in 32-bit mode also.
 @code{%default-extra-linux-options} are the ones quoted above, which had to be
 added in since they were replaced in the @code{extra-options} keyword.
@@ -1558,7 +1585,7 @@ The second way to setup the kernel configuration makes more use of Guix's
 features and allows you to share configuration segments between different
 kernels.  For example, all machines using EFI to boot have a number of EFI
 configuration flags that they need.  It is likely that all the kernels will
-share a list of filesystems to support.  By using variables it is easier to
+share a list of file systems to support.  By using variables it is easier to
 see at a glance what features are enabled and to make sure you don't have
 features in one kernel but missing in another.
 
@@ -1567,6 +1594,83 @@ likely that you'll need to modify the initrd on a machine using a custom
 kernel, since certain modules which are expected to be built may not be
 available for inclusion into the initrd.
 
+@node Connecting to Wireguard VPN
+@section Connecting to Wireguard VPN
+
+To connect to a Wireguard VPN server you need the kernel module to be
+loaded in memory and a package providing networking tools that support
+it (e.g.  @code{wireguard-tools} or @code{network-manager}).
+
+Here is a configuration example for Linux-Libre < 5.6, where the module
+is out of tree and need to be loaded manually---following revisions of
+the kernel have it built-in and so don't need such configuration:
+
+@lisp
+(use-modules (gnu))
+(use-service-modules desktop)
+(use-package-modules vpn)
+
+(operating-system
+  ;; …
+  (services (cons (simple-service 'wireguard-module
+                                  kernel-module-loader-service-type
+                                  '("wireguard"))
+                  %desktop-services))
+  (packages (cons wireguard-tools %base-packages))
+  (kernel-loadable-modules (list wireguard-linux-compat)))
+@end lisp
+
+After reconfiguring and restarting your system you can either use
+Wireguard tools or NetworkManager to connect to a VPN server.
+
+@subsection Using Wireguard tools
+
+To test your Wireguard setup it is convenient to use @command{wg-quick}.
+Just give it a configuration file @command{wg-quick up ./wg0.conf}; or
+put that file in @file{/etc/wireguard} and run @command{wg-quick up wg0}
+instead.
+
+@quotation Note
+Be warned that the author described this command as a: “[…] very quick
+and dirty bash script […]”.
+@end quotation
+
+@subsection Using NetworkManager
+
+Thanks to NetworkManager support for Wireguard we can connect to our VPN
+using @command{nmcli} command.  Up to this point this guide assumes that
+you're using Network Manager service provided by
+@code{%desktop-services}.  Ortherwise you need to adjust your services
+list to load @code{network-manager-service-type} and reconfigure your
+Guix system.
+
+To import your VPN configuration execute nmcli import command:
+
+@example shell
+# nmcli connection import type wireguard file wg0.conf
+Connection 'wg0' (edbee261-aa5a-42db-b032-6c7757c60fde) successfully added
+@end example
+
+This will create a configuration file in
+@file{/etc/NetworkManager/wg0.nmconnection}.  Next connect to the
+Wireguard server:
+
+@example shell
+$ nmcli connection up wg0
+Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)
+@end example
+
+By default NetworkManager will connect automatically on system boot.  To
+change that behaviour you need to edit your config:
+
+@example shell
+# nmcli connection modify wg0 connection.autoconnect no
+@end example
+
+For more specific information about NetworkManager and wireguard
+@uref{https://blogs.gnome.org/thaller/2019/03/15/wireguard-in-networkmanager/,see
+this post by thaller}.
+
 @node Customizing a Window Manager
 @section Customizing a Window Manager
 @cindex wm
@@ -1658,6 +1762,246 @@ your screen but not suspend it, it's a good idea to notify xss-lock about this s
 confusion occurs. This can be done by executing @code{xset s activate} immediately
 before you execute slock.
 
+@node Running Guix on a Linode Server
+@section Running Guix on a Linode Server
+@cindex linode, Linode
+
+To run Guix on a server hosted by @uref{https://www.linode.com, Linode},
+start with a recommended Debian server.  We recommend using the default
+distro as a way to bootstrap Guix. Create your SSH keys.
+
+@example
+ssh-keygen
+@end example
+
+Be sure to add your SSH key for easy login to the remote server.
+This is trivially done via Linode's graphical interface for adding
+SSH keys.  Go to your profile and click add SSH Key.
+Copy into it the output of:
+
+@example
+cat ~/.ssh/<username>_rsa.pub
+@end example
+
+Power the Linode down. In the Linode's Disks/Configurations tab, resize
+the Debian disk to be smaller. 30 GB is recommended.
+
+In the Linode settings, "Add a disk", with the following:
+@itemize @bullet
+@item
+Label: "Guix"
+
+@item
+Filesystem: ext4
+
+@item
+Set it to the remaining size
+@end itemize
+
+On the "configuration" field that comes with the default image, press
+"..." and select "Edit", then on that menu add to @file{/dev/sdc} the "Guix"
+label.
+
+Now "Add a Configuration", with the following:
+@itemize @bullet
+@item
+Label: Guix
+
+@item
+Kernel:GRUB 2 (it's at the bottom!  This step is @b{IMPORTANT!})
+
+@item
+Block device assignment:
+
+@item
+@file{/dev/sda}: Guix
+
+@item
+@file{/dev/sdb}: swap
+
+@item
+Root device: @file{/dev/sda}
+
+@item
+Turn off all the filesystem/boot helpers
+@end itemize
+
+Now power it back up, picking the Debian configuration.  Once it's
+booted up, ssh in your server via @code{ssh
+root@@@var{<your-server-IP-here>}}. (You can find your server IP address in
+your Linode Summary section.) Now you can run the "install guix from
+@pxref{Binary Installation,,, guix, GNU Guix}" steps:
+
+@example
+sudo apt-get install gpg
+wget https://sv.gnu.org/people/viewgpg.php?user_id=15145 -qO - | gpg --import -
+wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh
+chmod +x guix-install.sh
+./guix-install.sh
+guix pull
+@end example
+
+Now it's time to write out a config for the server.  The key information
+is below. Save the resulting file as @file{guix-config.scm}.
+
+@lisp
+(use-modules (gnu)
+             (guix modules))
+(use-service-modules networking
+                     ssh)
+(use-package-modules admin
+                     certs
+                     package-management
+                     ssh
+                     tls)
+
+(operating-system
+  (host-name "my-server")
+  (timezone "America/New_York")
+  (locale "en_US.UTF-8")
+  ;; This goofy code will generate the grub.cfg
+  ;; without installing the grub bootloader on disk.
+  (bootloader (bootloader-configuration
+               (bootloader
+                (bootloader
+                 (inherit grub-bootloader)
+                 (installer #~(const #t))))))
+  (file-systems (cons (file-system
+                        (device "/dev/sda")
+                        (mount-point "/")
+                        (type "ext4"))
+                      %base-file-systems))
+
+
+  (swap-devices (list "/dev/sdb"))
+
+
+  (initrd-modules (cons "virtio_scsi"    ; Needed to find the disk
+                        %base-initrd-modules))
+
+  (users (cons (user-account
+                (name "janedoe")
+                (group "users")
+                ;; Adding the account to the "wheel" group
+                ;; makes it a sudoer.
+                (supplementary-groups '("wheel"))
+                (home-directory "/home/janedoe"))
+               %base-user-accounts))
+
+  (packages (cons* nss-certs            ;for HTTPS access
+                   openssh-sans-x
+                   %base-packages))
+
+  (services (cons*
+             (service dhcp-client-service-type)
+             (service openssh-service-type
+                      (openssh-configuration
+                       (openssh openssh-sans-x)
+                       (password-authentication? #f)
+                       (authorized-keys
+                        `(("janedoe" ,(local-file "janedoe_rsa.pub"))
+                          ("root" ,(local-file "janedoe_rsa.pub"))))))
+             %base-services)))
+@end lisp
+
+Replace the following fields in the above configuration:
+@lisp
+(host-name "my-server")       ; replace with your server name
+; if you chose a linode server outside the U.S., then
+; use tzselect to find a correct timezone string
+(timezone "America/New_York") ; if needed replace timezone
+(name "janedoe")              ; replace with your username
+("janedoe" ,(local-file "janedoe_rsa.pub")) ; replace with your ssh key
+("root" ,(local-file "janedoe_rsa.pub")) ; replace with your ssh key
+@end lisp
+
+The last line in the above example lets you log into the server as root
+and set the initial root password.  After you have done this, you may
+delete that line from your configuration and reconfigure to prevent root
+login.
+
+Save your ssh public key (eg: @file{~/.ssh/id_rsa.pub}) as
+@file{@var{<your-username-here>}_rsa.pub} and your
+@file{guix-config.scm} in the same directory.  In a new terminal run
+these commands.
+
+@example
+sftp root@@<remote server ip address>
+put /home/<username>/ssh/id_rsa.pub .
+put /path/to/linode/guix-config.scm .
+@end example
+
+In your first terminal, mount the guix drive:
+
+@example
+mkdir /mnt/guix
+mount /dev/sdc /mnt/guix
+@end example
+
+Due to the way we set things up above, we do not install GRUB
+completely.  Instead we install only our grub configuration file.  So we
+need to copy over some of the other GRUB stuff that is already there:
+
+@example
+mkdir -p /mnt/guix/boot/grub
+cp -r /boot/grub/* /mnt/guix/boot/grub/
+@end example
+
+Now initialize the Guix installation:
+
+@example
+guix system init guix-config.scm /mnt/guix
+@end example
+
+Ok, power it down!
+Now from the Linode console, select boot and select "Guix".
+
+Once it boots, you should be able to log in via SSH!  (The server config
+will have changed though.)  You may encounter an error like:
+
+@example
+$ ssh root@@<server ip address>
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
+Someone could be eavesdropping on you right now (man-in-the-middle attack)!
+It is also possible that a host key has just been changed.
+The fingerprint for the ECDSA key sent by the remote host is
+SHA256:0B+wp33w57AnKQuHCvQP0+ZdKaqYrI/kyU7CfVbS7R4.
+Please contact your system administrator.
+Add correct host key in /home/joshua/.ssh/known_hosts to get rid of this message.
+Offending ECDSA key in /home/joshua/.ssh/known_hosts:3
+ECDSA host key for 198.58.98.76 has changed and you have requested strict checking.
+Host key verification failed.
+@end example
+
+Either delete @file{~/.ssh/known_hosts} file, or delete the offending line
+starting with your server IP address.
+
+Be sure to set your password and root's password.
+
+@example
+ssh root@@<remote ip address>
+passwd  ; for the root password
+passwd <username> ; for the user password
+@end example
+
+You may not be able to run the above commands at this point.  If you
+have issues remotely logging into your linode box via SSH, then you may
+still need to set your root and user password initially by clicking on
+the ``Launch Console'' option in your linode.  Choose the ``Glish''
+instead of ``Weblish''.  Now you should be able to ssh into the machine.
+
+Horray!  At this point you can shut down the server, delete the
+Debian disk, and resize the Guix to the rest of the size.
+Congratulations!
+
+By the way, if you save it as a disk image right at this point, you'll
+have an easy time spinning up new Guix images!  You may need to
+down-size the Guix image to 6144MB, to save it as an image.  Then you
+can resize it again to the max size.
+
 @node Setting up a bind mount
 @section Setting up a bind mount
 
@@ -1707,6 +2051,68 @@ mount itself.
                 ))
 @end lisp
 
+@node Getting substitutes from Tor
+@section Getting substitutes from Tor
+
+Guix daemon can use a HTTP proxy to get substitutes, here we are
+configuring it to get them via Tor.
+
+@quotation Warning
+@emph{Not all} Guix daemon's traffic will go through Tor!  Only
+HTTP/HTTPS will get proxied; FTP, Git protocol, SSH, etc connections
+will still go through the clearnet.  Again, this configuration isn't
+foolproof some of your traffic won't get routed by Tor at all.  Use it
+at your own risk.
+
+Also note that the procedure described here applies only to package
+substitution. When you update your guix distribution with
+@command{guix pull}, you still need to use @command{torsocks} if
+you want to route the connection to guix's git repository servers
+through Tor.
+@end quotation
+
+Guix's substitute server is available as a Onion service, if you want
+to use it to get your substitutes through Tor configure your system as
+follow:
+
+@lisp
+(use-modules (gnu))
+(use-service-module base networking)
+
+(operating-system
+  …
+  (services
+    (cons
+      (service tor-service-type
+              (tor-configuration
+                (config-file (plain-file "tor-config"
+                                         "HTTPTunnelPort 127.0.0.1:9250"))))
+      (modify-services %base-services
+        (guix-service-type
+          config => (guix-configuration
+                      (inherit config)
+                      ;; ci.guix.gnu.org's Onion service
+                      (substitute-urls "https://bp7o7ckwlewr4slm.onion")
+                      (http-proxy "http://localhost:9250")))))))
+@end lisp
+
+This will keep a tor process running that provides a HTTP CONNECT tunnel
+which will be used by @command{guix-daemon}.  The daemon can use other
+protocols than HTTP(S) to get remote resources, request using those
+protocols won't go through Tor since we are only setting a HTTP tunnel
+here.  Note that @code{substitutes-urls} is using HTTPS and not HTTP or
+it won't work, that's a limitation of Tor's tunnel; you may want to use
+@command{privoxy} instead to avoid such limitations.
+
+If you don't want to always get substitutes through Tor but using it just
+some of the times, then skip the @code{guix-configuration}.  When you
+want to get a substitute from the Tor tunnel run:
+
+@example
+sudo herd set-http-proxy guix-daemon http://localhost:9250
+guix build --substitute-urls=https://bp7o7ckwlewr4slm.onion …
+@end example
+
 @c *********************************************************************
 @node Advanced package management
 @chapter Advanced package management
@@ -2105,6 +2511,130 @@ mkdir -p "$GUIX_EXTRA_PROFILES/my-project"
 It's safe to delete the Guix channel profile you've just installed with the
 channel specification, the project profile does not depend on it.
 
+@c *********************************************************************
+@node Environment management
+@chapter Environment management
+
+Guix provides multiple tools to manage environment.  This chapter
+demonstrate such utilities.
+
+@menu
+* Guix environment via direnv:: Setup Guix environment with direnv
+@end menu
+
+@node Guix environment via direnv
+@section Guix environment via direnv
+
+Guix provides a @samp{direnv} package, which could extend shell after
+directory change.  This tool could be used to prepare a pure Guix
+environment.
+
+The following example provides a shell function for @file{~/.direnvrc}
+file, which could be used from Guix Git repository in
+@file{~/src/guix/.envrc} file to setup a build environment similar to
+described in @pxref{Building from Git,,, guix, GNU Guix Reference
+Manual}.
+
+Create a @file{~/.direnvrc} with a Bash code:
+
+@example
+# Thanks <https://github.com/direnv/direnv/issues/73#issuecomment-152284914>
+export_function()
+@{
+  local name=$1
+  local alias_dir=$PWD/.direnv/aliases
+  mkdir -p "$alias_dir"
+  PATH_add "$alias_dir"
+  local target="$alias_dir/$name"
+  if declare -f "$name" >/dev/null; then
+    echo "#!$SHELL" > "$target"
+    declare -f "$name" >> "$target" 2>/dev/null
+    # Notice that we add shell variables to the function trigger.
+    echo "$name \$*" >> "$target"
+    chmod +x "$target"
+  fi
+@}
+
+use_guix()
+@{
+    # Set GitHub token.
+    export GUIX_GITHUB_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+
+    # Unset 'GUIX_PACKAGE_PATH'.
+    export GUIX_PACKAGE_PATH=""
+
+    # Recreate a garbage collector root.
+    gcroots="$HOME/.config/guix/gcroots"
+    mkdir -p "$gcroots"
+    gcroot="$gcroots/guix"
+    if [ -L "$gcroot" ]
+    then
+        rm -v "$gcroot"
+    fi
+
+    # Miscellaneous packages.
+    PACKAGES_MAINTENANCE=(
+        direnv
+        git
+        git:send-email
+        git-cal
+        gnupg
+        guile-colorized
+        guile-readline
+        less
+        ncurses
+        openssh
+        xdot
+    )
+
+    # Environment packages.
+    PACKAGES=(help2man guile-sqlite3 guile-gcrypt)
+
+    # Thanks <https://lists.gnu.org/archive/html/guix-devel/2016-09/msg00859.html>
+    eval "$(guix environment --search-paths --root="$gcroot" --pure guix --ad-hoc $@{PACKAGES[@@]@} $@{PACKAGES_MAINTENANCE[@@]@} "$@@")"
+
+    # Predefine configure flags.
+    configure()
+    @{
+        ./configure --localstatedir=/var --prefix=
+    @}
+    export_function configure
+
+    # Run make and optionally build something.
+    build()
+    @{
+        make -j 2
+        if [ $# -gt 0 ]
+        then
+            ./pre-inst-env guix build "$@@"
+        fi
+    @}
+    export_function build
+
+    # Predefine push Git command.
+    push()
+    @{
+        git push --set-upstream origin
+    @}
+    export_function push
+
+    clear                        # Clean up the screen.
+    git-cal --author='Your Name' # Show contributions calendar.
+
+    # Show commands help.
+    echo "
+build          build a package or just a project if no argument provided
+configure      run ./configure with predefined parameters
+push           push to upstream Git repository
+"
+@}
+@end example
+
+Every project containing @file{.envrc} with a string @code{use guix}
+will have predefined environment variables and procedures.
+
+Run @command{direnv allow} to setup the environment for the first time.
+
 @c *********************************************************************
 @node Acknowledgments
 @chapter Acknowledgments