aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/conf.py4
-rw-r--r--doc/connections.rst29
-rw-r--r--doc/data.rst20
-rw-r--r--doc/hosts.rst6
-rw-r--r--doc/ideas.rst30
-rw-r--r--doc/index.rst1
-rw-r--r--doc/installation.rst2
-rw-r--r--doc/introduction.rst9
-rw-r--r--doc/pitfalls.rst31
-rw-r--r--doc/properties.rst5
-rw-r--r--doc/tutorial/os_installation.rst80
11 files changed, 166 insertions, 51 deletions
diff --git a/doc/conf.py b/doc/conf.py
index 0bf86c6..653cb12 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -22,7 +22,7 @@ copyright = '2020-2021, Sean Whitton'
author = 'Sean Whitton'
# The full version, including alpha/beta/rc tags
-release = '0.8.0'
+release = '0.9.0'
# -- General configuration ---------------------------------------------------
@@ -49,7 +49,7 @@ highlight_language = 'common-lisp'
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'haiku'
+html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
diff --git a/doc/connections.rst b/doc/connections.rst
index be3ed80..6e20500 100644
--- a/doc/connections.rst
+++ b/doc/connections.rst
@@ -114,22 +114,17 @@ in that saved image. Typically a ``:SUDO`` connection hop is used before hops
which start up remote Lisp images, so these issues will not arise for most
users.
-``:CHROOT.FORK``
-~~~~~~~~~~~~~~~~
-
-Since forking is typically only possible when it is not the case that multiple
-threads are running, it is better to avoid using this connection type as the
-first hop, i.e., directly out of the root Lisp (this is not much of a
-restriction, since typically the root Lisp is running under a uid which cannot
-use the ``chroot(2)`` system call anyway). More generally, you should avoid
-using this connection type within a Lisp image which might try to execute
-other deployments in parallel. Typical usage would be something like::
+Connections which fork: ``:CHROOT.FORK``, ``:SETUID``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These connection types cannot be used as the first hop, i.e., directly out of
+the root Lisp. This is because they must call fork(2), and Consfigurator only
+makes this system call in contexts in which there shouldn't ever be more than
+one thread (excluding Lisp implementation finaliser threads and the like).
+The root Lisp is not such a context, because it is often multithreaded due to
+the use of SLIME. This is, however, not much of a restriction, because
+typically the root Lisp is running under a UID which cannot use system calls
+like chroot(2) and setuid(2) anyway. Thus, typical usage on localhost would
+be something like::
(deploy (:sudo :sbcl (:chroot.fork :into "...")) ...)
-
-In some situations you might want to have a connection chain which effectively
-uses a connection type like ``:SBCL`` twice in a row, so that the first Lisp
-image can execute deployments in parallel while the second forks into the
-chroot (typically by having a ``DEPLOYS`` property with connection type
-``:SBCL`` as one of the properties applied by a deployment whose connection
-chain itself ends with ``:SBCL``).
diff --git a/doc/data.rst b/doc/data.rst
index faba8a3..a32acb1 100644
--- a/doc/data.rst
+++ b/doc/data.rst
@@ -21,7 +21,14 @@ not use prerequisite data identified by strings matching these conditions for
other purposes.
- ``(HOSTNAME . PATH)`` means the data that should be uploaded to ``PATH`` on
- ``HOSTNAME`` (and nowhere else)
+ ``HOSTNAME`` (and usually nowhere else, except in the case of, e.g., a
+ public key). ``PATH`` must be absolute, not relative.
+
+- ``(_CONTEXT . ITEM)`` is an arbitrary prerequisite data context named
+ ``CONTEXT``; typically ``CONTEXT`` will be a network or grouping name,
+ rather than referring to a single host. ``ITEM`` might be a path or some
+ other identifier. Reserved for consfigs; will not be used by property
+ definitions included with Consfigurator.
- ``("--lisp-system" . SYSTEM)`` means the data is Lisp code which, when
loaded, defines the packages and symbols contained in the ASDF system
@@ -34,14 +41,17 @@ other purposes.
identified by ``NAME``; see ``DATA.GIT-SNAPSHOT``
- ``("--pgp-pubkey" . FINGERPRINT)`` means the/a OpenPGP public key with
- fingerprint FINGERPRINT
+ fingerprint FINGERPRINT, ASCII-armoured
+
+- ``("--pgp-seckey" . FINGERPRINT)`` means the/a OpenPGP secret key with
+ fingerprint FINGERPRINT, ASCII-armoured
- ``("--luks-passphrase" . VOLUME-LABEL)`` means a LUKS passphrase for volume
with label ``VOLUME-LABEL``.
-(Proposed convention: Except for the first item above, these reserved names
-should start with ``--`` and use ``--`` to separate parameter values within
-the string. Hostnames cannot start with a hyphen.)
+(Proposed convention: Except for the first two items above, these reserved
+names should start with ``--`` and use ``--`` to separate parameter values
+within the string. Hostnames cannot start with a hyphen.)
Mechanics
---------
diff --git a/doc/hosts.rst b/doc/hosts.rst
index 1f8a56c..25829aa 100644
--- a/doc/hosts.rst
+++ b/doc/hosts.rst
@@ -31,6 +31,12 @@ keyword symbols. The semantics of these attributes are documented here:
- ``:HOSTNAME``: the host's hostname -- if the host has a domain name, then
the FQDN, not just the part before the first dot
+- ``:ALIASES``: see ``NETWORK:ALIASES``
+
+- ``:IPV4``: the host's public IPv4 addresses
+
+- ``:IPV6``: the host's public IPv6 addresses
+
- ``:DATA``: items of prerequisite data required by the host
- ``:OS``: the operating system of the host
diff --git a/doc/ideas.rst b/doc/ideas.rst
index 688d040..a98fa42 100644
--- a/doc/ideas.rst
+++ b/doc/ideas.rst
@@ -12,14 +12,6 @@ Properties
Connections
-----------
-- :SBCL could (fork and) SAVE-LISP-AND-DIE. That way, we have something that
- a cronjob can call to re-run the deployment to ensure that all properties
- remain applied. Need to think about how the property which sets up the
- cronjob will be specified in consfigs -- does it make sense to allow passing
- in arbitrary deployments, or do we only allow re-running exactly the same
- thing? If the former, the saved image will need to take some sort of
- command line input telling it what arguments to pass to DEPLOY*.
-
- Basic infrastructure for connections which work with just input and output
streams connected to an interactive POSIX sh somewhere, like TRAMP, and
probably using ``base64 -d`` for WRITEFILE. Probably the basic connection
@@ -35,13 +27,12 @@ Connections
temporary name so that rsync can do an incremental update, and then rename
the file to the new version.
-Data sources
-------------
-
-- It might be useful to have a data source which can just provide a single
- item of data when registered. Then in your consfig you can just register
- this data source to make a particular file you have on your system available
- to deployments.
+- It would sometimes be useful to have the SSH connection pass
+ ``-oHostName=<known IP address>`` when ``NETWORK:IPV4`` and/or
+ ``NETWORK:IPV6`` have been specified for the host, so that DNS propagation
+ is less likely to get in the way of configuring the host. Some hosts' SSH
+ daemons might only be accessible over VPNs and the like, however, so it will
+ need to be easy to override this.
Core
----
@@ -54,10 +45,11 @@ Core
- A CONCURRENTLY combinator for property application specifications, which
means to apply each of the enclosed properties in parallel. Particularly
useful surrounding a set of DEPLOYS applications, to concurrently deploy a
- number of hosts. We use ``WITH-CURRENT-DIRECTORY`` in various places, so we
- may not be able to do this using threads. But if we want to do it with lots
- of forking, then practically speaking usage of this combinator will be
- restricted to connection chains which start up remote Lisp images.
+ number of hosts. Now that we don't call fork(2) while executing
+ deployments, we ought to be able to do this using threads, and so it can
+ work in the root Lisp too. However, we still use ``WITH-CURRENT-DIRECTORY``
+ in various places. Perhaps that macro could be changed to only affect RUN,
+ MRUN etc. for the sake of enabling multithreading.
- It might be useful to have a restart for the case where an attempt is made
to apply a list of properties containing some ``:LISP`` properties with a
diff --git a/doc/index.rst b/doc/index.rst
index 680f406..2c62559 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -8,6 +8,7 @@ Consfigurator user's manual
introduction
installation
tutorial/disk_image
+ tutorial/os_installation
connections
properties
hosts
diff --git a/doc/installation.rst b/doc/installation.rst
index 4a2d0b2..c71836c 100644
--- a/doc/installation.rst
+++ b/doc/installation.rst
@@ -6,7 +6,7 @@ Installation
Debian and Debian derivatives
-----------------------------
-The most recent tagged release of Consfigurator is included in `Debian
+The most recent tagged release of Consfigurator is usually included in `Debian
unstable`_, and the .deb there should work fine on Debian stable and testing,
and derivatives like Ubuntu. After adding an apt source for unstable, if
necessary, ``apt-get install cl-consfigurator/unstable``.
diff --git a/doc/introduction.rst b/doc/introduction.rst
index 656e7eb..b6d2f0c 100644
--- a/doc/introduction.rst
+++ b/doc/introduction.rst
@@ -83,7 +83,7 @@ Try it out / quick start
;; These two properties are not for debootstrap(1) for but apt
;; inside the chroot.
(apt:uses-parent-proxy) ; use the apt-cacher-ng set up outside chroot
- (apt:uses-parent-mirror))) ; use the apt mirror set up above
+ (apt:uses-parent-mirrors))) ; use the apt mirror set up above
Here, "spwhitton" is my username on athena; we have to tell Consfigurator
what user it will be when it tries to sudo, so it knows whose password it
@@ -290,10 +290,9 @@ Portability and stability
- All of the code in the core library should be portable ANSI Common Lisp,
though optional packages providing properties and connection types might use
- implementation-specific functionality. There is one exception: we require
- an implementation of ``MACROEXPAND-ALL``, but most Lisps in use today
- provide this. Little to no testing is done by the author on implementations
- other than SBCL, so testing and portability patches are welcome.
+ implementation-specific functionality. Little to no testing is done by the
+ author on implementations other than SBCL, so testing and portability
+ patches are welcome.
- Little attempt is made by the author to support systems other than Debian
GNU/Linux, but again, portability patches are welcome, and the design of
diff --git a/doc/pitfalls.rst b/doc/pitfalls.rst
index 7a7bbae..b0610eb 100644
--- a/doc/pitfalls.rst
+++ b/doc/pitfalls.rst
@@ -48,3 +48,34 @@ serialisable, so you can't pass anonymous functions or objects containing
those. You can work around the latter restriction by defining a new property
which passes in the desired anonymous function, and then adding the new
property to your property application specification.
+
+Code-walking limitations
+------------------------
+
+The preprocessing of propspecs, and the conversion of unevaluated propspecs
+into propspecs, both require code walking. Consfigurator's implementation of
+this is in the function ``MAP-PROPSPEC-PROPAPPS``. However, due to
+limitations in the Common Lisp standard, it is not possible to implement the
+work of that function in a way which is both always correct and fully
+portable. I have not found a general purpose code walker which hooks into
+implementation-specific functionality and that is currently maintained, and so
+at present we use a best-effort portable code walker, Agnostic Lizard.
+
+This will almost always generate the correct expansions, but if you have
+particularly advanced macro property combinators then it is possible that
+``MAP-PROPSPEC-PROPAPPS`` will return incorrectly expanded forms. For full
+details see Michael Raskin. 2017. "Writing a best-effort portable code
+walker in Common Lisp." In *Proceedings of 10th European Lisp Symposium*,
+Vrije Universiteit Brussel, Belgium, April 2017 (ELS2017). DOI:
+10.5281/zenodo.3254669.
+
+It is possible to implement the work of ``MAP-PROPSPEC-PROPAPPS`` in terms of
+``MACROEXPAND-ALL``, whose semantics are conventionally well-understood and
+for which fully correct implementations are available in most implementations
+of Common Lisp (the trivial-macroexpand-all library can be used to get at
+these). However, note that we cannot just call ``MACROEXPAND-ALL`` on
+propspecs because unquoted lists appearing as arguments to properties in
+atomic property applications will look like invalid function calls to the code
+walker. Avoiding this would seem to require wrapping the propspec in one
+macrolet for each known property, and this makes ``MACROEXPAND-ALL`` too slow,
+even if the macrolet forms are precomputed.
diff --git a/doc/properties.rst b/doc/properties.rst
index b21f51b..3273da6 100644
--- a/doc/properties.rst
+++ b/doc/properties.rst
@@ -7,8 +7,9 @@ Names
The names of properties may not end in the character ``.``, because that has a
special meaning in unevaluated property application specifications.
-Properties occupy the function cells of symbols, so do not try to define an
-ordinary function with the same name as a property.
+Properties with ``:APPLY`` subroutines occupy the function cells of symbols,
+so except in the case of properties with no ``:APPLY`` subroutine, do not try
+to define an ordinary function with the same name as a property.
Working directories
-------------------
diff --git a/doc/tutorial/os_installation.rst b/doc/tutorial/os_installation.rst
new file mode 100644
index 0000000..7c114f0
--- /dev/null
+++ b/doc/tutorial/os_installation.rst
@@ -0,0 +1,80 @@
+Tutorial: OS installation
+=========================
+
+Consfigurator implements at least the basic elements of a number of methods
+for installing operating systems.
+
+.. include:: conventions.rst
+
+Build and write out a raw disk image
+------------------------------------
+
+This is the simplest method, and Consfigurator has decent support built-in:
+see the previous tutorial. It is less practical for systems which have large
+disks and/or complex, nested partitioning schemes, such as ext4 on LVM on
+LUKS, as is common for GNU/Linux laptops. In such cases it is nontrivial to
+expand the partitions to fill the whole physical disk after the first
+successful boot, so the disk image has to be the same size as the target disk,
+which can be unwieldy.
+
+Live replacement of provider cloud images
+-----------------------------------------
+
+See the docstring of the INSTALLER:CLEANLY-INSTALLED-ONCE property. This is
+an efficient way to handle machines in faraway datacentres. Consfigurator's
+support for installing Debian stable this way has been fairly well tested, and
+the technique should work for other operating systems too, once Consfigurator
+has been taught how to bootstrap them.
+
+Build a specialised live image
+------------------------------
+
+This third approach is more experimental; Consfigurator has all the necessary
+capabilities, at least for Debian, but at present you'll need to string them
+together yourself in your consfig. With this approach you build a live image
+containing everything you need to run Consfigurator on the hardware to which
+you want to install. After booting up the live system, you can either run
+Consfigurator manually, or you can set things up to have it run automatically
+upon boot.
+
+Consfigurator's ability to bootstrap fresh root filesystems typically requires
+Internet access, but an alternative is to build and customise a chroot
+corresponding to the root filesystem of the target system, and include that in
+the live image, such that after boot Consfigurator just needs to partition the
+disk, copy in the contents of the prebuilt chroot, and update /etc/fstab and
+/etc/crypttab with UUIDs. Here is a sketch of how to do something like that::
+
+ (try-register-data-source
+ :git-snapshot :name "consfig"
+ :repo #P"src/cl/consfig/" :depth 1 :branch "master")
+
+ (defproplist live-installer-built-for :lisp (with-chroot-for)
+ "Build a custom Debian Live system at /srv/live/installer.iso.
+
+ Typically this property is not applied in a DEFHOST form, but rather run as
+ needed at the REPL. The reason for this is that otherwise the whole image will
+ get rebuilt each time a commit is made to ~/src/cl/consfig/."
+ (:desc "Debian Live system image built")
+ (disk:debian-live-iso-built. nil "/srv/live/installer.iso"
+ (os:debian-stable "bullseye" :amd64)
+ (apt:installed "task-english" "live-config" "lvm2" "cryptsetup")
+ (git:snapshot-extracted "/etc/skel/src/cl" "consfig")
+ (chroot:os-bootstrapped-for
+ nil
+ (merge-pathnames (get-hostname with-chroot-for) "/srv/chroot/")
+ with-chroot-for)))
+
+Supposing we've a DEFHOST form for test.silentflame.com, on our laptop we
+could then use::
+
+ CONSFIG> (hostdeploy-these laptop.silentflame.com
+ (live-installer-built-for test.silentflame.com))
+
+Then once the live system has booted on the target host, you'd use the
+DISK:HOST-VOLUMES-CREATED and INSTALLER:CHROOT-INSTALLED-TO-VOLUMES properties
+to complete the installation.
+
+To prepare a live image that is capable of installing more than one system
+without an Internet connection, you'd probably need to investigate including
+an apt repo, or equivalent, in the live system, and point Consfigurator's OS
+bootstrapping properties at that.