Skip to content
Snippets Groups Projects
guix.texi 716 KiB
Newer Older
  • Learn to ignore specific revisions
  • @command{mkfs.ext4} and related commands.  So, assuming the target root
    partition lives at @file{/dev/sda1}, a file system with the label
    @code{my-root} can be created with:
    
    @example
    mkfs.ext4 -L my-root /dev/sda1
    @end example
    
    @cindex encrypted disk
    If you are instead planning to encrypt the root partition, you can use
    the Cryptsetup/LUKS utilities to do that (see @inlinefmtifelse{html,
    @uref{https://linux.die.net/man/8/cryptsetup, @code{man cryptsetup}},
    @code{man cryptsetup}} for more information.)  Assuming you want to
    store the root partition on @file{/dev/sda1}, the command sequence would
    be along these lines:
    
    @example
    cryptsetup luksFormat /dev/sda1
    cryptsetup open --type luks /dev/sda1 my-partition
    mkfs.ext4 -L my-root /dev/mapper/my-partition
    @end example
    
    Once that is done, mount the target root partition under @file{/mnt}
    
    with a command like (again, assuming @code{my-root} is the label of the
    root partition):
    
    mount LABEL=my-root /mnt
    
    Also mount any other partitions you would like to use on the target
    system relative to this path.  If you have @file{/boot} on a separate
    partition for example, mount it at @file{/mnt/boot} now so it is found
    by @code{guix system init} afterwards.
    
    
    Finally, if you plan to use one or more swap partitions (@pxref{Memory
    Concepts, swap space,, libc, The GNU C Library Reference Manual}), make
    sure to initialize them with @command{mkswap}.  Assuming you have one
    swap partition on @file{/dev/sda2}, you would run:
    
    @example
    mkswap /dev/sda2
    
    swapon /dev/sda2
    
    Alternatively, you may use a swap file.  For example, assuming that in
    the new system you want to use the file @file{/swapfile} as a swap file,
    you would run@footnote{This example will work for many types of file
    systems (e.g., ext4).  However, for copy-on-write file systems (e.g.,
    btrfs), the required steps may be different.  For details, see the
    manual pages for @command{mkswap} and @command{swapon}.}:
    
    @example
    # This is 10 GiB of swap space.  Adjust "count" to change the size.
    dd if=/dev/zero of=/mnt/swapfile bs=1MiB count=10240
    # For security, make the file readable and writable only by root.
    chmod 600 /mnt/swapfile
    mkswap /mnt/swapfile
    swapon /mnt/swapfile
    @end example
    
    Note that if you have encrypted the root partition and created a swap
    file in its file system as described above, then the encryption also
    protects the swap file, just like any other file in that file system.
    
    
    @node Proceeding with the Installation
    @subsection Proceeding with the Installation
    
    With the target partitions ready and the target root mounted on
    @file{/mnt}, we're ready to go.  First, run:
    
    @example
    herd start cow-store /mnt
    @end example
    
    This makes @file{/gnu/store} copy-on-write, such that packages added to it
    during the installation phase are written to the target disk on @file{/mnt}
    rather than kept in memory.  This is necessary because the first phase of
    the @command{guix system init} command (see below) entails downloads or
    builds to @file{/gnu/store} which, initially, is an in-memory file system.
    
    Next, you have to edit a file and
    
    provide the declaration of the operating system to be installed.  To
    
    that end, the installation system comes with three text editors: GNU nano
    (@pxref{Top,,, nano, GNU nano Manual}), GNU Zile (an Emacs clone), and
    nvi (a clone of the original BSD @command{vi} editor).
    
    We strongly recommend storing that file on the target root file system, say,
    as @file{/mnt/etc/config.scm}.  Failing to do that, you will have lost your
    configuration file once you have rebooted into the newly-installed system.
    
    @xref{Using the Configuration System}, for an overview of the
    configuration file.  The example configurations discussed in that
    section are available under @file{/etc/configuration} in the
    installation image.  Thus, to get started with a system configuration
    providing a graphical display server (a ``desktop'' system), you can run
    something along these lines:
    
    @example
    # mkdir /mnt/etc
    # cp /etc/configuration/desktop.scm /mnt/etc/config.scm
    # zile /mnt/etc/config.scm
    @end example
    
    You should pay attention to what your configuration file contains, and
    in particular:
    
    @itemize
    @item
    
    Make sure the @code{grub-configuration} form refers to the target you
    want to install GRUB on.  It should mention @code{grub-bootloader} if
    you are installing GRUB in the legacy way, or @code{grub-efi-bootloader}
    for newer UEFI systems.  For legacy systems, the @code{target} field
    names a device, like @code{/dev/sda}; for UEFI systems it names a path
    to a mounted EFI partition, like @code{/boot/efi}, and do make sure the
    path is actually mounted.
    
    
    @item
    Be sure that your partition labels match the value of their respective
    @code{device} fields in your @code{file-system} configuration, assuming
    your @code{file-system} configuration sets the value of @code{title} to
    @code{'label}.
    
    
    @item
    If there are encrypted or RAID partitions, make sure to add a
    @code{mapped-devices} field to describe them (@pxref{Mapped Devices}).
    
    Once you are done preparing the configuration file, the new system must
    be initialized (remember that the target root file system is mounted
    under @file{/mnt}):
    
    
    @example
    guix system init /mnt/etc/config.scm /mnt
    @end example
    
    @noindent
    
    This copies all the necessary files and installs GRUB on
    
    @file{/dev/sdX}, unless you pass the @option{--no-bootloader} option.  For
    
    more information, @pxref{Invoking guix system}.  This command may trigger
    
    downloads or builds of missing packages, which can take some time.
    
    
    Once that command has completed---and hopefully succeeded!---you can run
    @command{reboot} and boot into the new system.  The @code{root} password
    in the new system is initially empty; other users' passwords need to be
    initialized by running the @command{passwd} command as @code{root},
    unless your configuration specifies otherwise
    (@pxref{user-account-password, user account passwords}).
    
    
    @cindex upgrading GuixSD
    From then on, you can update GuixSD whenever you want by running
    @command{guix pull} as @code{root} (@pxref{Invoking guix pull}), and
    then running @command{guix system reconfigure} to build a new system
    generation with the latest packages and services (@pxref{Invoking guix
    system}).  We recommend doing that regularly so that your system
    includes the latest security updates (@pxref{Security Updates}).
    
    
    Join us on @code{#guix} on the Freenode IRC network or on
    
    @file{guix-devel@@gnu.org} to share your experience---good or not so
    good.
    
    
    @node Installing GuixSD in a VM
    @subsection Installing GuixSD in a Virtual Machine
    
    @cindex virtual machine, GuixSD installation
    
    @cindex virtual private server (VPS)
    @cindex VPS (virtual private server)
    If you'd like to install GuixSD in a virtual machine (VM) or on a
    virtual private server (VPS) rather than on your beloved machine, this
    section is for you.
    
    
    To boot a @uref{http://qemu.org/,QEMU} VM for installing GuixSD in a
    disk image, follow these steps:
    
    @enumerate
    @item
    
    First, retrieve and decompress the GuixSD installation image as
    described previously (@pxref{USB Stick Installation}).
    
    
    @item
    Create a disk image that will hold the installed system.  To make a
    qcow2-formatted disk image, use the @command{qemu-img} command:
    
    @example
    
    qemu-img create -f qcow2 guixsd.img 50G
    
    The resulting file will be much smaller than 50 GB (typically less than
    1 MB), but it will grow as the virtualized storage device is filled up.
    
    
    @item
    Boot the USB installation image in an VM:
    
    @example
    qemu-system-x86_64 -m 1024 -smp 1 \
    
      -net user -net nic,model=virtio -boot menu=on \
    
      -drive file=guixsd-install-@value{VERSION}.@var{system} \
    
      -drive file=guixsd.img
    
    The ordering of the drives matters.
    
    
    In the VM console, quickly press the @kbd{F12} key to enter the boot
    menu.  Then press the @kbd{2} key and the @kbd{RET} key to validate your
    selection.
    
    @item
    You're now root in the VM, proceed with the installation process.
    @xref{Preparing for Installation}, and follow the instructions.
    @end enumerate
    
    Once installation is complete, you can boot the system that's on your
    @file{guixsd.img} image.  @xref{Running GuixSD in a VM}, for how to do
    that.
    
    
    @node Building the Installation Image
    
    @subsection Building the Installation Image
    
    
    @cindex installation image
    
    The installation image described above was built using the @command{guix
    system} command, specifically:
    
    @example
    
    guix system disk-image gnu/system/install.scm
    
    Have a look at @file{gnu/system/install.scm} in the source tree,
    and see also @ref{Invoking guix system} for more information
    
    about the installation image.
    
    
    @node System Configuration
    @section System Configuration
    
    @cindex system configuration
    
    The Guix System Distribution supports a consistent whole-system configuration
    
    mechanism.  By that we mean that all aspects of the global system
    configuration---such as the available system services, timezone and
    locale settings, user accounts---are declared in a single place.  Such
    a @dfn{system configuration} can be @dfn{instantiated}---i.e., effected.
    
    One of the advantages of putting all the system configuration under the
    control of Guix is that it supports transactional system upgrades, and
    
    makes it possible to roll back to a previous system instantiation,
    
    should something go wrong with the new one (@pxref{Features}).  Another
    
    advantage is that it makes it easy to replicate the exact same configuration
    
    across different machines, or at different points in time, without
    having to resort to additional administration tools layered on top of
    
    the own tools of the system.
    
    @c Yes, we're talking of Puppet, Chef, & co. here.  ↑
    
    This section describes this mechanism.  First we focus on the system
    administrator's viewpoint---explaining how the system is configured and
    instantiated.  Then we show how this mechanism can be extended, for
    instance to support new system services.
    
    @menu
    * Using the Configuration System::  Customizing your GNU system.
    
    * operating-system Reference::  Detail of operating-system declarations.
    
    * File Systems::                Configuring file system mounts.
    
    * Mapped Devices::              Block device extra processing.
    
    * User Accounts::               Specifying user accounts.
    
    * Locales::                     Language and cultural convention settings.
    
    * Services::                    Specifying system services.
    
    * Setuid Programs::             Programs running with root privileges.
    
    * X.509 Certificates::          Authenticating HTTPS servers.
    
    * Name Service Switch::         Configuring libc's name service switch.
    
    * Initial RAM Disk::            Linux-Libre bootstrapping.
    
    * Bootloader Configuration::    Configuring the boot loader.
    
    * Invoking guix system::        Instantiating a system configuration.
    
    * Running GuixSD in a VM::      How to run GuixSD in a virtual machine.
    
    * Defining Services::           Adding new service definitions.
    @end menu
    
    @node Using the Configuration System
    @subsection Using the Configuration System
    
    The operating system is configured by providing an
    @code{operating-system} declaration in a file that can then be passed to
    the @command{guix system} command (@pxref{Invoking guix system}).  A
    simple setup, with the default system services, the default Linux-Libre
    kernel, initial RAM disk, and boot loader looks like this:
    
    @findex operating-system
    @lisp
    
    @include os-config-bare-bones.texi
    
    This example should be self-describing.  Some of the fields defined
    above, such as @code{host-name} and @code{bootloader}, are mandatory.
    Others, such as @code{packages} and @code{services}, can be omitted, in
    which case they get a default value.
    
    Below we discuss the effect of some of the most important fields
    (@pxref{operating-system Reference}, for details about all the available
    fields), and how to @dfn{instantiate} the operating system using
    @command{guix system}.
    
    @unnumberedsubsubsec Globally-Visible Packages
    
    
    @vindex %base-packages
    
    The @code{packages} field lists packages that will be globally visible
    on the system, for all user accounts---i.e., in every user's @code{PATH}
    environment variable---in addition to the per-user profiles
    (@pxref{Invoking guix package}).  The @var{%base-packages} variable
    provides all the tools one would expect for basic user and administrator
    tasks---including the GNU Core Utilities, the GNU Networking Utilities,
    the GNU Zile lightweight text editor, @command{find}, @command{grep},
    
    etc.  The example above adds GNU@tie{}Screen and OpenSSH to those,
    taken from the @code{(gnu packages screen)} and @code{(gnu packages ssh)}
    modules (@pxref{Package Modules}).  The
    
    @code{(list package output)} syntax can be used to add a specific output
    of a package:
    
    @lisp
    (use-modules (gnu packages))
    (use-modules (gnu packages dns))
    
    (operating-system
      ;; ...
      (packages (cons (list bind "utils")
                      %base-packages)))
    @end lisp
    
    @findex specification->package
    Referring to packages by variable name, like @var{tcpdump} above, has
    the advantage of being unambiguous; it also allows typos and such to be
    diagnosed right away as ``unbound variables''.  The downside is that one
    needs to know which module defines which package, and to augment the
    @code{use-package-modules} line accordingly.  To avoid that, one can use
    the @code{specification->package} procedure of the @code{(gnu packages)}
    module, which returns the best package for a given name or name and
    version:
    
    @lisp
    (use-modules (gnu packages))
    
    (operating-system
      ;; ...
      (packages (append (map specification->package
    
                             '("tcpdump" "htop" "gnupg@@2.0"))
    
                        %base-packages)))
    @end lisp
    
    
    @unnumberedsubsubsec System Services
    
    
    @cindex services
    
    @vindex %base-services
    The @code{services} field lists @dfn{system services} to be made
    available when the system starts (@pxref{Services}).
    The @code{operating-system} declaration above specifies that, in
    addition to the basic services, we want the @command{lshd} secure shell
    
    daemon listening on port 2222 (@pxref{Networking Services,
    @code{lsh-service}}).  Under the hood,
    
    @code{lsh-service} arranges so that @code{lshd} is started with the
    right command-line options, possibly with supporting configuration files
    
    generated as needed (@pxref{Defining Services}).
    
    @cindex customization, of services
    @findex modify-services
    Occasionally, instead of using the base services as is, you will want to
    
    customize them.  To do this, use @code{modify-services} (@pxref{Service
    Reference, @code{modify-services}}) to modify the list.
    
    For example, suppose you want to modify @code{guix-daemon} and Mingetty
    (the console log-in) in the @var{%base-services} list (@pxref{Base
    Services, @code{%base-services}}).  To do that, you can write the
    following in your operating system declaration:
    
    (define %my-services
      ;; My very own list of services.
      (modify-services %base-services
        (guix-service-type config =>
                           (guix-configuration
                            (inherit config)
                            (use-substitutes? #f)
                            (extra-options '("--gc-keep-derivations"))))
        (mingetty-service-type config =>
                               (mingetty-configuration
    
                                (inherit config)))))
    
    
    (operating-system
      ;; @dots{}
      (services %my-services))
    
    This changes the configuration---i.e., the service parameters---of the
    @code{guix-service-type} instance, and that of all the
    @code{mingetty-service-type} instances in the @var{%base-services} list.
    Observe how this is accomplished: first, we arrange for the original
    configuration to be bound to the identifier @code{config} in the
    @var{body}, and then we write the @var{body} so that it evaluates to the
    desired configuration.  In particular, notice how we use @code{inherit}
    to create a new configuration which has the same values as the old
    configuration, but with a few modifications.
    
    @cindex encrypted disk
    The configuration for a typical ``desktop'' usage, with an encrypted
    root partition, the X11 display
    
    server, GNOME and Xfce (users can choose which of these desktop
    environments to use at the log-in screen by pressing @kbd{F1}), network
    management, power management, and more, would look like this:
    
    A graphical UEFI system with a choice of lightweight window managers
    
    instead of full-blown desktop environments would look like this:
    
    @lisp
    @include os-config-lightweight-desktop.texi
    @end lisp
    
    
    @xref{Desktop Services}, for the exact list of services provided by
    
    @var{%desktop-services}.  @xref{X.509 Certificates}, for background
    information about the @code{nss-certs} package that is used here.
    
    Again, @var{%desktop-services} is just a list of service objects.  If
    you want to remove services from there, you can do so using the
    procedures for list filtering (@pxref{SRFI-1 Filtering and
    Partitioning,,, guile, GNU Guile Reference Manual}).  For instance, the
    following expression returns a list that contains all the services in
    @var{%desktop-services} minus the Avahi service:
    
    @example
    (remove (lambda (service)
              (eq? (service-kind service) avahi-service-type))
            %desktop-services)
    @end example
    
    @unnumberedsubsubsec Instantiating the System
    
    Assuming the @code{operating-system} declaration
    is stored in the @file{my-system-config.scm}
    
    file, the @command{guix system reconfigure my-system-config.scm} command
    instantiates that configuration, and makes it the default GRUB boot
    
    entry (@pxref{Invoking guix system}).
    
    
    The normal way to change the system configuration is by updating this
    
    file and re-running @command{guix system reconfigure}.  One should never
    
    have to touch files in @file{/etc} or to run commands that modify the
    
    system state such as @command{useradd} or @command{grub-install}.  In
    fact, you must avoid that since that would not only void your warranty
    but also prevent you from rolling back to previous versions of your
    system, should you ever need to.
    
    @cindex roll-back, of the operating system
    Speaking of roll-back, each time you run @command{guix system
    reconfigure}, a new @dfn{generation} of the system is created---without
    modifying or deleting previous generations.  Old system generations get
    
    an entry in the bootloader boot menu, allowing you to boot them in case
    
    something went wrong with the latest generation.  Reassuring, no?  The
    @command{guix system list-generations} command lists the system
    
    generations available on disk.  It is also possible to roll back the
    system via the commands @command{guix system roll-back} and
    @command{guix system switch-generation}.
    
    Although the command @command{guix system reconfigure} will not modify
    previous generations, must take care when the current generation is not
    the latest (e.g., after invoking @command{guix system roll-back}), since
    the operation might overwrite a later generation (@pxref{Invoking guix
    system}).
    
    @unnumberedsubsubsec The Programming Interface
    
    
    At the Scheme level, the bulk of an @code{operating-system} declaration
    is instantiated with the following monadic procedure (@pxref{The Store
    Monad}):
    
    @deffn {Monadic Procedure} operating-system-derivation os
    Return a derivation that builds @var{os}, an @code{operating-system}
    object (@pxref{Derivations}).
    
    The output of the derivation is a single directory that refers to all
    the packages, configuration files, and other supporting files needed to
    instantiate @var{os}.
    @end deffn
    
    This procedure is provided by the @code{(gnu system)} module.  Along
    with @code{(gnu services)} (@pxref{Services}), this module contains the
    guts of GuixSD.  Make sure to visit it!
    
    
    
    @node operating-system Reference
    @subsection @code{operating-system} Reference
    
    This section summarizes all the options available in
    @code{operating-system} declarations (@pxref{Using the Configuration
    System}).
    
    @deftp {Data Type} operating-system
    This is the data type representing an operating system configuration.
    By that, we mean all the global system configuration, not per-user
    configuration (@pxref{Using the Configuration System}).
    
    @table @asis
    @item @code{kernel} (default: @var{linux-libre})
    
    The package object of the operating system kernel to use@footnote{Currently
    
    only the Linux-libre kernel is supported.  In the future, it will be
    possible to use the GNU@tie{}Hurd.}.
    
    
    @item @code{kernel-arguments} (default: @code{'()})
    List of strings or gexps representing additional arguments to pass on
    
    the command-line of the kernel---e.g., @code{("console=ttyS0")}.
    
    @item @code{bootloader}
    
    The system bootloader configuration object.  @xref{Bootloader Configuration}.
    
    
    @item @code{initrd} (default: @code{base-initrd})
    
    @cindex initrd
    @cindex initial RAM disk
    
    A two-argument monadic procedure that returns an initial RAM disk for
    the Linux kernel.  @xref{Initial RAM Disk}.
    
    
    @item @code{firmware} (default: @var{%base-firmware})
    @cindex firmware
    List of firmware packages loadable by the operating system kernel.
    
    
    The default includes firmware needed for Atheros- and Broadcom-based
    WiFi devices (Linux-libre modules @code{ath9k} and @code{b43-open},
    respectively).  @xref{Hardware Considerations}, for more info on
    supported hardware.
    
    @item @code{host-name}
    The host name.
    
    @item @code{hosts-file}
    @cindex hosts file
    
    A file-like object (@pxref{G-Expressions, file-like objects}) for use as
    
    @file{/etc/hosts} (@pxref{Host Names,,, libc, The GNU C Library
    
    Reference Manual}).  The default is a file with entries for
    
    @code{localhost} and @var{host-name}.
    
    @item @code{mapped-devices} (default: @code{'()})
    A list of mapped devices.  @xref{Mapped Devices}.
    
    @item @code{file-systems}
    A list of file systems.  @xref{File Systems}.
    
    @item @code{swap-devices} (default: @code{'()})
    @cindex swap devices
    
    A list of strings identifying devices or files to be used for ``swap
    space'' (@pxref{Memory Concepts,,, libc, The GNU C Library Reference
    Manual}).  For example, @code{'("/dev/sda3")} or @code{'("/swapfile")}.
    It is possible to specify a swap file in a file system on a mapped
    device, provided that the necessary device mapping and file system are
    also specified.  @xref{Mapped Devices} and @ref{File Systems}.
    
    @item @code{users} (default: @code{%base-user-accounts})
    
    @itemx @code{groups} (default: @var{%base-groups})
    List of user accounts and groups.  @xref{User Accounts}.
    
    @item @code{skeletons} (default: @code{(default-skeletons)})
    
    A list target file name/file-like object tuples (@pxref{G-Expressions,
    file-like objects}).  These are the skeleton files that will be added to
    the home directory of newly-created user accounts.
    
    
    For instance, a valid value may look like this:
    
    @example
    
    `((".bashrc" ,(plain-file "bashrc" "echo Hello\n"))
      (".guile" ,(plain-file "guile"
                             "(use-modules (ice-9 readline))
                              (activate-readline)")))
    
    @end example
    
    @item @code{issue} (default: @var{%default-issue})
    A string denoting the contents of the @file{/etc/issue} file, which is
    
    displayed when users log in on a text console.
    
    
    @item @code{packages} (default: @var{%base-packages})
    The set of packages installed in the global profile, which is accessible
    at @file{/run/current-system/profile}.
    
    
    The default set includes core utilities and it is good practice to
    
    install non-core utilities in user profiles (@pxref{Invoking guix
    package}).
    
    @item @code{timezone}
    A timezone identifying string---e.g., @code{"Europe/Paris"}.
    
    
    You can run the @command{tzselect} command to find out which timezone
    string corresponds to your region.  Choosing an invalid timezone name
    causes @command{guix system} to fail.
    
    
    @item @code{locale} (default: @code{"en_US.utf8"})
    The name of the default locale (@pxref{Locale Names,,, libc, The GNU C
    Library Reference Manual}).  @xref{Locales}, for more information.
    
    @item @code{locale-definitions} (default: @var{%default-locale-definitions})
    The list of locale definitions to be compiled and that may be used at
    run time.  @xref{Locales}.
    
    @item @code{locale-libcs} (default: @code{(list @var{glibc})})
    The list of GNU@tie{}libc packages whose locale data and tools are used
    to build the locale definitions.  @xref{Locales}, for compatibility
    considerations that justify this option.
    
    
    @item @code{name-service-switch} (default: @var{%default-nss})
    
    Configuration of the libc name service switch (NSS)---a
    
    @code{<name-service-switch>} object.  @xref{Name Service Switch}, for
    details.
    
    
    @item @code{services} (default: @var{%base-services})
    
    A list of service objects denoting system services.  @xref{Services}.
    
    
    @item @code{pam-services} (default: @code{(base-pam-services)})
    @cindex PAM
    @cindex pluggable authentication modules
    Linux @dfn{pluggable authentication module} (PAM) services.
    @c FIXME: Add xref to PAM services section.
    
    @item @code{setuid-programs} (default: @var{%setuid-programs})
    List of string-valued G-expressions denoting setuid programs.
    @xref{Setuid Programs}.
    
    
    @item @code{sudoers-file} (default: @var{%sudoers-specification})
    @cindex sudoers file
    
    The contents of the @file{/etc/sudoers} file as a file-like object
    (@pxref{G-Expressions, @code{local-file} and @code{plain-file}}).
    
    
    This file specifies which users can use the @command{sudo} command, what
    they are allowed to do, and what privileges they may gain.  The default
    is that only @code{root} and members of the @code{wheel} group may use
    @code{sudo}.
    
    @end table
    @end deftp
    
    
    @node File Systems
    @subsection File Systems
    
    The list of file systems to be mounted is specified in the
    
    @code{file-systems} field of the operating system declaration
    
    (@pxref{Using the Configuration System}).  Each file system is declared
    using the @code{file-system} form, like this:
    
    (file-system
      (mount-point "/home")
      (device "/dev/sda3")
      (type "ext4"))
    
    As usual, some of the fields are mandatory---those shown in the example
    above---while others can be omitted.  These are described below.
    
    @deftp {Data Type} file-system
    Objects of this type represent file systems to be mounted.  They
    contain the following members:
    
    @table @asis
    @item @code{type}
    This is a string specifying the type of the file system---e.g.,
    @code{"ext4"}.
    
    @item @code{mount-point}
    This designates the place where the file system is to be mounted.
    
    @item @code{device}
    This names the ``source'' of the file system.  By default it is the name
    of a node under @file{/dev}, but its meaning depends on the @code{title}
    field described below.
    
    @item @code{title} (default: @code{'device})
    This is a symbol that specifies how the @code{device} field is to be
    interpreted.
    
    When it is the symbol @code{device}, then the @code{device} field is
    interpreted as a file name; when it is @code{label}, then @code{device}
    is interpreted as a partition label name; when it is @code{uuid},
    @code{device} is interpreted as a partition unique identifier (UUID).
    
    UUIDs may be converted from their string representation (as shown by the
    
    @command{tune2fs -l} command) using the @code{uuid} form@footnote{The
    @code{uuid} form expects 16-byte UUIDs as defined in
    @uref{https://tools.ietf.org/html/rfc4122, RFC@tie{}4122}.  This is the
    form of UUID used by the ext2 family of file systems and others, but it
    is different from ``UUIDs'' found in FAT file systems, for instance.},
    like this:
    
    
    @example
    (file-system
      (mount-point "/home")
      (type "ext4")
      (title 'uuid)
      (device (uuid "4dab5feb-d176-45de-b287-9b0a6e4c01cb")))
    @end example
    
    
    The @code{label} and @code{uuid} options offer a way to refer to disk
    
    partitions without having to hard-code their actual device
    name@footnote{Note that, while it is tempting to use
    @file{/dev/disk/by-uuid} and similar device names to achieve the same
    result, this is not recommended: These special device nodes are created
    by the udev daemon and may be unavailable at the time the device is
    mounted.}.
    
    However, when the source of a file system is a mapped device (@pxref{Mapped
    
    Devices}), its @code{device} field @emph{must} refer to the mapped
    device name---e.g., @file{/dev/mapper/root-partition}---and consequently
    @code{title} must be set to @code{'device}.  This is required so that
    the system knows that mounting the file system depends on having the
    corresponding device mapping established.
    
    
    @item @code{flags} (default: @code{'()})
    This is a list of symbols denoting mount flags.  Recognized flags
    
    include @code{read-only}, @code{bind-mount}, @code{no-dev} (disallow
    access to special files), @code{no-suid} (ignore setuid and setgid
    bits), and @code{no-exec} (disallow program execution.)
    
    @item @code{options} (default: @code{#f})
    This is either @code{#f}, or a string denoting mount options.
    
    @item @code{mount?} (default: @code{#t})
    This value indicates whether to automatically mount the file system when
    the system is brought up.  When set to @code{#f}, the file system gets
    an entry in @file{/etc/fstab} (read by the @command{mount} command) but
    is not automatically mounted.
    
    
    @item @code{needed-for-boot?} (default: @code{#f})
    This Boolean value indicates whether the file system is needed when
    booting.  If that is true, then the file system is mounted when the
    initial RAM disk (initrd) is loaded.  This is always the case, for
    instance, for the root file system.
    
    @item @code{check?} (default: @code{#t})
    This Boolean indicates whether the file system needs to be checked for
    errors before being mounted.
    
    @item @code{create-mount-point?} (default: @code{#f})
    When true, the mount point is created if it does not exist yet.
    
    
    @item @code{dependencies} (default: @code{'()})
    
    This is a list of @code{<file-system>} or @code{<mapped-device>} objects
    representing file systems that must be mounted or mapped devices that
    must be opened before (and unmounted or closed after) this one.
    
    
    As an example, consider a hierarchy of mounts: @file{/sys/fs/cgroup} is
    a dependency of @file{/sys/fs/cgroup/cpu} and
    @file{/sys/fs/cgroup/memory}.
    
    
    Another example is a file system that depends on a mapped device, for
    example for an encrypted partition (@pxref{Mapped Devices}).
    
    @end table
    @end deftp
    
    The @code{(gnu system file-systems)} exports the following useful
    variables.
    
    @defvr {Scheme Variable} %base-file-systems
    These are essential file systems that are required on normal systems,
    
    such as @var{%pseudo-terminal-file-system} and @var{%immutable-store} (see
    
    below.)  Operating system declarations should always contain at least
    these.
    
    @defvr {Scheme Variable} %pseudo-terminal-file-system
    This is the file system to be mounted as @file{/dev/pts}.  It supports
    @dfn{pseudo-terminals} created @i{via} @code{openpty} and similar
    functions (@pxref{Pseudo-Terminals,,, libc, The GNU C Library Reference
    Manual}).  Pseudo-terminals are used by terminal emulators such as
    @command{xterm}.
    @end defvr
    
    
    Ludovic Courtès's avatar
    Ludovic Courtès committed
    @defvr {Scheme Variable} %shared-memory-file-system
    This file system is mounted as @file{/dev/shm} and is used to support
    memory sharing across processes (@pxref{Memory-mapped I/O,
    @code{shm_open},, libc, The GNU C Library Reference Manual}).
    @end defvr
    
    
    @defvr {Scheme Variable} %immutable-store
    This file system performs a read-only ``bind mount'' of
    @file{/gnu/store}, making it read-only for all the users including
    @code{root}.  This prevents against accidental modification by software
    running as @code{root} or by system administrators.
    
    The daemon itself is still able to write to the store: it remounts it
    read-write in its own ``name space.''
    @end defvr
    
    
    @defvr {Scheme Variable} %binary-format-file-system
    The @code{binfmt_misc} file system, which allows handling of arbitrary
    executable file types to be delegated to user space.  This requires the
    @code{binfmt.ko} kernel module to be loaded.
    @end defvr
    
    @defvr {Scheme Variable} %fuse-control-file-system
    The @code{fusectl} file system, which allows unprivileged users to mount
    and unmount user-space FUSE file systems.  This requires the
    @code{fuse.ko} kernel module to be loaded.
    @end defvr
    
    
    @node Mapped Devices
    @subsection Mapped Devices
    
    @cindex device mapping
    @cindex mapped devices
    The Linux kernel has a notion of @dfn{device mapping}: a block device,
    such as a hard disk partition, can be @dfn{mapped} into another device,
    
    usually in @code{/dev/mapper/},
    
    with additional processing over the data that flows through
    it@footnote{Note that the GNU@tie{}Hurd makes no difference between the
    concept of a ``mapped device'' and that of a file system: both boil down
    to @emph{translating} input/output operations made on a file to
    operations on its backing store.  Thus, the Hurd implements mapped
    devices, like file systems, using the generic @dfn{translator} mechanism
    (@pxref{Translators,,, hurd, The GNU Hurd Reference Manual}).}.  A
    typical example is encryption device mapping: all writes to the mapped
    device are encrypted, and all reads are deciphered, transparently.
    
    Guix extends this notion by considering any device or set of devices that
    are @dfn{transformed} in some way to create a new device; for instance,
    RAID devices are obtained by @dfn{assembling} several other devices, such
    as hard disks or partitions, into a new one that behaves as one partition.
    Other examples, not yet implemented, are LVM logical volumes.
    
    Mapped devices are declared using the @code{mapped-device} form,
    defined as follows; for examples, see below.
    
    
    @deftp {Data Type} mapped-device
    Objects of this type represent device mappings that will be made when
    the system boots up.
    
    
    This is either a string specifying the name of the block device to be mapped,
    such as @code{"/dev/sda3"}, or a list of such strings when several devices
    need to be assembled for creating a new one.
    
    This string specifies the name of the resulting mapped device.  For
    kernel mappers such as encrypted devices of type @code{luks-device-mapping},
    specifying @code{"my-partition"} leads to the creation of
    
    the @code{"/dev/mapper/my-partition"} device.
    
    For RAID devices of type @code{raid-device-mapping}, the full device name
    such as @code{"/dev/md0"} needs to be given.
    
    This must be a @code{mapped-device-kind} object, which specifies how
    @var{source} is mapped to @var{target}.
    @end table
    @end deftp
    
    @defvr {Scheme Variable} luks-device-mapping
    This defines LUKS block device encryption using the @command{cryptsetup}
    
    command from the package with the same name.  It relies on the
    
    @code{dm-crypt} Linux kernel module.
    @end defvr
    
    
    @defvr {Scheme Variable} raid-device-mapping
    This defines a RAID device, which is assembled using the @code{mdadm}
    command from the package with the same name.  It requires a Linux kernel
    module for the appropriate RAID level to be loaded, such as @code{raid456}
    for RAID-4, RAID-5 or RAID-6, or @code{raid10} for RAID-10.
    @end defvr
    
    @cindex disk encryption
    @cindex LUKS
    The following example specifies a mapping from @file{/dev/sda3} to
    @file{/dev/mapper/home} using LUKS---the
    
    @url{https://gitlab.com/cryptsetup/cryptsetup,Linux Unified Key Setup}, a
    
    standard mechanism for disk encryption.
    The @file{/dev/mapper/home}
    device can then be used as the @code{device} of a @code{file-system}
    declaration (@pxref{File Systems}).
    
    @example
    (mapped-device
      (source "/dev/sda3")
      (target "home")
      (type luks-device-mapping))
    @end example
    
    Alternatively, to become independent of device numbering, one may obtain
    the LUKS UUID (@dfn{unique identifier}) of the source device by a
    command like:
    
    @example
    cryptsetup luksUUID /dev/sda3
    @end example
    
    and use it as follows:
    
    @example
    (mapped-device
      (source (uuid "cb67fc72-0d54-4c88-9d4b-b225f30b0f44"))
      (target "home")
      (type luks-device-mapping))
    @end example
    
    
    @cindex swap encryption
    It is also desirable to encrypt swap space, since swap space may contain
    sensitive data.  One way to accomplish that is to use a swap file in a
    file system on a device mapped via LUKS encryption.  In this way, the
    swap file is encrypted because the entire device is encrypted.
    @xref{Preparing for Installation,,Disk Partitioning}, for an example.
    
    
    A RAID device formed of the partitions @file{/dev/sda1} and @file{/dev/sdb1}
    may be declared as follows:
    
    @example
    (mapped-device
      (source (list "/dev/sda1" "/dev/sdb1"))
      (target "/dev/md0")
      (type raid-device-mapping))
    @end example
    
    The @file{/dev/md0} device can then be used as the @code{device} of a
    @code{file-system} declaration (@pxref{File Systems}).
    Note that the RAID level need not be given; it is chosen during the
    initial creation and formatting of the RAID device and is determined
    automatically later.
    
    
    
    @node User Accounts
    @subsection User Accounts
    
    @cindex users
    @cindex accounts
    @cindex user accounts
    
    User accounts and groups are entirely managed through the
    @code{operating-system} declaration.  They are specified with the
    @code{user-account} and @code{user-group} forms:
    
    @example
    (user-account
      (name "alice")
      (group "users")
    
      (supplementary-groups '("wheel"   ;allow use of sudo, etc.
                              "audio"   ;sound card
                              "video"   ;video devices such as webcams
                              "cdrom")) ;the good ol' CD-ROM
    
      (comment "Bob's sister")
      (home-directory "/home/alice"))
    @end example
    
    When booting or upon completion of @command{guix system reconfigure},
    the system ensures that only the user accounts and groups specified in
    the @code{operating-system} declaration exist, and with the specified
    properties.  Thus, account or group creations or modifications made by
    directly invoking commands such as @command{useradd} are lost upon
    reconfiguration or reboot.  This ensures that the system remains exactly
    as declared.
    
    
    @deftp {Data Type} user-account
    Objects of this type represent user accounts.  The following members may
    be specified:
    
    @table @asis
    @item @code{name}
    The name of the user account.
    
    @item @code{group}
    
    @cindex groups
    
    This is the name (a string) or identifier (a number) of the user group
    this account belongs to.
    
    @item @code{supplementary-groups} (default: @code{'()})
    Optionally, this can be defined as a list of group names that this
    account belongs to.
    
    @item @code{uid} (default: @code{#f})
    This is the user ID for this account (a number), or @code{#f}.  In the
    latter case, a number is automatically chosen by the system when the
    account is created.
    
    @item @code{comment} (default: @code{""})
    
    A comment about the account, such as the account owner's full name.
    
    @item @code{home-directory}
    This is the name of the home directory for the account.
    
    @item @code{create-home-directory?} (default: @code{#t})
    Indicates whether the home directory of this account should be created
    if it does not exist yet.
    
    
    @item @code{shell} (default: Bash)
    This is a G-expression denoting the file name of a program to be used as
    the shell (@pxref{G-Expressions}).
    
    @item @code{system?} (default: @code{#f})
    This Boolean value indicates whether the account is a ``system''
    account.  System accounts are sometimes treated specially; for instance,
    graphical login managers do not list them.
    
    @anchor{user-account-password}
    
    @item @code{password} (default: @code{#f})
    
    You would normally leave this field to @code{#f}, initialize user
    passwords as @code{root} with the @command{passwd} command, and then let
    
    users change it with @command{passwd}.  Passwords set with
    @command{passwd} are of course preserved across reboot and
    reconfiguration.
    
    
    If you @emph{do} want to have a preset password for an account, then
    this field must contain the encrypted password, as a string.
    
    @xref{crypt,,, libc, The GNU C Library Reference Manual}, for more information
    on password encryption, and @ref{Encryption,,, guile, GNU Guile Reference
    
    Manual}, for information on Guile's @code{crypt} procedure.
    
    @end table
    @end deftp