<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"><channel><title>civilfritz.net (unsorted thoughts from Jonathon Anderson)</title><link>https://civilfritz.net/</link><description></description><atom:link href="https://civilfritz.net/anderbubble.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2024 &lt;a href="mailto:janderson@civilfritz.net"&gt;Jonathon Anderson&lt;/a&gt; &lt;a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"&gt;&lt;img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /&gt;&lt;/a&gt;</copyright><lastBuildDate>Sun, 24 Mar 2024 06:48:48 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Splitting Warewulf Images Between PXE and NFS</title><link>https://civilfritz.net/anderbubble/splitting-warewulf-images-between-pxe-and-nfs/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;p&gt;&lt;em&gt;&lt;a href="https://ciq.co/blog/splitting-warewulf-images-between-pxe-and-nfs/"&gt;This article was also published via the CIQ blog on 6 December 2022.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Warewulf 4 introduced compatibility with the OCI container ecosystem,
which greatly streamlines the process of defining, importing, and
maintaining compute node images compared to other systems--even
compared to Warewulf 3! But one aspect of compute node images remains
unchanged: they can quickly grow in size.&lt;/p&gt;
&lt;p&gt;Warewulf (and the technique of PXE-booting a node image more broadly)
expects that a compute node image will remain relatively small. Larger
sets of software, like you might provide via an Environment Modules
stack or, perhaps, via Spack, are typically deployed via a central NFS
share, which is then mounted at runtime by the booted compute
node. Even OpenHPC, with software packaged as operating system
containers, supports this paradigm, with packages installed on the
head node, landing in &lt;code&gt;/opt&lt;/code&gt;, and then being shared from the head node
to compute nodes.&lt;/p&gt;
&lt;p&gt;However, there are still benefits to maintaining this software as part
of a compute node image; but such a large image can quickly grow to
tens of gigabytes, making network booting difficult.&lt;/p&gt;
&lt;p&gt;In this article I'll demonstrate how a full software stack can be
managed together with a given compute node image, but the resultant
payload can be split in-place between PXE-served netbooting and an
NFS-mounted file system.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This procedure depends on support for &lt;code&gt;/etc/warewulf/excludes&lt;/code&gt;, which
was broken in Warewulf v4.3.0.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;The root image&lt;/h3&gt;
&lt;p&gt;First, I start with the standard Rocky Linux 8 image as published by
HPCng.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;container&lt;span class="w"&gt; &lt;/span&gt;import&lt;span class="w"&gt; &lt;/span&gt;docker://docker.io/warewulf/rocky:8&lt;span class="w"&gt; &lt;/span&gt;rocky-8-split
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Installing some software&lt;/h3&gt;
&lt;p&gt;Using the OpenHPC project as a source, I install a set of typical
scientific software. Most OpenHPC packages install software in &lt;code&gt;/opt&lt;/code&gt;
for distribution via NFS, which is what we're going to do: just a
little bit differently than usual.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;container&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;rocky-8-split
&lt;span class="go"&gt;[rocky-8-split] Warewulf&amp;gt; dnf -y install 'dnf-command(config-manager)'&lt;/span&gt;
&lt;span class="go"&gt;[rocky-8-split] Warewulf&amp;gt; dnf config-manager --set-enabled powertools&lt;/span&gt;
&lt;span class="go"&gt;[rocky-8-split] Warewulf&amp;gt; dnf -y install epel-release http://repos.openhpc.community/OpenHPC/2/CentOS_8/x86_64/ohpc-release-2-1.el8.x86_64.rpm&lt;/span&gt;
&lt;span class="go"&gt;[rocky-8-split] Warewulf&amp;gt; dnf -y install valgrind-ohpc {netcdf,pnetcdf,hypre,boost}-gnu9-mpich-ohpc&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After installing the software our image is approaching 2GB. This isn't
egregious (and the compressed image as sent over the network is even
smaller), but gives us a point of comparison for what comes next.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;du&lt;span class="w"&gt; &lt;/span&gt;-h&lt;span class="w"&gt; &lt;/span&gt;/var/lib/warewulf/container/rocky-8-split.img&lt;span class="o"&gt;{&lt;/span&gt;,.gz&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;1.8G    /var/lib/warewulf/container/rocky-8-split.img&lt;/span&gt;
&lt;span class="go"&gt;651M    /var/lib/warewulf/container/rocky-8-split.img.gz&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Excluding the software from the final image&lt;/h3&gt;
&lt;p&gt;Warewulf consults &lt;code&gt;/etc/warewulf/excludes&lt;/code&gt; within the image itself to
define files that should not be included in the built image. For our
example here, I exclude the full contents of &lt;code&gt;/opt/&lt;/code&gt;, in anticipation
that we'll be mounting it via NFS in stead.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="go"&gt;[rocky-8-split] Warewulf&amp;gt; cat /etc/warewulf/excludes&lt;/span&gt;
&lt;span class="go"&gt;/boot&lt;/span&gt;
&lt;span class="go"&gt;/usr/share/GeoIP&lt;/span&gt;
&lt;span class="go"&gt;/opt/*&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Rebuilding the image with &lt;code&gt;/opt/*&lt;/code&gt; excluded, the image is reduced in
size, and further software installation would no longer increase the
final size of the image delivered over PXE.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;du&lt;span class="w"&gt; &lt;/span&gt;-h&lt;span class="w"&gt; &lt;/span&gt;/var/lib/warewulf/container/rocky-8-split.img&lt;span class="o"&gt;{&lt;/span&gt;,.gz&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;1.1G    /var/lib/warewulf/container/rocky-8-split.img&lt;/span&gt;
&lt;span class="go"&gt;483M    /var/lib/warewulf/container/rocky-8-split.img.gz&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Exporting the software via NFS&lt;/h3&gt;
&lt;p&gt;With the software in &lt;code&gt;/opt&lt;/code&gt; excluded from the image, we need to export
it via NFS in stead. This is relatively easily done, though we must
discover and hard-code paths to the container directory.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;readlink&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;container&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;rocky-8-split&lt;span class="k"&gt;)&lt;/span&gt;/opt
&lt;span class="go"&gt;/var/lib/warewulf/chroots/rocky-8-split/rootfs/opt&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Add an NFS export to &lt;code&gt;/etc/warewulf/warewulf.conf&lt;/code&gt;, restart the
Warewulf server, and configure NFS with &lt;code&gt;wwctl&lt;/code&gt;. Note that I've
specified &lt;code&gt;mount: false&lt;/code&gt; for this export, as I want to control &lt;em&gt;which&lt;/em&gt;
nodes will mount it: presumably nodes that aren't using this image
should not mount this image's software.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nt"&gt;nfs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;export paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/var/lib/warewulf/chroots/rocky-8-split/rootfs/opt&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;export options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;rw,sync,no_root_squash&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;false&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;restart&lt;span class="w"&gt; &lt;/span&gt;warewulfd
&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;configure&lt;span class="w"&gt; &lt;/span&gt;nfs
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Mounting the software on the compute node&lt;/h3&gt;
&lt;p&gt;We can mount this new NFS share just like any other, by listing it in &lt;code&gt;fstab&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Warewulf typically configures &lt;code&gt;fstab&lt;/code&gt; as part of the &lt;code&gt;wwinit&lt;/code&gt;
overlay. In order to mount this NFS share without setting &lt;code&gt;mount:
true&lt;/code&gt; for all nodes, I copy &lt;code&gt;fstab.ww&lt;/code&gt; to a new overlay and add an
additional entry.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;overlay&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;rocky-8-split
&lt;span class="go"&gt;OVERLAY NAME                   FILES/DIRS&lt;/span&gt;
&lt;span class="go"&gt;rocky-8-split                  /etc/&lt;/span&gt;
&lt;span class="go"&gt;rocky-8-split                  /etc/fstab.ww&lt;/span&gt;

&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;overlay&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;rocky-8-split&lt;span class="w"&gt; &lt;/span&gt;/etc/fstab.ww&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tail&lt;span class="w"&gt; &lt;/span&gt;-n1
&lt;span class="go"&gt;{{ .Ipaddr }}:/var/lib/warewulf/chroots/rocky-8-split/rootfs/opt /opt nfs defaults 0 0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I can add the new overlay to our &lt;code&gt;wwinit&lt;/code&gt; list, and the &lt;code&gt;fstab&lt;/code&gt; in
&lt;code&gt;rocky-8-split&lt;/code&gt; will override the one in &lt;code&gt;wwinit&lt;/code&gt;. (Note: &lt;code&gt;--wwinit&lt;/code&gt;
was specified as &lt;code&gt;--system&lt;/code&gt; in Warewulf 4.3.0.)&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;profile&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--wwinit&lt;span class="w"&gt; &lt;/span&gt;wwinit,rocky-8-split&lt;span class="w"&gt; &lt;/span&gt;default
&lt;span class="gp"&gt;[root@wwctl1 ~]# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;profile&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--container&lt;span class="w"&gt; &lt;/span&gt;rocky-8-split&lt;span class="w"&gt; &lt;/span&gt;default
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From a compute node, we can see that &lt;code&gt;/opt&lt;/code&gt; is mounted via NFS as
expected.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@compute1 ~]# &lt;/span&gt;findmnt&lt;span class="w"&gt; &lt;/span&gt;/opt
&lt;span class="go"&gt;TARGET SOURCE                                                      FSTYPE OPTIONS&lt;/span&gt;
&lt;span class="go"&gt;/opt   10.0.0.3:/var/lib/warewulf/chroots/rocky-8-split/rootfs/opt nfs4   rw,relatime,vers=4.2,rsize=262144,wsize=262144,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.4,local_lock=none,addr=10.0.0.3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can further confirm that &lt;code&gt;/opt&lt;/code&gt; is empty on the local, PXE-deployed
file system.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;[root@compute1 ~]# &lt;/span&gt;mount&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;/mnt
&lt;span class="gp"&gt;[root@compute1 ~]# &lt;/span&gt;du&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;/mnt/opt
&lt;span class="go"&gt;0   /mnt/opt&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Future work&lt;/h3&gt;
&lt;p&gt;As demonstrated here, we can already implement split PXE/NFS images
using functionality already in Warewulf; but future Warewulf
development may simplify this process further:&lt;/p&gt;
&lt;h4&gt;Container path variables in warewulf.conf&lt;/h4&gt;
&lt;p&gt;We could support referring to compute node images in
&lt;code&gt;warewulf.conf&lt;/code&gt;. For example, it would be nice to be able to replace&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nt"&gt;nfs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;export paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/var/lib/warewulf/chroots/rocky-8-split/rootfs/opt&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;export options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;rw,sync,no_root_squash&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;false&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;with something like&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nt"&gt;nfs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;export paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;containers&lt;/span&gt;&lt;span class="p p-Indicator"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'rocky-8-split'&lt;/span&gt;&lt;span class="p p-Indicator"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;}}&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/opt&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;export options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;rw,sync,no_root_squash&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;false&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This way, our configuration would not have to hard-code the path to
the container chroot.&lt;/p&gt;
&lt;h4&gt;Move NFS mount settings to nodes and profiles&lt;/h4&gt;
&lt;p&gt;Right now, NFS client settings are stored in &lt;code&gt;warewulf.conf&lt;/code&gt; as &lt;code&gt;mount
options&lt;/code&gt;, &lt;code&gt;mount&lt;/code&gt;, and implicitly via &lt;code&gt;path&lt;/code&gt;; but if these settings
were moved to nodes and profiles we could configure per-profile and
per-node NFS client behavior without having to manually edit or
override &lt;code&gt;fstab&lt;/code&gt;.&lt;/p&gt;</description><category>technology</category><category>warewulf</category><guid>urn:uuid:0f31138a-a5e0-467b-be30-c9287d505ec9</guid><pubDate>Wed, 07 Dec 2022 23:30:00 GMT</pubDate></item><item><title>Stateless provisioning of stateful nodes: examples with Warewulf 4</title><link>https://civilfritz.net/anderbubble/stateless-provisioning-of-stateful-nodes/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;p&gt;&lt;em&gt;&lt;a href="https://ciq.co/blog/stateless-provisioning-of-stateful-notes-examples-with-warewulf-4/"&gt;This article was also published via the CIQ blog on 30 November 2022.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When deploying Warewulf 4, we often encounter expectations that
Warewulf should support stateful provisioning. Typically these
expectations are born from experience with another system (such as
Foreman, XCAT, or even Warewulf 3) that supported writing a
provisioned operating system to the local disk of each compute node.&lt;/p&gt;
&lt;p&gt;Warewulf 4 intentionally omits this kind of stateful provisioning from
its feature set, following experiences from Warewulf 3: the code for
stateful provisioning was complex, and required a disproportionate
amount of maintenance compared to the number of sites using it.&lt;/p&gt;
&lt;p&gt;For the most part, we think that arguments for stateful provisioning
are better addressed within Warewulf 4's stateless provisioning
process. I'd like to go over three such common use cases here, and
show how each can be addressed to provision nodes with local state
using Warewulf 4.&lt;/p&gt;
&lt;h3&gt;Local scratch&lt;/h3&gt;
&lt;p&gt;The first thing to understand is that stateless provisioning does not
mean diskless nodes. For example, you may have a local disk that you
want to provide as a scratch file system.&lt;/p&gt;
&lt;p&gt;Warewulf compute nodes run a small &lt;code&gt;wwclient&lt;/code&gt; agent that assists with
the &lt;code&gt;init&lt;/code&gt; process during boot and deploys the node's overlays during
boot and runtime. &lt;code&gt;wwclient&lt;/code&gt; reads its own initialization scripts from
&lt;code&gt;/warewulf/init.d/&lt;/code&gt;, so we can place startup scripts there to take
actions during boot.&lt;/p&gt;
&lt;p&gt;My test nodes here are KVM instances with a virtual disk at
&lt;code&gt;/dev/vda&lt;/code&gt;. This &lt;code&gt;wwclient&lt;/code&gt; init script looks for a "local-scratch"
file system and, if it does not exist, creates one on the local disk.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# /warewulf/init.d/70-mkfs-local-scratch&lt;/span&gt;

&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/sbin:/usr/bin

&lt;span class="c1"&gt;# KVM disks require a kernel module&lt;/span&gt;
modprobe&lt;span class="w"&gt; &lt;/span&gt;virtio_blk

&lt;span class="nv"&gt;fs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;findfs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;LABEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;local-scratch&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"local-scratch filesystem already exists: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;fs&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/vda
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Creating local-scratch filesystem on &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mkfs.ext4&lt;span class="w"&gt; &lt;/span&gt;-FL&lt;span class="w"&gt; &lt;/span&gt;local-scratch&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;wwclient&lt;/code&gt; runs this script before it passes &lt;code&gt;init&lt;/code&gt; on to systemd, so
it is also processed before &lt;code&gt;fstab&lt;/code&gt;. So we can mount the
"local-scratch" file system just like any other disk in &lt;code&gt;fstab&lt;/code&gt;.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;LABEL=local-scratch /mnt/scratch ext4 defaults,X-mount.mkdir,nofail 0 0
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Warewulf 4 overlay system allows us to deploy customized files to
nodes or groups of nodes (via profiles) at boot. For this example,
I've placed my customized &lt;code&gt;fstab&lt;/code&gt; and init script in a "local-scratch"
overlay and included it as a system overlay, alongside the default
&lt;code&gt;wwinit&lt;/code&gt; overlay.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;overlay&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;local-scratch
&lt;span class="go"&gt;OVERLAY NAME                   FILES/DIRS  &lt;/span&gt;
&lt;span class="go"&gt;local-scratch                  /etc/        &lt;/span&gt;
&lt;span class="go"&gt;local-scratch                  /etc/fstab.ww&lt;/span&gt;
&lt;span class="go"&gt;local-scratch                  /warewulf/   &lt;/span&gt;
&lt;span class="go"&gt;local-scratch                  /warewulf/init.d/&lt;/span&gt;
&lt;span class="go"&gt;Local-scratch                  /warewulf/init.d/70-mkfs-local-scratch&lt;/span&gt;

&lt;span class="gp"&gt;# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;profile&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--system&lt;span class="w"&gt; &lt;/span&gt;wwinit,local-scratch&lt;span class="w"&gt; &lt;/span&gt;default
&lt;span class="gp"&gt;# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;overlay&lt;span class="w"&gt; &lt;/span&gt;build
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because &lt;code&gt;local-scratch&lt;/code&gt; is listed after &lt;code&gt;wwinit&lt;/code&gt; in the "system"
overlay list (see above), its &lt;code&gt;fstab&lt;/code&gt; overrides the definition in the
&lt;code&gt;wwinit&lt;/code&gt; overlay. &lt;code&gt;70-mkfs-local-scratch&lt;/code&gt; is placed alongside other
init scripts, and is processed in lexical order.&lt;/p&gt;
&lt;p&gt;A node booting with this overlay will create (if it does not exist) a
"local-scratch" file system and mount it at "/mnt/scratch",
potentially for use by compute jobs.&lt;/p&gt;
&lt;h3&gt;Disk partitioning&lt;/h3&gt;
&lt;p&gt;But perhaps you want to do something more complex. Perhaps you have a
single disk, but you want to allocate part of it for scratch (as
above) and part of it as swap space. Perhaps contrary to popular
opinion, we actively encourage the use of swap space in an
image-netboot environment like Warewulf 4: a swap partition that is at
least as big as the image to be booted allows Linux to write idle
portions of the image to disk, freeing up system memory for compute
jobs.&lt;/p&gt;
&lt;p&gt;So let's expand on the above pattern to actually &lt;em&gt;partition&lt;/em&gt; a disk,
rather than just format it.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# /warewulf/init.d/70-parted&lt;/span&gt;

&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/sbin:/usr/bin

&lt;span class="c1"&gt;# KVM disks require a kernel module&lt;/span&gt;
modprobe&lt;span class="w"&gt; &lt;/span&gt;virtio_blk

&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;findfs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;LABEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;local-swap&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;findfs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;LABEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;local-scratch&lt;span class="k"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Found local-swap: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Found local-scratch: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/vda
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;1"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;2"&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Writing partition table to &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;parted&lt;span class="w"&gt; &lt;/span&gt;--script&lt;span class="w"&gt; &lt;/span&gt;--align&lt;span class="o"&gt;=&lt;/span&gt;optimal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mklabel&lt;span class="w"&gt; &lt;/span&gt;gpt&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mkpart&lt;span class="w"&gt; &lt;/span&gt;primary&lt;span class="w"&gt; &lt;/span&gt;linux-swap&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;2GB&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mkpart&lt;span class="w"&gt; &lt;/span&gt;primary&lt;span class="w"&gt; &lt;/span&gt;ext4&lt;span class="w"&gt; &lt;/span&gt;2GB&lt;span class="w"&gt; &lt;/span&gt;-1

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Creating local-swap on &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mkswap&lt;span class="w"&gt; &lt;/span&gt;--label&lt;span class="o"&gt;=&lt;/span&gt;local-swap&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Creating local-scratch on &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mkfs.ext4&lt;span class="w"&gt; &lt;/span&gt;-FL&lt;span class="w"&gt; &lt;/span&gt;local-scratch&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This new init script looks for the expected "local-scratch" and
"local-swap" and, if either of them is not found, uses &lt;code&gt;parted&lt;/code&gt; to
partition the disk and creates them. As before, this is done before
&lt;code&gt;fstab&lt;/code&gt; is processed, so we can configure these with &lt;code&gt;fstab&lt;/code&gt; the
standard way.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;LABEL=local-swap swap swap defaults,nofail 0 0
LABEL=local-scratch /mnt/scratch ext4 defaults,X-mount.mkdir,nofail 0 0
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This configuration went into a new &lt;code&gt;parted&lt;/code&gt; overlay, allowing us to
configure some nodes for "local-scratch" only, and some nodes for this
partitioned layout.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gp"&gt;# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;overlay&lt;span class="w"&gt; &lt;/span&gt;list&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;parted
&lt;span class="go"&gt;OVERLAY NAME                   FILES/DIRS  &lt;/span&gt;
&lt;span class="go"&gt;parted                         /etc/        &lt;/span&gt;
&lt;span class="go"&gt;parted                         /etc/fstab.ww&lt;/span&gt;
&lt;span class="go"&gt;parted                         /warewulf/   &lt;/span&gt;
&lt;span class="go"&gt;parted                         /warewulf/init.d/&lt;/span&gt;
&lt;span class="go"&gt;parted                         /warewulf/init.d/70-parted&lt;/span&gt;

&lt;span class="gp"&gt;# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;profile&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--system&lt;span class="w"&gt; &lt;/span&gt;wwinit,parted&lt;span class="w"&gt; &lt;/span&gt;default
&lt;span class="gp"&gt;# &lt;/span&gt;wwctl&lt;span class="w"&gt; &lt;/span&gt;overlay&lt;span class="w"&gt; &lt;/span&gt;build
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(Note: I installed &lt;code&gt;parted&lt;/code&gt; in my system image to support this; but
the same could also be done with &lt;code&gt;sfdisk&lt;/code&gt;, which is included in the
image by default.)&lt;/p&gt;
&lt;h3&gt;Persistent storage for logs&lt;/h3&gt;
&lt;p&gt;Another common use case we hear concerns the persistence of logs on
the compute nodes. Particularly in a failure event, where a node must
be rebooted, it can be useful to have retained logs on the compute
host so that they can be investigated when the node is brought back
up: in a default stateless deployment, these logs are lost on reboot.&lt;/p&gt;
&lt;p&gt;We can extend from the previous two examples to deploy a "local-log"
file system to retain these logs between reboots.&lt;/p&gt;
&lt;p&gt;(Note: generally we advise &lt;em&gt;not&lt;/em&gt; retaining logs on compute nodes: in
stead, you should deploy something like Elasticsearch, Splunk, or even
just a central rsyslog instance.)&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# /warewulf/init.d/70-parted&lt;/span&gt;

&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/sbin:/usr/bin

&lt;span class="c1"&gt;# KVM disks require a kernel module&lt;/span&gt;
modprobe&lt;span class="w"&gt; &lt;/span&gt;virtio_blk

&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;findfs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;LABEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;local-swap&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;local_log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;findfs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;LABEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;local-log&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;findfs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;LABEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;local-scratch&lt;span class="k"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_log&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Found local-swap: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Found local-log: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_log&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Found local-scratch: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/vda
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;1"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;local_log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;2"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;3"&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Writing partition table to &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;parted&lt;span class="w"&gt; &lt;/span&gt;--script&lt;span class="w"&gt; &lt;/span&gt;--align&lt;span class="o"&gt;=&lt;/span&gt;optimal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mklabel&lt;span class="w"&gt; &lt;/span&gt;gpt&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mkpart&lt;span class="w"&gt; &lt;/span&gt;primary&lt;span class="w"&gt; &lt;/span&gt;linux-swap&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;2GB&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mkpart&lt;span class="w"&gt; &lt;/span&gt;primary&lt;span class="w"&gt; &lt;/span&gt;ext4&lt;span class="w"&gt; &lt;/span&gt;2GB&lt;span class="w"&gt; &lt;/span&gt;4GB&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mkpart&lt;span class="w"&gt; &lt;/span&gt;primary&lt;span class="w"&gt; &lt;/span&gt;ext4&lt;span class="w"&gt; &lt;/span&gt;4GB&lt;span class="w"&gt; &lt;/span&gt;-1

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Creating local-swap on &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mkswap&lt;span class="w"&gt; &lt;/span&gt;--label&lt;span class="o"&gt;=&lt;/span&gt;local-swap&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_swap&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Creating local-log on &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_log&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mkfs.ext4&lt;span class="w"&gt; &lt;/span&gt;-FL&lt;span class="w"&gt; &lt;/span&gt;local-log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_log&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Populating local-log from image /var/log/"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;/mnt/log/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;mount&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_log&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/mnt/log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rsync&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;/var/log/&lt;span class="w"&gt; &lt;/span&gt;/mnt/log/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;umount&lt;span class="w"&gt; &lt;/span&gt;/mnt/log/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;rmdir&lt;span class="w"&gt; &lt;/span&gt;/mnt/log

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Creating local-scratch on &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;mkfs.ext4&lt;span class="w"&gt; &lt;/span&gt;-FL&lt;span class="w"&gt; &lt;/span&gt;local-scratch&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;local_scratch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For the most part, this follows the same pattern from the "parted"
example above; but adds a step to initalize the new "local-log" file
system from the directory structure in the image.&lt;/p&gt;
&lt;p&gt;Finally, the new file system is added to fstab, after which logs will
be persisted on the local disk.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;LABEL=local-swap swap swap defaults,nofail 0 0
LABEL=local-scratch /mnt/scratch ext4 defaults,X-mount.mkdir,nofail 0 0
LABEL=local-log /var/log ext4 defaults,nofail 0 0
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Some applications may write logs outside of &lt;code&gt;/var/log&lt;/code&gt;; but, in these
instances, it's probably easier to configure the application to write
to &lt;code&gt;/var/log&lt;/code&gt; than to try to capture all the places where logs might
be written.&lt;/p&gt;
&lt;h3&gt;The future&lt;/h3&gt;
&lt;p&gt;There are a few more use cases that we sometimes hear brought up in
the context of stateful node provisioning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How can we use Ansible to configure compute nodes?&lt;/li&gt;
&lt;li&gt;How can we configure custom kernels and kernel modules per node?&lt;/li&gt;
&lt;li&gt;Isn't stateless provisioning slower than having the OS deployed on
  disk?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you'd like to hear more about these or other potential corner-cases
for stateless provisioning, &lt;a href="https://ciq.co/contact-us"&gt;get in touch!&lt;/a&gt; We'd love to
hear from you, learn about the work you're doing, and address any of
the challenges you're having.&lt;/p&gt;</description><category>technology</category><category>warewulf</category><guid>urn:uuid:f6dd7a5c-d8ad-43a8-a38c-e982ec2e1637</guid><pubDate>Fri, 21 Oct 2022 06:00:00 GMT</pubDate></item><item><title>Warewulf Deep Dive | CIQ Webinar</title><link>https://civilfritz.net/anderbubble/2022-07-07-warewulf-deep-dive-ciq-webinar/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;p&gt;I'm really excited about Warewulf 4! I'm also really excited about
OpenHPC, Apptainer, and containerizing HPC workloads, particularly
MPI. Today I presented my most recent work in these areas in the CIQ
webinar.&lt;/p&gt;
&lt;div class="youtube-video"&gt;
&lt;iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/EpVDeesAq4c?rel=0&amp;amp;wmode=transparent" frameborder="0" allow="encrypted-media" allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;&lt;p&gt;We're doing these webinars every week! I hope you'll join us Thursdays
at 11:00 Pacific time, either via &lt;a class="reference external" href="https://www.youtube.com/c/CtrlIQ"&gt;YouTube&lt;/a&gt; and &lt;a class="reference external" href="https://www.linkedin.com/company/ctrliq/"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;</description><guid>urn:uuid:8e4076ce-e6b4-4f7f-9e9d-98d48ff85d09</guid><pubDate>Thu, 07 Jul 2022 21:58:59 GMT</pubDate></item><item><title>Apptainer Signatures | CIQ Webinar</title><link>https://civilfritz.net/anderbubble/2022-05-19-apptainer-signatures-ciq-webinar/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;p&gt;I had the pleasure of participating in my first CIQ webinar today!
Check it out if you'd like to learn a bit about Apptainer's support
for cryptographic signatures, using well-established PGP
infrastructure and paradigms.&lt;/p&gt;
&lt;div class="youtube-video"&gt;
&lt;iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/qODlcbeVW?rel=0&amp;amp;wmode=transparent" frameborder="0" allow="encrypted-media" allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;&lt;p&gt;I hope you'll join us for our next session! We're live every Thursday
at 11:00 Pacific time, streaming to &lt;a class="reference external" href="https://www.youtube.com/c/CtrlIQ"&gt;YouTube&lt;/a&gt; and &lt;a class="reference external" href="https://www.linkedin.com/company/ctrliq/"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;</description><guid>urn:uuid:d647da7c-0447-476f-8fe8-23525d1b4f69</guid><pubDate>Thu, 19 May 2022 19:25:28 GMT</pubDate></item><item><title>Ancient Astronauts | Scifi Camp with Andrew Sears</title><link>https://civilfritz.net/anderbubble/2022-04-25-scifi-camp-ancient-astronauts/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;a class="reference external image-reference" href="https://civilfritz.net/anderbubble/2022-04-25-scifi-camp-ancient-astronauts/scifi-camp.jpg"&gt;&lt;img alt="Astro Warrior box art" src="https://civilfritz.net/anderbubble/2022-04-25-scifi-camp-ancient-astronauts/scifi-camp.thumbnail.jpg" style="width: 200px;"&gt;&lt;/a&gt;
&lt;p&gt;I had a lot of fun talking about &lt;a class="reference external" href="https://www.scifi.camp/1886039/10505090-ancient-astronauts"&gt;Ancient Astronauts&lt;/a&gt; with my good friend
Andrew Sears on his new podcast series &lt;a class="reference external" href="https://www.scifi.camp"&gt;Scifi Camp&lt;/a&gt;. We talk about Stargate,
Mass Effect, and the fuzzy boundary with faith and religion. I hope you enjoy
it as much as I did!&lt;/p&gt;</description><guid>urn:uuid:8cf79172-2a54-45db-90fe-72cffeaf699d</guid><pubDate>Mon, 25 Apr 2022 06:00:00 GMT</pubDate></item><item><title>the person I love the least</title><link>https://civilfritz.net/anderbubble/the-person-i-love-the-least/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;blockquote&gt;
&lt;p&gt;I really only love God as much as I love the person I love the
least.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;~ Dorothy Day, journalist&lt;/p&gt;</description><guid>urn:uuid:a3d5210f-bdc9-4d3d-ae5f-e75b3113828c</guid><pubDate>Mon, 18 Nov 2019 04:28:09 GMT</pubDate></item><item><title>God in your own image</title><link>https://civilfritz.net/anderbubble/god-in-your-own-image/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;blockquote&gt;
&lt;p&gt;You can safely assume you’ve created God in your own image when it
turns out that God hates all the same people you do.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;~ Anne Lamott quoting her “priest friend Tom” in Bird by Bird&lt;/p&gt;</description><guid>urn:uuid:8ad4aaea-701f-44fb-93c9-fdca9bd957fd</guid><pubDate>Mon, 18 Nov 2019 04:06:35 GMT</pubDate></item><item><title>an open letter to the TED team</title><link>https://civilfritz.net/anderbubble/2019-11-03-ted-letter/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;p&gt;Some time back I was talking with church leadership about possible
opportunities for me to serve the church, including potential calling
to leadership. At the time I insisted that theological differences
between myself and the church disqualified me.&lt;/p&gt;
&lt;p&gt;I still believe I have important theological differences with the
church, even if only in my own questioning and theological formation;
but I have felt a weight of consideration ever since, and I believe
that the Spirit is provoking me to action. What that means I do not
yet know, but I decided that, at the very least, I could formally put
my name in for consideration by the church, and leave it to the
church, rather than my own preemption, to disqualify me.&lt;/p&gt;
&lt;p&gt;After applying I was asked to schedule a 30-minute conversation with
the church's trustees, elders, and deacons (TED) team. As part of the
conversation, I will be expected to share responses to the following
questions:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please share a brief statement (3-5 minutes) about your faith in
Christ and how your personal relationship began and continues.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have been raised in the church my entire life, my father a Christian
Rock Band Jesus Hippie and my mother proselytized by him early in
their relationship. I didn't appreciate the full impact of my
upbringing until adulthood; but my father always had an earnest heart
for God, and my mother a love for everyone around her. I grew up
assuming these characteristics, and I am so thankful that they are
encoded so deeply in who I am.&lt;/p&gt;
&lt;p&gt;As a family we attended a Church of the Nazarene; but I also
exclusively attended a small private school, kindergarten through
highschool run by a fundamentalist Baptist church, followed by four
years at a Nazarene univeristy. Church, has been embedded in virtual
every aspect of my life for as long as I can remember; and more than
that, a pervasively diverse church context means that I have always
had to acknowledge and consider different, conflicting, and often
opposing views of God and the scripture, even within Christianity.&lt;/p&gt;
&lt;p&gt;This much pervasive access to church can make the experience of God
somewhat mundane; so it wasn't until somewhere in my teens that I
really felt God alive in my life. It's somewhat cliché, but I attended
a weekend &lt;em&gt;cursillo&lt;/em&gt; retreat run by local Methodist churches as part
of The Upper Room ministries. I shouldn't have needed it--I had
exactly the same kind of example at home already--but it was there
that I first recognized the difference between assumptively "going to
church" and living a life that is transformed by the Spirit and
oriented toward God. I continued to work (and speak) at the retreat
for years after, and my entire family attended successively afterward.&lt;/p&gt;
&lt;p&gt;The next notable impact to my faith came as a result of my wife and I
living for three and a half years in the Kingdom of Saudi
Arabia. Though we were only there professionally, the facts of being a
Christian in &lt;em&gt;the&lt;/em&gt; nation of Isalm cannot be avoided--and why should
they? There our understanding of God and Christ was deepended through
comparison and contrast with the people around us. We met several
strong Christians, largely among the students, and gathered to worship
in our homes (eventually &lt;em&gt;our home&lt;/em&gt; specifically) every week.&lt;/p&gt;
&lt;p&gt;We have worshiped almost exclusively at Presbyterian churches since
returning to the States, first at Redeemer Presbyterian in New York
and now at First Pres in Boulder, an extension of our existing desire
to challenge our own theological background and assumptions through
comparison and contrast.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is currently going on in your life spiritually? What is God
teaching you? What growth are you experiencing?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Fankly, &lt;em&gt;this&lt;/em&gt; is something going on in my life spiritually: I am
trying to be ever more open to the leading of the Spirit, particularly
where I habitually resist Him. For example: when we were first asked
to open our home to our church in Saudi Arabia, I literally said, "OK;
as long as I'm not expected to lead." Of course, it was scarcely a
year later that I was preparing scripture readings, selecting songs
for us to sing together, and distributing communion, after our
previous leaders graduated from their respective academic programs and
returned home.&lt;/p&gt;
&lt;p&gt;I love theology, and I try to not let my esoteric interests get in the
way of ministry and community. Most recently I have been reading the
work of David Bentley Hart. I finished his defense of universal
salvation "That All Shall Be Saved" and found it a profound challenge
to what might be the last vestiges of my fundamentalist assumptions
about hell; but I am currently re-reading the New Testament with his
defense in mind to better discern my assumptions about scripture from
my actual reading of it. After and during that I am also reading his
defense of theism: "The Experience of God."&lt;/p&gt;
&lt;p&gt;More personally, the Spirit is convicting me regarding how I respond
to disagreement in my marriage. I say this here only because my
comments so far have been largely academic, and I don't want to imply
that the Spirit doesn't affect me more intimately as well; but, while
I'm open to discussing such things, I tend to wait for them to be
asked explicitly as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How did you come to be a part of First Pres? What experiences have
you had as a part of our church family? What excites you about the
future?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We came to Boulder largely chasing my wife's family (in Greeley) and
the church family that we had had in Saudi: themselves largely from
the Boulder area. When we surveyed the churches in the area we found
mostly a certain type of closed conservatism, a certain type of loose
liberalism, or a certain type of seeker congregation: none of these
seemed to fulfill our expectations to be challenged toward growth in
the faith. But we found First Pres, supported by our previous
experiences at Redeemer, and encouraged by what we heard in sermon
recordings online. We attended and, in our first services we
encountered academic theology (led by Carl); passionate tradition
(bagpipes); and earnest community (in coffee with Erik).&lt;/p&gt;
&lt;p&gt;We showed up to Family Small Groups without prior arrangement; and,
though there was no group for us to join on the spot, our chidren were
cared for and we were told to enjoy the evening together.&lt;/p&gt;
&lt;p&gt;At First Pres I feel at home, in a way that I have not felt since I
left my childhood church.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do you seek to discern God's will for you personally? How might
you discern God's will in a group setting?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I seek God's will for me personally through prayer and study; but I
cannot ignore the transforming work of the Spirit in my life as
well. I can scarcely believe my life, and I am excited by the prospect
of even deeper relationship with God.&lt;/p&gt;
&lt;p&gt;In a group setting, if my self-assessment is accurate, I have a
tendency and aptitude for listening to all perspectives and helping to
bring parties to at least a common understanding. I consider what is
said long after a group meeting, and often follow-up off-cycle to ask
questions or assert possibilities. I pray, but more generally I
believe that I feel the Spirit leading throughout the day, and I hope
that I would be able to discern that leading in a more formal group as
well.&lt;/p&gt;
&lt;p&gt;Perhaps more technically, I argue. And I hope that that is not
understood as &lt;em&gt;argumentative&lt;/em&gt;; but I try what I believe to be Truth by
presenting it for scruitiny. I am strong in my beliefs, but I am also
quick to abandon my own misunderstandings. When I argue, I argue from
scripture and (where it is a help and not a distraction)
well-established shared belief.&lt;/p&gt;
&lt;hr class="docutils"&gt;
&lt;p&gt;I was also pointed to the Essential Tenents of ECO &lt;a class="footnote-reference brackets" href="https://civilfritz.net/anderbubble/2019-11-03-ted-letter/#footnote-1" id="footnote-reference-1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;; and it is here
that I am afraid I will have the most trouble. As above, I don't
intend to be argumentative; but I also do not want to conceal
anything, so I will do my best to enumerate my concerns here.&lt;/p&gt;
&lt;p&gt;I want to be clear: I do not begrudge ECO or First Pres these
essential tenents. I recognize the importance of common doctrine, and
I value the diversity of Christianity as expressed in the diversity
among congregations: that diversity does not necessarily need to be
expressed &lt;em&gt;within&lt;/em&gt; each congregation. Still, First Pres is my home;
and if I am to serve here, I have to be honest about what I believe as
well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regarding "God’s Word: The Authority for Our Confession"&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have serious concerns regarding the common definition of the Word of
God. Even today, Carl preached in his sermon that God's word is
incarnate, proclaimed, and written; but the essential tenents omit
acknowledgement of God's word as proclaimed altogether.&lt;/p&gt;
&lt;p&gt;I further fear, and have for many years, that the veneration of the
so-called "written Word of God" is a form of idolatry: the Bible
serves as an image of God's Word, and its worship (in everything but
name) is troubling to me. More striclty, I consider the scripture a
&lt;em&gt;testament&lt;/em&gt; to the Word of God, not the Word itself (as opposed to
Christ, the Word Incarnate.)&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;do&lt;/em&gt; acknowledge, as Paul taught Timothy, that "All Scripture is
breathed out by God and profitable for teaching, for reproof, for
correction, and for training in righteousness, that the man of God may
be complete, equipped for every good work." But I'll still point out
that Paul certainly was not talking about the gospels, the revelation,
or much less the epistles (particularly that he was contemporaneously
writing), but "the sacred writings" that Timothy had been acquanted
with "from childhood." This is not to say that the Christian
scriptures are not themselves "Breathed out by God," and I have faith
in the work of the Spirit in preserving the Scripture through church
tradition and study; but I believe the true nature of the scripture is
more complex than is often exhorted in such essential tenents, and the
true nature of the Word of God more complex still.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We confess that God alone is Lord of the conscience, but this
freedom is for the purpose of allowing us to be subject always and
primarily to God’s Word.&lt;/p&gt;
&lt;p&gt;We are happy to confess ourselves captive to the Word of God&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Perhaps there is some scriptural basis for this imagery that I am
missing; but without it I am troubled by this imagery. Life in Christ
is denotatively freedom; we are not captives, but heirs, ransomed from
sin and death. I do not deny that "the Spirit will never prompt our
conscience to conclusions that are at odds with the Scriptures that He
has inspired"--perhaps this is an unnecessary complaint; but the heart
with which we approach the Word matters to me, and I find it important
to recognize that the Spirit changes our desires to be those of God;
we are not &lt;em&gt;captive&lt;/em&gt; to the Word, but freed by it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regarding "secondary authority"&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[W]e affirm the secondary authority of the following ECO
Confessional Standards as faithful expositions of the Word of God:
Nicene Creed, Apostles’ Creed, Heidelberg Catechism, Westminster
Confession, Westminster Shorter Catechism, Westminster Larger
Catechism and the Theological Declaration of Barmen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don't know how I missed this before; but this greatly expands the
scope of the so-called "essential" tenents. I have studied some of
these; but certainly not all, and I would be loathe to assumptively
confirm their authority in my theology, or my adherence to them,
without further study (and given the differences raised by the
primarily-stated essential tenents, I can only expect there would be
further differences in a greater body of confessions).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;regarding "Trinity and Incarnation: The Two Central Christian
Mysteries"&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have strong, fundamental concerns regarding the doctrine of the
Trinity.&lt;/p&gt;
&lt;p&gt;But first let me be clear: I believe in God, non-contingent,
transcendent, Father and creator of all. I believe that Jesus, the
Christ, is the incarnate Word of God, one with the Father, in the
Father and in whom the Father is. I believe in the Holy Spirit, the
paraclete, the helper and advocate, who comes in the name of Christ
and is sent by the Father, the Spirit of Christ and, thus, the Father.&lt;/p&gt;
&lt;p&gt;But there is a great deal of distance between that and bold claims
about God as having a fundamentally "trinitarian" nature. This is not
quite idolatry; but it is seeking to define God by our experience of
him, where he is more accurately transcendent. God has revealed
himself freqntly through social terms, but it is eisegesis to read
this as emphatically trinitarian. God did not direct Israel, for
example, to worship "God the Creator; God the Fire of the Bush; and
God the Pillar of Cloud"; but God. And if God did not direct worship
to a plurality, but a unity God, then we should not break from that
direction.&lt;/p&gt;
&lt;p&gt;And what of the Word of God? Surely the Word of God is God, as John
proclaimed. But if Christ is one part of a trinity God, then surely
the Word is a person of God, existing before "the Word became flesh
and dwelt among us." So perhaps the trinity is more accurately "the
Father, the Word, and the Spirit"?&lt;/p&gt;
&lt;p&gt;But I am particularly troubled by extra-Biblical habits I have
observed recently of praying to individual "members of the trinity";
we are to pray to God, the Father, as Christ did and directed us to.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;affirmed by all Christians everywhere&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is simply not true: there have been many Christians that have had
different interpretations and understandings of the being of Christ. I
may not agree with them, but to ignore them is distracting and
disingenuous.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;like us in having both a human soul and a human body&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This anthropology isn't Biblical, so far as I can tell. Maybe it is
technically true to say that Christ had a human soul; but this
statement does not mean what a western mind will infer from it. God
did not make a human body and then put a human soul into it; man
&lt;em&gt;became&lt;/em&gt; a living soul when God breathed into it. As such, to say that
Christ is "like us in every way but sin" but then say that he has a
"human soul" is both non-sensical and contradictory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regarding "God’s grace in Christ"&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our desires are no longer trustworthy guides to goodness, and what
seems natural to us no longer corresponds to God’s design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I hope that these tenents do not mean to indicate that we who are
alive in the Spirit are unable to discern good. "We have received
[...] the Spirit who is from God, that we might understand the things
freely given us by God. And we impart this in words not taught by
human wisdom but taught by the Spirit, interpreting spiritual truths
to those who are spiritual." It is the promise of life in the Spirit
that our hearts are turned towards the things of God; that our desires
are made trustworthy, being those of the Spirit.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Jesus takes our place both in bearing the weight of condemnation
against our sin on the cross&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I require further study here; but I believe this to be incorrect
theology. Christ did not "bear the weight of [presumably God's]
condemnation against our sin"; in stead, his death paid the ransom to
free us from our slavery to death.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regarding "Election for salvation and service"&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I am thankful that ECO does not, at least here, go so far as to
proclaim limited atonement an essential tenent. (Perhaps it does
implicitly by extension through one of the "secondary" authorities.)
But I must say that the language of atonement does not appear, to me,
to be concerned with eternal salvation or the church in general, but
of specifically the work of the Spirit in Israel in the church
age. "Israel failed to obtain what it was seeking. The elect obtained
it, but the rest were hardened." But later "a partial hardening has
come upon Israel, until the fullness of the Gentiles has come in. And
in this way all Israel will be saved."&lt;/p&gt;
&lt;p&gt;"just as you were at one time disobedient to God but now have received
mercy because of their disobedience, so they too have now been
disobedient in order that by the mercy shown to you they also may now
receive mercy. For God has consigned all to disobedience, that he may
have mercy on all."&lt;/p&gt;
&lt;p&gt;Therefore I hold that, at the very least, the concept of election as
expressed by Paul does not reflect eternal salvation, or its absence;
but the work of God in the lives of some for the age towards an
ultimately redemptive purpose for all.&lt;/p&gt;
&lt;p&gt;One last thing: Paul explicitly doesn't use the word "elect" to refer to
Gentiles; only Israel.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regarding "Living in obedience to the Word of God"&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I note here only to claim this commandment as expressed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;pursue truth, even when such pursuit is costly, and defend truth
when it is challenged, recognizing that truth is in order to
goodness and that its preservation matters;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="footnote-1" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="https://civilfritz.net/anderbubble/2019-11-03-ted-letter/#footnote-reference-1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.eco-pres.org/essential-tenets/"&gt;ECO Constitution (Polity and Essential Tenets)&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;</description><guid>urn:uuid:d2274d6a-920c-475d-8211-958ea10760c8</guid><pubDate>Sun, 03 Nov 2019 22:57:14 GMT</pubDate></item><item><title>on the defiance of expectations in Epic Mickey</title><link>https://civilfritz.net/anderbubble/epic-mickey-defies-expectations/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;p&gt;I love it when a game defies my expectations sufficiently to make me
uncomfortable. If a game can make me feel discomfort, there's
something worth considering there--something that merits deeper
understanding. There are things that a game can say about the player
that couldn't be said in any other medium, and sometimes the message
is all the more effective when I'm caught vulnerably by my own
assumptions.&lt;/p&gt;
&lt;p&gt;My first experience with this kind of discomfort came during my first
playthrough of Mass Effect 2. Near the end of the game Shepard--the
protagonist and player character--has accumulated a band of
compatriots toward a final mission to stop the Reapers; but just
before that final mission, the ship's crew is abducted by the
Collectors.&lt;/p&gt;
&lt;p&gt;Mass Effect is a role-playing game, and understanding genre tropes is
an important aspect of interpreting a work and its impact. Many
fantasy role-playing games have a similar plot point: the hero has
completed his preparations. He is near the end of his journey. The
stakes have never been higher, and the situation is urgent: Meteor is
about to crash into Midgar; Gannon is about to destroy Hyrule; or, as
is the case in Mass Effect 2, the Reapers are preparing to consume all
life in the galaxy.&lt;/p&gt;
&lt;p&gt;But role-playing games have another trope: the side quest. These are
typically available throughout the game; but the moment before the
final climactic mission is the last chance in most RPGs to finish up
any side-quests that have been left undone. In Mass Effect 2, side
quests take the form of "loyalty missions"--character-specific
missions that provide additional backstory and inter-personal context
for the members of your cohort. Completing these missions also
improves an invisible but important loyalty stat which affects how
team members respond to Shepard.&lt;/p&gt;
&lt;p&gt;I'm a bit of a completionist, so I took this opportunity before the
final mission to complete all of these loyalty missions. I did this
all while I poked fun at the video game tropes on display: the big
bad, poised and ready to attack; we, the player character, traipsing
about the galaxy on unrelated menial missions. After all: Meteor won't
crash into Midgar until the plot is ready for it; Gannon never will
destroy Hyrule; and the Collectors will wait around until Shepard is
good and ready to face them.&lt;/p&gt;
&lt;p&gt;But that's not what happens. When I finally did embark on the final
mission to stop the Collectors and rescue the crew, we found only
Dr. Chakwas alive.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;They're gone. All of them. I'm the only one left.&lt;/p&gt;
&lt;p&gt;I watched them die. They were... processed--rendered down into some
kind of raw genetic paste and pumped through these tubes.&lt;/p&gt;
&lt;p&gt;What took you so long, Shepard? You could have saved them if you'd
gotten here sooner!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dr. Chakwas' words are true. While I was taking my time maximizing a
gamified loyalty stat, the game was monitoring my activities after the
abduction of the crew. Leave immediately, and you may save them all;
but the longer you wait, the more of them die.&lt;/p&gt;
&lt;p&gt;With this, the game defies trope, and punishes the player for
approaching the work as a simple genre piece. In reality, Shephard
would never meander about, but would prioritize the mission and the
retrieval of the crew. But it's just a game, right?&lt;/p&gt;
&lt;p&gt;But it is the fact that it &lt;em&gt;is&lt;/em&gt; a game that enables this experience. A
character in a book won't die because you waited a week to read the
last chapter; but in my Mass Effect, we lost the entire crew: named
characters with backstories and interactions that had developed
throughout the game. And the consequences don't end there, either:
Mass Effect is a three-part series, and the death of these characters
carries on even into the next game.&lt;/p&gt;
&lt;p&gt;Mass Effect 2 expects you to care about its characters; and, if you
don't--if you just play it like a video game, expecting it to behave
like other video games--it punishes you for it by taking those
characters away.&lt;/p&gt;
&lt;p&gt;But even then, I never would have expected to feel this same defiance
of expectation from Epic Mickey.&lt;/p&gt;
&lt;!--
.. thumbnail:: small-pete.png
   :width: 15em
   :alt: Small Pete
   :align: right
--&gt;

&lt;p&gt;Epic Mickey could hardly be more different from Mass Effect. It's a
third-person platforming character action game with light adventure
elements. It's a children's game, contrasted with media hysteria
regarding Mass Effect's "mature" content. More immediately, Mass
Effect is a good game; and I definitely wasn't enjoying Epic Mickey.&lt;/p&gt;
&lt;p&gt;But I have kids, and those kids were excited about Mickey, so I was
playing through it as a social activity with them. I really wasn't
taking it seriously: jump on the platforms; paint the environment with
the magic paintbrush; mash "A" when characters talk to you; make
"progress."&lt;/p&gt;
&lt;p&gt;Not too far into the game, I ran into a character called "Small Pete,"
a rendition of a classic Disney character, "Pete," who often serves as
the antagonist of a Mickey Mouse story.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I spent years getting' along with gremlins. Only had to knock 'em
around on occasion. Then, the ONE TIME I crash my boat into their
village, they seem to think I'm some kinda villain.&lt;/p&gt;
&lt;p&gt;Not that I give two hoots what they think, but it WAS an
accident. And my ship's log will prove it.&lt;/p&gt;
&lt;p&gt;Those little monsters won't let me near the wreck to get it,
though. Hmm... I'll bet they'd let you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was immediately suspicious of Small Pete's story (assuming I paid it
any mind at all, beyond just mashing "A"); but we got a quest
objective and moved on.&lt;/p&gt;
&lt;p&gt;I continued jumping between platforms, tagging the environment, and
mashing "A," until we met Gremlin Shaky.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Gremlin Shaky offers to trade a pin for Pete's ship's log" src="https://civilfritz.net/anderbubble/epic-mickey-defies-expectations/gremlin-shaky.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I smell treasure! You found it!&lt;/p&gt;
&lt;p&gt;How's about you trade me that ship's log for a flashy new pin?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I still wasn't paying attention. Why would I? The platforming was
mediocre. The characters were either flat or carbon-copies of each
other. Each gremlin looks the same as all the others. So I interpreted
this interaction with the same level of attention that I would pay to
most collect-a-thon games:&lt;/p&gt;
&lt;p&gt;"Oh, right. The ship's log. I guess I picked it up along the way. Pete
wanted us to get that for him, right? What was that for, again? This
must be the guy I'm supposed to give it to. And when I do I'll get a
pin as a reward, eh? Ok, I guess it's a collectible, so I guess I'll
do it."&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thank you very much. This will make excellent reading. Here's your
pin.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But that wasn't all there was to it. Immediately after finishing the
interaction I received a "quest failed" notification.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Quest Failed, find Small Pete's Ship's log" src="https://civilfritz.net/anderbubble/epic-mickey-defies-expectations/quest-failed-small-pete.png"&gt;&lt;/p&gt;
&lt;p&gt;I kept playing, just accepting that I had failed the quest, and
probably missed out on some minimal benefit. But something about the
interaction bothered me. Small Pete seemed to be a character teetering
on the edge of villany. He was willing to "knock 'em around on
occasion"; but he seemed genuinely (if covertly) concerned with
clearning his name. He wasn't a villain &lt;em&gt;yet&lt;/em&gt;. He was a bully.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So you left my ship's log with those grubby gremlins, eh? Well,
here's a little taste of what happens to those who cross me!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I had betrayed Small Pete. I hadn't done it out of malice. Worse: I
had paid him no mind. He asked for help, and I ignored
him. Eventually, I traded his name for a collectible pin I didn't even
care about. In a literal sense, I had turned him into a villain: Small
Pete had become a video-game boss, generating a combat encounter to
punctuate the chapter.&lt;/p&gt;
&lt;p&gt;I found myself considering what it would take to correct this mistaken
path through the game's narrative. I had overwritten my save several
times since I had given Pete's ship's log to Gremlin Shaky. I would
have to start the game over from the beginning.&lt;/p&gt;
&lt;p&gt;The very fact that I was considering it made me uncomfortable. I did
not enjoy playing this game. But, for the sake of a fictional
character as absurd as Small Pete, I was considering sacrificing some
portion of my time in pursuit of his redemption.&lt;/p&gt;
&lt;p&gt;I tell my kids that it's part of a parent's job to give them
consequences that they can learn from and grow through, while
protecting them from consequences that they can't recover from, if
only for a time. In a small, but very real, way, Epic Mickey was that
for me. I ignored a call for help. I was careless. A character was
treated unjustly, and that injustice led him to embrace his own darker
tendencies.&lt;/p&gt;
&lt;p&gt;I never did go back and do right by Small Pete. In fact, I don't think
I played the game again after that. I'm sure we were called down for
dinner, and then distracted by another game I enjoyed playing
more. But I still think about Small Pete, about the time I didn't pay
enough attention, and about the consequences that might develop when I
allow myself to become just a little bit more callous to the world
around me.&lt;/p&gt;</description><guid>urn:uuid:622aeb4e-bfd3-41c2-9324-76ad2fee3f39</guid><pubDate>Mon, 25 Mar 2019 06:00:00 GMT</pubDate></item><item><title>Home (POA)</title><link>https://civilfritz.net/anderbubble/home/</link><dc:creator>Jonathon Anderson</dc:creator><description>&lt;p&gt;I just posted the entirety of the &lt;a class="reference external" href="https://civilfritz.net/music/album-poa-home/"&gt;P.O.A. album, "Home."&lt;/a&gt;&lt;/p&gt;</description><guid>urn:uuid:203ea018-628e-4ce6-9087-33a4671fe405</guid><pubDate>Mon, 17 Sep 2018 05:14:00 GMT</pubDate></item></channel></rss>