]> birchwood-abbey.net Git - Network.git/commitdiff
Update README.html.
authorMatt Birkholz <matt@birchwood-abbey.net>
Fri, 2 Jan 2026 22:09:08 +0000 (15:09 -0700)
committerMatt Birkholz <matt@birchwood-abbey.net>
Fri, 2 Jan 2026 22:09:08 +0000 (15:09 -0700)
README.html

index 88be3f29d46b749f4d3b15a468b4536bf863b29a..bba7d6710f19d035c3b6264d8deca61fcbbdb9d3 100644 (file)
@@ -3,7 +3,7 @@
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
 <head>
-<!-- 2025-11-23 Sun 13:07 -->
+<!-- 2026-01-02 Fri 15:07 -->
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1" />
 <title>Birchwood Abbey Networks</title>
@@ -24,8 +24,8 @@ idiosyncrasies.  The roles herein are abbey specific, emphasized by
 the <code>abbey-</code> prefix on their names.  These roles are applied <i>after</i>
 the generic institutional roles (again, documented <a href="Institute/README.html">here</a>).
 </p>
-<div id="outline-container-orgf3ea803" class="outline-2">
-<h2 id="orgf3ea803"><span class="section-number-2">1.</span> Overview</h2>
+<div id="outline-container-org961589e" class="outline-2">
+<h2 id="org961589e"><span class="section-number-2">1.</span> Overview</h2>
 <div class="outline-text-2" id="text-1">
 <p>
 A Small Institute makes security and privacy top priorities but
@@ -64,7 +64,7 @@ map is very similar, with differences mainly in terminology,
 philosophy, attitude.
 </p>
 
-<pre class="example" id="org4276841">
+<pre class="example" id="org0b1f40c">
                 |                                                   
                 =                                                   
               _|||_                                                 
@@ -103,8 +103,8 @@ philosophy, attitude.
 </pre>
 </div>
 </div>
-<div id="outline-container-org02a341b" class="outline-2">
-<h2 id="org02a341b"><span class="section-number-2">2.</span> The Abbey Particulars</h2>
+<div id="outline-container-orgca2c4ea" class="outline-2">
+<h2 id="orgca2c4ea"><span class="section-number-2">2.</span> The Abbey Particulars</h2>
 <div class="outline-text-2" id="text-2">
 <p>
 The abbey's public particulars are included below.  They are the
@@ -134,8 +134,8 @@ into <a href="private_ex/vars-abbey.yml"><q>private_ex/vars-abbey.yml</q></a>.
 </p>
 </div>
 </div>
-<div id="outline-container-orgbfc625e" class="outline-2">
-<h2 id="orgbfc625e"><span class="section-number-2">3.</span> The Abbey Front Role</h2>
+<div id="outline-container-org1b50b4c" class="outline-2">
+<h2 id="org1b50b4c"><span class="section-number-2">3.</span> The Abbey Front Role</h2>
 <div class="outline-text-2" id="text-3">
 <p>
 Birchwood Abbey's front door is a Digital Ocean Droplet configured as
@@ -144,8 +144,8 @@ with Apache2, spooling email with Postfix and serving it with
 Dovecot-IMAPd, and hosting a VPN with WireGuard™.
 </p>
 </div>
-<div id="outline-container-org5e99273" class="outline-3">
-<h3 id="org5e99273"><span class="section-number-3">3.1.</span> Install Emacs</h3>
+<div id="outline-container-orgf6f9f79" class="outline-3">
+<h3 id="orgf6f9f79"><span class="section-number-3">3.1.</span> Install Emacs</h3>
 <div class="outline-text-3" id="text-3-1">
 <p>
 The monks of the abbey are masters of the staff (bo) and Emacs.
@@ -160,8 +160,8 @@ The monks of the abbey are masters of the staff (bo) and Emacs.
 </div>
 </div>
 </div>
-<div id="outline-container-orgb7a2cfb" class="outline-3">
-<h3 id="orgb7a2cfb"><span class="section-number-3">3.2.</span> Configure Public Email Aliases</h3>
+<div id="outline-container-org553cc85" class="outline-3">
+<h3 id="org553cc85"><span class="section-number-3">3.2.</span> Configure Public Email Aliases</h3>
 <div class="outline-text-3" id="text-3-2">
 <p>
 The abbey uses several additional email aliases.  These are the public
@@ -201,11 +201,11 @@ from there, forwarding <code>sysadm</code> to a real person.
 </div>
 </div>
 </div>
-<div id="outline-container-org267af54" class="outline-3">
-<h3 id="org267af54"><span class="section-number-3">3.3.</span> Configure Git Daemon on Front</h3>
+<div id="outline-container-org1f28e49" class="outline-3">
+<h3 id="org1f28e49"><span class="section-number-3">3.3.</span> Configure Git Daemon on Front</h3>
 <div class="outline-text-3" id="text-3-3">
 <p>
-The abbey publishes member Git repositories with <code>git-daemon</code>.  If
+The abbey publishes member Git repositories with <code>git daemon</code>.  If
 Dick (a member of A Small Institute) builds a Foo project Git
 repository in <q>~/foo/</q>, he can publish it to the campus by
 symbolically linking its <q>.git/</q> into <q>~/Public/Git/</q> on Core.  If the
@@ -244,59 +244,45 @@ rsync -av --del small.institute.org:Public/foo/ ~/Public/foo/
 </pre>
 
 <p>
-With SystemD and the <code>git-daemon-sysvinit</code> package installed, SystemD
-supervises a <code>git-daemon</code> service unit launched with
-<code>/etc/init.d/git-daemon</code>.  The old SysV <code>init</code> script gets its
-configuration from the customary <q>/etc/default/git-daemon</q> file.  The
-script then constructs the appropriate <code>git-daemon</code> command.  The
-<code>git-daemon(1)</code> manual page explains the command options in detail.
-As explained in <q>/usr/share/doc/git-daemon-sysvinit/README.Debian</q>,
-the service must be enabled by setting <code>GIT_DAEMON_ENABLE</code> to <code>true</code>.
-The base path is also changed to agree with <q>gitweb.cgi</q>.
+The <code>git daemon</code> is run by SystemD per the <q>git-daemon.service</q> file.
+The <code>git-daemon(1)</code> manual page explains the options in detail.  The
+<code>--base-path</code> option should agree with <code>$projectroot</code> in the
+<q>/etc/gitweb.conf</q> file installed <a href="#orgc63f8e5">here</a>.
 </p>
 
 <p>
-User repositories are enabled by adding a <code>user-path</code> option <i>and</i>
-disabling the default whitelist.  To specify an empty whitelist, the
-default (a list of one directory: <q>/var/lib/git</q>) must be avoided by
-setting <code>GIT_DAEMON_DIRECTORY</code> to a blank (not empty) string.
+User repositories are enabled by adding a <code>--user-path</code> option <i>and</i>
+specifying an empty whitelist (i.e., no directories listed on the
+command line).
+</p>
+
+<p>
+The <code>git daemon</code> is run as an unprivileged system user: <code>gitd</code>.  Thus
+it has access to anything world readable.  However <code>git</code> must be
+willing to forgive the fact that <code>gitd</code> does not <i>own</i> any of the
+repositories it is serving.  To accomplish this, <code>gitd</code> gets a home
+directory, <q>/home/gitd/</q>, in which is installed a <q>.gitconfig</q> created
+by a <code>git config --global --add safe.directory \*</code> command.
 </p>
 
 <p>
 The code below is included in both Front and Core configurations,
-which should be nearly identical for testing purposes.  Rather than
+which should be (nearly) identical for testing purposes.  Rather than
 factor out small roles like <code>abbey-git-server</code>, Emacs Org Mode's Noweb
 support does the duplication, by multiple references to code blocks
-like <code>git-tasks</code> and <code>git-handlers</code>.
+like <code>gitd-tasks</code> and <code>gitd-handlers</code>.
 </p>
 
 <div class="org-src-container">
 <a href="roles_t/abbey-front/tasks/main.yml"><q>roles_t/abbey-front/tasks/main.yml</q></a><pre class="src src-conf"><code>
-&lt;&lt;git-tasks&gt;&gt;
+&lt;&lt;gitd-tasks&gt;&gt;
 </code></pre>
 </div>
 
 <div class="org-src-container">
-<code>git-tasks</code><pre class="src src-conf" id="org762b923"><code>- name: Install git daemon.
+<code>gitd-tasks</code><pre class="src src-conf" id="org8125b8a"><code>- name: Install git.
   become: yes
-  <span class="org-variable-name">apt: pkg</span>=git-daemon-sysvinit
-
-- name: Configure git daemon.
-  become: yes
-  lineinfile:
-    path: /etc/default/git-daemon
-    regexp: <span class="org-string">"{{ item.patt }}"</span>
-    line: <span class="org-string">"{{ item.line }}"</span>
-  loop:
-  - patt: <span class="org-string">'^GIT_DAEMON_ENABLE *='</span>
-    line: <span class="org-string">'GIT_DAEMON_ENABLE=true'</span>
-  - patt: <span class="org-string">'^GIT_DAEMON_OPTIONS *='</span>
-    line: <span class="org-string">'GIT_DAEMON_OPTIONS="--user-path=Public/Git"'</span>
-  - patt: <span class="org-string">'^GIT_DAEMON_BASE_PATH *='</span>
-    line: <span class="org-string">'GIT_DAEMON_BASE_PATH="/var/www/git"'</span>
-  - patt: <span class="org-string">'^GIT_DAEMON_DIRECTORY *='</span>
-    line: <span class="org-string">'GIT_DAEMON_DIRECTORY=" "'</span>
-  notify: Restart git daemon.
+  <span class="org-variable-name">apt: pkg</span>=git
 
 - name: Create /var/www/git/.
   become: yes
@@ -305,27 +291,90 @@ like <code>git-tasks</code> and <code>git-handlers</code>.
     state: directory
     group: staff
     <span class="org-variable-name">mode: u</span>=rwx,g=srwx,o=rx
+
+- name: Create user gitd.
+  become: yes
+  user:
+    name: gitd
+    password: <span class="org-string">"!"</span>
+    home: /home/gitd
+    shell: /usr/bin/git-shell
+
+- name: Create /home/gitd/.gitconfig.
+  become: yes
+  copy:
+    content: |
+      [<span class="org-type">safe</span>]
+        <span class="org-variable-name">directory</span> = *
+    dest: /home/gitd/.gitconfig
+    owner: gitd
+    group: gitd
+    <span class="org-variable-name">mode: u</span>=rw,g=r,o=r
+
+- name: Configure git-daemon.
+  become: yes
+  copy:
+    content: |
+        [<span class="org-type">Unit</span>]
+        <span class="org-variable-name">Description</span>=Git Daemon
+        <span class="org-variable-name">After</span>=network.target
+
+        [<span class="org-type">Service</span>]
+        <span class="org-variable-name">ExecStart</span>=/usr/bin/git daemon \
+                        --reuseaddr --verbose \
+                        <span class="org-variable-name">--user-path</span>=Public/Git \
+                        <span class="org-variable-name">--base-path</span>=/var/www/git
+
+        <span class="org-variable-name">Restart</span>=always
+        <span class="org-variable-name">RestartSec</span>=5
+
+        <span class="org-variable-name">StandardOutput</span>=journal
+        <span class="org-variable-name">StandardError</span>=journal
+        <span class="org-variable-name">SyslogIdentifier</span>=git-daemon
+
+        <span class="org-variable-name">User</span>=gitd
+        <span class="org-variable-name">Group</span>=gitd
+
+        [<span class="org-type">Install</span>]
+        <span class="org-variable-name">WantedBy</span>=multi-user.target
+    dest: /etc/systemd/system/git-daemon.service
+  notify:
+  - Reload systemd.
+  - Restart git-daemon.
+
+- name: Enable git-daemon.
+  become: yes
+  systemd:
+    service: git-daemon
+    enabled: yes
 </code></pre>
 </div>
 
 <div class="org-src-container">
 <a href="roles_t/abbey-front/handlers/main.yml"><q>roles_t/abbey-front/handlers/main.yml</q></a><pre class="src src-conf"><code>
-&lt;&lt;git-handlers&gt;&gt;
+&lt;&lt;gitd-handlers&gt;&gt;
 </code></pre>
 </div>
 
 <div class="org-src-container">
-<code>git-handlers</code><pre class="src src-conf" id="org78c8daa"><code>
-- name: Restart git daemon.
+<code>gitd-handlers</code><pre class="src src-conf" id="orgb920ea7"><code>
+- name: Reload systemd.
+  become: yes
+  systemd:
+    daemon-reload: yes
+
+- name: Restart git-daemon.
   become: yes
-  command: systemctl restart git-daemon
+  systemd:
+    service: git-daemon
+    state: restarted
   tags: actualizer
 </code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org699d236" class="outline-3">
-<h3 id="org699d236"><span class="section-number-3">3.4.</span> Configure Gitweb on Front</h3>
+<div id="outline-container-org0019fd0" class="outline-3">
+<h3 id="org0019fd0"><span class="section-number-3">3.4.</span> Configure Gitweb on Front</h3>
 <div class="outline-text-3" id="text-3-4">
 <p>
 The abbey provides an HTML interface to members' public Git
@@ -346,13 +395,13 @@ page, the second <code>RewriteRule</code> specifies the root directory of the
 user's public Git repositories via the <code>GITWEB_PROJECTROOT</code>
 environment variable.  It makes <code>http://www/~dick/git</code> run
 Gitweb with the project root <q>~dick/Public/Git/</q>, the same directory
-the <code>git-daemon</code> makes available.  The first <code>RewriteRule</code> directs
+the <code>git daemon</code> makes available.  The first <code>RewriteRule</code> directs
 URLs with no user name to the default.  Thus <code>http://www/git</code>
 lists the repositories found in <q>/var/www/git/</q>.
 </p>
 
 <div class="org-src-container">
-<code>apache-gitweb</code><pre class="src src-conf" id="org087507e"><code>
+<code>apache-gitweb</code><pre class="src src-conf" id="org72f1894"><code>
 Alias /gitweb-static/ /usr/share/gitweb/static/
 &lt;Directory <span class="org-string">"/usr/share/gitweb/static/"</span>&gt;
     Options MultiViews
@@ -410,7 +459,13 @@ web site <q>/favicon.ico</q>.
 </p>
 
 <div class="org-src-container">
-<code>apache-gitweb-tasks</code><pre class="src src-conf" id="org5d6da49"><code>- name: Enable Apache2 rewrite module for Gitweb.
+<a href="roles_t/abbey-front/tasks/main.yml"><q>roles_t/abbey-front/tasks/main.yml</q></a><pre class="src src-conf"><code>
+&lt;&lt;gitweb-tasks&gt;&gt;
+</code></pre>
+</div>
+
+<div class="org-src-container">
+<code>gitweb-tasks</code><pre class="src src-conf" id="orgc63f8e5"><code>- name: Enable Apache2 rewrite module for Gitweb.
   become: yes
   <span class="org-variable-name">apache2_module: name</span>=rewrite
   notify: Restart Apache2.
@@ -447,7 +502,13 @@ web site <q>/favicon.ico</q>.
 </div>
 
 <div class="org-src-container">
-<code>apache-gitweb-handlers</code><pre class="src src-conf" id="org0a16216"><code>- name: Restart Apache2.
+<a href="roles_t/abbey-front/handlers/main.yml"><q>roles_t/abbey-front/handlers/main.yml</q></a><pre class="src src-conf"><code>
+&lt;&lt;gitweb-handlers&gt;&gt;
+</code></pre>
+</div>
+
+<div class="org-src-container">
+<code>gitweb-handlers</code><pre class="src src-conf" id="orga0c7f06"><code>- name: Restart Apache2.
   become: yes
   systemd:
     service: apache2
@@ -457,8 +518,8 @@ web site <q>/favicon.ico</q>.
 </div>
 </div>
 </div>
-<div id="outline-container-orged32002" class="outline-3">
-<h3 id="orged32002"><span class="section-number-3">3.5.</span> Configure Apache for Abbey Documentation</h3>
+<div id="outline-container-orge27fab4" class="outline-3">
+<h3 id="orge27fab4"><span class="section-number-3">3.5.</span> Configure Apache for Abbey Documentation</h3>
 <div class="outline-text-3" id="text-3-5">
 <p>
 Some of the directives added to the <q>-vhost.conf</q> file are needed by
@@ -476,7 +537,7 @@ filename suffixes.
 </p>
 
 <div class="org-src-container">
-<code>apache-abbey</code><pre class="src src-conf" id="org729ab6e"><code>&lt;Directory {{ docroot }}/Abbey/&gt;
+<code>apache-abbey</code><pre class="src src-conf" id="org635af88"><code>&lt;Directory {{ docroot }}/Abbey/&gt;
     AllowOverride Indexes FileInfo
     Options +Indexes +FollowSymLinks
 &lt;/Directory&gt;
@@ -499,8 +560,8 @@ AddType text/plain private pub public_vpn req rev sample txt yml
 </div>
 </div>
 </div>
-<div id="outline-container-orgdd6d40b" class="outline-3">
-<h3 id="orgdd6d40b"><span class="section-number-3">3.6.</span> Configure Photos URLs on Front</h3>
+<div id="outline-container-org48f710e" class="outline-3">
+<h3 id="org48f710e"><span class="section-number-3">3.6.</span> Configure Photos URLs on Front</h3>
 <div class="outline-text-3" id="text-3-6">
 <p>
 Some of the directives added to the <q>-vhost.conf</q> file map the abbey's
@@ -512,7 +573,7 @@ matching configurations for accurate previews and tests.
 </p>
 
 <div class="org-src-container">
-<code>apache-photos</code><pre class="src src-conf" id="orgee7659b"><code>
+<code>apache-photos</code><pre class="src src-conf" id="org5096221"><code>
 RedirectMatch /Photos$ /Photos/
 RedirectMatch /Photos/(20[0-9][0-9])_([0-9][0-9])_([0-9][0-9])$ \
               /Photos/$1_$2_$3/
@@ -525,8 +586,8 @@ AliasMatch /Photos/$ {{ docroot }}/Photos/index.html
 </div>
 </div>
 </div>
-<div id="outline-container-org4c832e7" class="outline-3">
-<h3 id="org4c832e7"><span class="section-number-3">3.7.</span> Configure Apache on Front</h3>
+<div id="outline-container-orgd0a2883" class="outline-3">
+<h3 id="orgd0a2883"><span class="section-number-3">3.7.</span> Configure Apache on Front</h3>
 <div class="outline-text-3" id="text-3-7">
 <p>
 The abbey needs to add some Apache2 configuration directives to the
@@ -537,11 +598,11 @@ The abbey simply creates a <q>birchwood-abbey.net-vhost.conf</q> file in
 </p>
 
 <p>
-The following task adds the <a href="#org729ab6e"><code>apache-abbey</code></a>, <a href="#orgee7659b"><code>apache-photos</code></a>, and
-<a href="#org087507e"><code>apache-gitweb</code></a> directives described above to the <q>-vhost.conf</q> file,
+The following task adds the <a href="#org635af88"><code>apache-abbey</code></a>, <a href="#org5096221"><code>apache-photos</code></a>, and
+<a href="#org72f1894"><code>apache-gitweb</code></a> directives described above to the <q>-vhost.conf</q> file,
 and includes <q>options-ssl-apache.conf</q> from <q>/etc/letsencrypt/</q>.  The
 rest of the Let's Encrypt configuration is discussed in the following
-<a href="#org19b0c76">Install Let's Encrypt</a> section.
+<a href="#org84b4a08">Install Let's Encrypt</a> section.
 </p>
 
 <div class="org-src-container">
@@ -559,20 +620,12 @@ rest of the Let's Encrypt configuration is discussed in the following
         IncludeOptional /etc/letsencrypt/options-ssl-apache.conf
     dest: /etc/apache2/sites-available/birchwood-abbey.net-vhost.conf
   notify: Restart Apache2.
-
-&lt;&lt;apache-gitweb-tasks&gt;&gt;
-</code></pre>
-</div>
-
-<div class="org-src-container">
-<a href="roles_t/abbey-front/handlers/main.yml"><q>roles_t/abbey-front/handlers/main.yml</q></a><pre class="src src-conf"><code>
-&lt;&lt;apache-gitweb-handlers&gt;&gt;
 </code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org8b56a72" class="outline-3">
-<h3 id="org8b56a72"><span class="section-number-3">3.8.</span> Configure Apache Log Archival</h3>
+<div id="outline-container-org6cd258b" class="outline-3">
+<h3 id="org6cd258b"><span class="section-number-3">3.8.</span> Configure Apache Log Archival</h3>
 <div class="outline-text-3" id="text-3-8">
 <p>
 These tasks hack Apache's <code>logrotate(8)</code> configuration to rotate
@@ -612,29 +665,30 @@ The replacement <q>logrotate-mailer</q> does, and includes it in a
   - { regexp: <span class="org-string">"^\tmail "</span>, line: <span class="org-string">"\tmail webmaster"</span> }
   - { regexp: <span class="org-string">"^\tmailfirst"</span>, line: <span class="org-string">"\tmailfirst"</span> }
 
-- name: Configure logrotate.
-  become: yes
-  copy:
-    src: logrotate-mailer.conf
-    dest: /etc/systemd/system/logrotate.service.d/mailer.conf
-  notify: Reload systemd.
-
 - name: Install logrotate mailer.
   become: yes
   copy:
     src: logrotate-mailer
     dest: /usr/local/sbin/logrotate-mailer
     <span class="org-variable-name">mode: u</span>=rwx,g=rx,o=rx
-</code></pre>
-</div>
 
-<div class="org-src-container">
-<a href="roles_t/abbey-front/handlers/main.yml"><q>roles_t/abbey-front/handlers/main.yml</q></a><pre class="src src-conf"><code>
-- name: Reload systemd.
+- name: Install logrotate.
   become: yes
-  systemd:
-    daemon_reload: yes
-  tags: actualizer
+  <span class="org-variable-name">apt: pkg</span>=logrotate
+
+- name: Create logrotate drop-in configuration directory.
+  become: yes
+  file:
+    path: /etc/systemd/system/logrotate.service.d
+    state: directory
+    <span class="org-variable-name">mode: u</span>=rwx,g=rx,o=rx
+
+- name: Configure logrotate.
+  become: yes
+  copy:
+    src: logrotate-mailer.conf
+    dest: /etc/systemd/system/logrotate.service.d/mailer.conf
+  notify: Reload systemd.
 </code></pre>
 </div>
 
@@ -705,8 +759,8 @@ encrypting and sending to <code>sendmail</code>.
 </div>
 </div>
 </div>
-<div id="outline-container-org19b0c76" class="outline-3">
-<h3 id="org19b0c76"><span class="section-number-3">3.9.</span> Install Let's Encrypt</h3>
+<div id="outline-container-org84b4a08" class="outline-3">
+<h3 id="org84b4a08"><span class="section-number-3">3.9.</span> Install Let's Encrypt</h3>
 <div class="outline-text-3" id="text-3-9">
 <p>
 The abbey uses a Let's Encrypt certificate to authenticate its public
@@ -715,7 +769,7 @@ certificate is a terminal session affair (with prompts and lines
 entered as shown below).
 </p>
 
-<pre class="example" id="org633b789">
+<pre class="example" id="org76969b0">
 $ sudo apt install python3-certbot-apache
 $ sudo certbot --apache -d birchwood-abbey.net
 ...
@@ -781,11 +835,20 @@ package is installed and its <q>live/</q> subdirectory is world readable.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=python3-certbot-apache
 
-- name: Ensure Let<span class="org-string">'s Encrypt certificate is readable.
+- name: Look for /etc/letsencrypt/live/.
+  stat:
+    path: /etc/letsencrypt/live
+  register: letsencrypt
+- debug:
+    msg: <span class="org-string">"/etc/letsencrypt/live/ does not (yet) exist"</span>
+  when: not letsencrypt.stat.exists
+
+- name: <span class="org-string">"Ensure Let's Encrypt certificate is readable."</span>
   become: yes
   file:
-    mode: u=rwx,g=rx,o=rx
-    path: /etc/letsencrypt/live</span>
+    <span class="org-variable-name">mode: u</span>=rwx,g=rx,o=rx
+    path: /etc/letsencrypt/live
+  when: letsencrypt.stat.exists
 </code></pre>
 </div>
 
@@ -798,36 +861,72 @@ links keep the window for a mismatch extremely small.
 </p>
 
 <p>
-With the institutional configuration, Postfix, Dovecot and Apache
-servers get their certificate&amp;key from <q>/etc/server.crt&amp;.key</q>.  The
-institutional roles check that they exist, but will not create them.
-In this abbey specific role, <q>/etc/server.crt&amp;key</q> are ours to frob.
-The following tasks ensure they are symbolic links to
-<q>/etc/letsencrypt/live/birchwood-abbey.net/fullchain&amp;privkey.pem</q>.  If
-<q>/etc/letsencrypt/</q> was restored from a backup, the servers should be
-restarted manually.
+A small institute configures its Postfix, Dovecot and Apache servers
+use the certificate in <q>/etc/server.crt</q>.  Ansible copies the small
+institute's self-signed (private) certificate there, but only if the
+file does not exist.  This abbey specific role is free to symbolically
+link this file (and the corresponding <q>/etc/server.key</q> file) to
+<q>/etc/letsencrypt/live/birchwood-abbey.net/fullchain.pem</q> (and
+<q>privkey.pem</q>).
+</p>
+
+<p>
+If <q>/etc/letsencrypt/</q> was restored from a backup, the servers should
+be restarted manually.
 </p>
 
 <div class="org-src-container">
 <a href="roles_t/abbey-front/tasks/main.yml"><q>roles_t/abbey-front/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Use Let<span class="org-string">'s Encrypt certificate&amp;key.
+- name: <span class="org-string">"Use Let's Encrypt certificate&amp;key."</span>
+  become: yes
   file:
     state: link
-    src: "{{ item.target }}"
-    path: "{{ item.link }}"
+    src: <span class="org-string">"{{ item.target }}"</span>
+    path: <span class="org-string">"{{ item.link }}"</span>
     force: yes
   loop:
   - target: /etc/letsencrypt/live/birchwood-abbey.net/fullchain.pem
     link: /etc/server.crt
   - target: /etc/letsencrypt/live/birchwood-abbey.net/privkey.pem
-    link: /etc/server.key</span>
+    link: /etc/server.key
+  when: letsencrypt.stat.exists
 </code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgbbc57f8" class="outline-3">
-<h3 id="orgbbc57f8"><span class="section-number-3">3.10.</span> Rotate Let's Encrypt Log</h3>
+<div id="outline-container-org1bdf2c2" class="outline-3">
+<h3 id="org1bdf2c2"><span class="section-number-3">3.10.</span> Restart servers caching the Let's Encrypt certificate.</h3>
 <div class="outline-text-3" id="text-3-10">
+<div class="org-src-container">
+<a href="roles_t/abbey-front/tasks/main.yml"><q>roles_t/abbey-front/tasks/main.yml</q></a><pre class="src src-conf"><code>
+- name: Install Certbot hook.
+  become: yes
+  copy:
+    src: certbot_hook
+    dest: /etc/letsencrypt/renewal-hooks/post/restart-abbey-servers
+    <span class="org-variable-name">mode: u</span>=rwx,g=rx,o=rx
+  when: letsencrypt.stat.exists
+</code></pre>
+</div>
+
+<p>
+The Dovecot IMAP server seems to cache the Let's Encrypt certificate.
+Whenever it runs for more than 3 months (i.e. every 3 months), email
+stops flowing because fetchmail notices the server certificate has
+expired.  The Postfix and Apache2 servers seem not to cache their
+server certificate.
+</p>
+
+<div class="org-src-container">
+<a href="roles_t/abbey-front/files/certbot_hook"><q>roles_t/abbey-front/files/certbot_hook</q></a><pre class="src src-conf"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/bash
+</span>systemctl reload dovecot
+</code></pre>
+</div>
+</div>
+</div>
+<div id="outline-container-orgff09563" class="outline-3">
+<h3 id="orgff09563"><span class="section-number-3">3.11.</span> Rotate Let's Encrypt Log</h3>
+<div class="outline-text-3" id="text-3-11">
 <p>
 The following task arranges to rotate Certbot's logs files.
 </p>
@@ -854,9 +953,9 @@ The following task arranges to rotate Certbot's logs files.
 </div>
 </div>
 </div>
-<div id="outline-container-org8dd4061" class="outline-3">
-<h3 id="org8dd4061"><span class="section-number-3">3.11.</span> Archive Let's Encrypt Data</h3>
-<div class="outline-text-3" id="text-3-11">
+<div id="outline-container-org40b7d48" class="outline-3">
+<h3 id="org40b7d48"><span class="section-number-3">3.12.</span> Archive Let's Encrypt Data</h3>
+<div class="outline-text-3" id="text-3-12">
 <p>
 A backup copy of Let's Encrypt's data (<q>/etc/letsencrypt/</q>) is sent to
 <code>root@core</code> in OpenPGP encrypted email every time it changes.  Changes
@@ -865,12 +964,12 @@ are detected by keeping a copy in <q>/etc/letsencrypt~/</q> for comparison.
 
 <div class="org-src-container">
 <a href="roles_t/abbey-front/tasks/main.yml"><q>roles_t/abbey-front/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install Let<span class="org-string">'s Encrypt archive script.
+- name: <span class="org-string">"Install Let's Encrypt archive script."</span>
   become: yes
   copy:
     src: cron.daily_letsencrypt
     dest: /etc/cron.daily/letsencrypt
-    mode: u=rwx,g=rx,o=rx</span>
+    <span class="org-variable-name">mode: u</span>=rwx,g=rx,o=rx
 </code></pre>
 </div>
 
@@ -934,8 +1033,8 @@ imported into <code>root@front</code>'s GnuPG key file.
 </div>
 </div>
 </div>
-<div id="outline-container-orge7c63b8" class="outline-2">
-<h2 id="orge7c63b8"><span class="section-number-2">4.</span> The Abbey Core Role</h2>
+<div id="outline-container-orgc325de7" class="outline-2">
+<h2 id="orgc325de7"><span class="section-number-2">4.</span> The Abbey Core Role</h2>
 <div class="outline-text-2" id="text-4">
 <p>
 Birchwood Abbey's core is a mini-PC (System76 Meerkat) configured as A
@@ -945,8 +1044,8 @@ with Postfix and Dovecot, and providing essential localnet services:
 NTP, DNS and DHCP.
 </p>
 </div>
-<div id="outline-container-org527c528" class="outline-3">
-<h3 id="org527c528"><span class="section-number-3">4.1.</span> Include Abbey Variables</h3>
+<div id="outline-container-org1f3ff6d" class="outline-3">
+<h3 id="org1f3ff6d"><span class="section-number-3">4.1.</span> Include Abbey Variables</h3>
 <div class="outline-text-3" id="text-4-1">
 <p>
 In this abbey specific document, most abbey particulars are not
@@ -965,8 +1064,8 @@ directory, <q>playbooks/</q>.
 </div>
 </div>
 </div>
-<div id="outline-container-orgb98fbad" class="outline-3">
-<h3 id="orgb98fbad"><span class="section-number-3">4.2.</span> Install Additional Packages</h3>
+<div id="outline-container-orgd8805da" class="outline-3">
+<h3 id="orgd8805da"><span class="section-number-3">4.2.</span> Install Additional Packages</h3>
 <div class="outline-text-3" id="text-4-2">
 <p>
 The scripts that maintain the abbey's web site use a number of
@@ -986,8 +1085,8 @@ The house task list uses JQuery.
 </div>
 </div>
 </div>
-<div id="outline-container-orgb220438" class="outline-3">
-<h3 id="orgb220438"><span class="section-number-3">4.3.</span> Configure Private Email Aliases</h3>
+<div id="outline-container-orgedad99a" class="outline-3">
+<h3 id="orgedad99a"><span class="section-number-3">4.3.</span> Configure Private Email Aliases</h3>
 <div class="outline-text-3" id="text-4-3">
 <p>
 The abbey uses several additional email aliases.  These are the campus
@@ -1028,36 +1127,60 @@ e.g. <code>mythtv@mythtv.birchwood.private</code>, locally.)
 </div>
 </div>
 </div>
-<div id="outline-container-org6c3e11d" class="outline-3">
-<h3 id="org6c3e11d"><span class="section-number-3">4.4.</span> Configure Git Daemon on Core</h3>
+<div id="outline-container-org5d20d9d" class="outline-3">
+<h3 id="org5d20d9d"><span class="section-number-3">4.4.</span> Configure Git Daemon on Core</h3>
 <div class="outline-text-3" id="text-4-4">
 <p>
 These tasks are identical to those executed on Front, for similar Git
-services on Front and Core.  See <a href="#org267af54">3.3</a> and
-<a href="#org699d236">Configure Gitweb on Front</a> for more information.
+services on Front and Core.  This allows changes to be tested on Core
+before they are pushed to Front.  See <a href="#org1f28e49">3.3</a>
+for more information.
 </p>
 
 <div class="org-src-container">
 <a href="roles_t/abbey-core/tasks/main.yml"><q>roles_t/abbey-core/tasks/main.yml</q></a><pre class="src src-conf"><code>
-&lt;&lt;git-tasks&gt;&gt;
+&lt;&lt;gitd-tasks&gt;&gt;
 </code></pre>
 </div>
 
 <div class="org-src-container">
 <a href="roles_t/abbey-core/handlers/main.yml"><q>roles_t/abbey-core/handlers/main.yml</q></a><pre class="src src-conf"><code>
-&lt;&lt;git-handlers&gt;&gt;
+&lt;&lt;gitd-handlers&gt;&gt;
 </code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgb749be4" class="outline-3">
-<h3 id="orgb749be4"><span class="section-number-3">4.5.</span> Configure Apache on Core</h3>
+<div id="outline-container-orgc3d5416" class="outline-3">
+<h3 id="orgc3d5416"><span class="section-number-3">4.5.</span> Configure Gitweb on Core</h3>
 <div class="outline-text-3" id="text-4-5">
 <p>
+These tasks are identical to those executed on Front, for similar
+Gitweb services on Front and Core.  This allows changes to be tested
+on Core before they are pushed to Front.  See <a href="#org0019fd0">Configure Gitweb on
+Front</a> for more information.
+</p>
+
+<div class="org-src-container">
+<a href="roles_t/abbey-core/tasks/main.yml"><q>roles_t/abbey-core/tasks/main.yml</q></a><pre class="src src-conf"><code>
+&lt;&lt;gitweb-tasks&gt;&gt;
+</code></pre>
+</div>
+
+<div class="org-src-container">
+<a href="roles_t/abbey-core/handlers/main.yml"><q>roles_t/abbey-core/handlers/main.yml</q></a><pre class="src src-conf"><code>
+&lt;&lt;gitweb-handlers&gt;&gt;
+</code></pre>
+</div>
+</div>
+</div>
+<div id="outline-container-org3a8853f" class="outline-3">
+<h3 id="org3a8853f"><span class="section-number-3">4.6.</span> Configure Apache on Core</h3>
+<div class="outline-text-3" id="text-4-6">
+<p>
 The Apache2 configuration on Core specifies three web sites (live,
 test, and campus).  The live and test sites must operate just like the
-site on Front.  Their configurations include the same <a href="#org729ab6e"><code>apache-abbey</code></a>,
-<a href="#orgee7659b"><code>apache-photos</code></a>, and <a href="#org087507e"><code>apache-gitweb</code></a> used on Front.
+site on Front.  Their configurations include the same <a href="#org635af88"><code>apache-abbey</code></a>,
+<a href="#org5096221"><code>apache-photos</code></a>, and <a href="#org72f1894"><code>apache-gitweb</code></a> used on Front.
 </p>
 
 <div class="org-src-container">
@@ -1087,27 +1210,19 @@ site on Front.  Their configurations include the same <a href="#org729ab6e"><cod
     dest: /etc/apache2/sites-available/test-vhost.conf
     <span class="org-variable-name">mode: u</span>=rw,g=r,o=r
   notify: Restart Apache2.
-
-&lt;&lt;apache-gitweb-tasks&gt;&gt;
-</code></pre>
-</div>
-
-<div class="org-src-container">
-<a href="roles_t/abbey-core/handlers/main.yml"><q>roles_t/abbey-core/handlers/main.yml</q></a><pre class="src src-conf"><code>
-&lt;&lt;apache-gitweb-handlers&gt;&gt;
 </code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org838f2e2" class="outline-3">
-<h3 id="org838f2e2"><span class="section-number-3">4.6.</span> Configure Documentation URLs</h3>
-<div class="outline-text-3" id="text-4-6">
+<div id="outline-container-orgd475415" class="outline-3">
+<h3 id="orgd475415"><span class="section-number-3">4.7.</span> Configure Documentation URLs</h3>
+<div class="outline-text-3" id="text-4-7">
 <p>
 The institute serves its <q>/usr/share/doc/</q> on the house (campus) web
 site.  This is a debugging convenience, making some HTML documentation
 more accessible, especially the documentation of software installed on
 Core and not on typical desktop clients.  Also included: the Apache2
-directives that enable user Git publishing with Gitweb (defined <a href="#org087507e">here</a>).
+directives that enable user Git publishing with Gitweb (defined <a href="#org72f1894">here</a>).
 </p>
 
 <div class="org-src-container">
@@ -1128,9 +1243,9 @@ directives that enable user Git publishing with Gitweb (defined <a href="#org087
 </div>
 </div>
 </div>
-<div id="outline-container-org5b4621f" class="outline-3">
-<h3 id="org5b4621f"><span class="section-number-3">4.7.</span> Install Apt Cacher</h3>
-<div class="outline-text-3" id="text-4-7">
+<div id="outline-container-org94e2626" class="outline-3">
+<h3 id="org94e2626"><span class="section-number-3">4.8.</span> Install Apt Cacher</h3>
+<div class="outline-text-3" id="text-4-8">
 <p>
 The abbey uses the Apt-Cacher:TNG package cache on Core.  The
 <code>apt-cacher</code> domain name is defined in <q>private/db.domain</q>.
@@ -1145,9 +1260,9 @@ The abbey uses the Apt-Cacher:TNG package cache on Core.  The
 </div>
 </div>
 </div>
-<div id="outline-container-orgbc620cb" class="outline-3">
-<h3 id="orgbc620cb"><span class="section-number-3">4.8.</span> Use Cloister Apt Cache</h3>
-<div class="outline-text-3" id="text-4-8">
+<div id="outline-container-orgf08a21f" class="outline-3">
+<h3 id="orgf08a21f"><span class="section-number-3">4.9.</span> Use Cloister Apt Cache</h3>
+<div class="outline-text-3" id="text-4-9">
 <p>
 Core itself will benefit from using the package cache, but should
 contact <code>https</code> repositories directly.  (There are few such cretins
@@ -1159,10 +1274,8 @@ so caching their packages is not a priority.)
 - name: Use the local Apt package cache.
   become: yes
   copy:
-    content: &gt;
-      Acquire::http::Proxy
-      <span class="org-string">"http://apt-cacher.birchwood.private.:3142"</span>;
-
+    content: |
+      Acquire::http::Proxy <span class="org-string">"http://{{ core_addr }}:3142"</span>;
       Acquire::https::Proxy <span class="org-string">"DIRECT"</span>;
     dest: /etc/apt/apt.conf.d/01proxy
     <span class="org-variable-name">mode: u</span>=rw,g=r,o=r
@@ -1170,9 +1283,9 @@ so caching their packages is not a priority.)
 </div>
 </div>
 </div>
-<div id="outline-container-org314a1e2" class="outline-3">
-<h3 id="org314a1e2"><span class="section-number-3">4.9.</span> Configure NAGIOS</h3>
-<div class="outline-text-3" id="text-4-9">
+<div id="outline-container-org748759e" class="outline-3">
+<h3 id="org748759e"><span class="section-number-3">4.10.</span> Configure NAGIOS</h3>
+<div class="outline-text-3" id="text-4-10">
 <p>
 A small institute uses <code>nagios4</code> to monitor the health of its network,
 with an initial smattering of monitors adopted from the Debian
@@ -1185,9 +1298,9 @@ another customized <code>check_sensors</code> plugin (<code>abbey_pisensors</cod
 Raspberry Pis.
 </p>
 </div>
-<div id="outline-container-org0cd3e32" class="outline-4">
-<h4 id="org0cd3e32"><span class="section-number-4">4.9.1.</span> Monitoring The Home Disk</h4>
-<div class="outline-text-4" id="text-4-9-1">
+<div id="outline-container-org59fad33" class="outline-4">
+<h4 id="org59fad33"><span class="section-number-4">4.10.1.</span> Monitoring The Home Disk</h4>
+<div class="outline-text-4" id="text-4-10-1">
 <p>
 The abbey adds monitoring of the space remaining on the volume at
 <q>/home/</q> on Core.  (The small institute only monitors the space
@@ -1241,9 +1354,9 @@ RAID-5 array under <q>/home/</q>.
 </div>
 </div>
 </div>
-<div id="outline-container-org793bf62" class="outline-4">
-<h4 id="org793bf62"><span class="section-number-4">4.9.2.</span> Custom NAGIOS Monitor <code>abbey_pisensors</code></h4>
-<div class="outline-text-4" id="text-4-9-2">
+<div id="outline-container-org911a170" class="outline-4">
+<h4 id="org911a170"><span class="section-number-4">4.10.2.</span> Custom NAGIOS Monitor <code>abbey_pisensors</code></h4>
+<div class="outline-text-4" id="text-4-10-2">
 <p>
 The <code>check_sensors</code> plugin is included in the package
 <code>monitoring-plugins-basic</code>, but it does not report any readings.  The
@@ -1337,9 +1450,9 @@ recognizable temperature in the <code>sensors</code> output.
 </div>
 </div>
 </div>
-<div id="outline-container-orgc83910e" class="outline-4">
-<h4 id="orgc83910e"><span class="section-number-4">4.9.3.</span> Stolen NAGIOS Monitor <code>check_mdstat</code></h4>
-<div class="outline-text-4" id="text-4-9-3">
+<div id="outline-container-orgfa94f9b" class="outline-4">
+<h4 id="orgfa94f9b"><span class="section-number-4">4.10.3.</span> Stolen NAGIOS Monitor <code>check_mdstat</code></h4>
+<div class="outline-text-4" id="text-4-10-3">
 <p>
 This <code>check_mdstat</code> plugin was copied from the NAGIOS Exchange (<a href="https://exchange.nagios.org/directory/plugins/operating-systems/linux/check_mdstat/details/">here</a>).
 It detects a failing disk in a multi-disk array.
@@ -1425,9 +1538,9 @@ EOE
 </div>
 </div>
 </div>
-<div id="outline-container-org884a7fd" class="outline-4">
-<h4 id="org884a7fd"><span class="section-number-4">4.9.4.</span> Configure NAGIOS Monitoring of The Cloister</h4>
-<div class="outline-text-4" id="text-4-9-4">
+<div id="outline-container-org065f0c0" class="outline-4">
+<h4 id="org065f0c0"><span class="section-number-4">4.10.4.</span> Configure NAGIOS Monitoring of The Cloister</h4>
+<div class="outline-text-4" id="text-4-10-4">
 <p>
 The abbey adds monitoring for more servers: Dantooine and Kessel.
 They are <code>abbey-cloister</code> servers, so they are configured as small
@@ -1440,9 +1553,9 @@ The configurations for these servers are very similar to Gate's, but
 are idiosyncratically in flux.
 </p>
 </div>
-<div id="outline-container-org1748c6a" class="outline-5">
-<h5 id="org1748c6a"><span class="section-number-5">4.9.4.1.</span> Cloister Network Addresses</h5>
-<div class="outline-text-5" id="text-4-9-4-1">
+<div id="outline-container-org3e109b1" class="outline-5">
+<h5 id="org3e109b1"><span class="section-number-5">4.10.4.1.</span> Cloister Network Addresses</h5>
+<div class="outline-text-5" id="text-4-10-4-1">
 <p>
 The IP addresses of all three hosts are nice to use in the NAGIOS
 configuration (to avoid depending on name service) and so are
@@ -1457,9 +1570,9 @@ kessel_addr:                10.84.138.10
 </div>
 </div>
 </div>
-<div id="outline-container-orgf516f5f" class="outline-5">
-<h5 id="orgf516f5f"><span class="section-number-5">4.9.4.2.</span> Install NAGIOS Configurations</h5>
-<div class="outline-text-5" id="text-4-9-4-2">
+<div id="outline-container-orgf83186b" class="outline-5">
+<h5 id="orgf83186b"><span class="section-number-5">4.10.4.2.</span> Install NAGIOS Configurations</h5>
+<div class="outline-text-5" id="text-4-10-4-2">
 <p>
 The following task installs each host's NAGIOS configuration.
 </p>
@@ -1477,9 +1590,9 @@ The following task installs each host's NAGIOS configuration.
 </div>
 </div>
 </div>
-<div id="outline-container-orge146107" class="outline-5">
-<h5 id="orge146107"><span class="section-number-5">4.9.4.3.</span> NAGIOS Monitoring of Dantooine</h5>
-<div class="outline-text-5" id="text-4-9-4-3">
+<div id="outline-container-org31151d6" class="outline-5">
+<h5 id="org31151d6"><span class="section-number-5">4.10.4.3.</span> NAGIOS Monitoring of Dantooine</h5>
+<div class="outline-text-5" id="text-4-10-4-3">
 <div class="org-src-container">
 <a href="roles_t/abbey-core/templates/nagios-dantooine.cfg"><q>roles_t/abbey-core/templates/nagios-dantooine.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define host</span> {
     use                     linux-server
@@ -1539,9 +1652,9 @@ The following task installs each host's NAGIOS configuration.
 </div>
 </div>
 </div>
-<div id="outline-container-org29612d8" class="outline-5">
-<h5 id="org29612d8"><span class="section-number-5">4.9.4.4.</span> NAGIOS Monitoring of Kessel</h5>
-<div class="outline-text-5" id="text-4-9-4-4">
+<div id="outline-container-orgb2af791" class="outline-5">
+<h5 id="orgb2af791"><span class="section-number-5">4.10.4.4.</span> NAGIOS Monitoring of Kessel</h5>
+<div class="outline-text-5" id="text-4-10-4-4">
 <div class="org-src-container">
 <a href="roles_t/abbey-core/templates/nagios-kessel.cfg"><q>roles_t/abbey-core/templates/nagios-kessel.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define host</span> {
     use                     linux-server
@@ -1596,9 +1709,9 @@ The following task installs each host's NAGIOS configuration.
 </div>
 </div>
 </div>
-<div id="outline-container-orga71a03b" class="outline-3">
-<h3 id="orga71a03b"><span class="section-number-3">4.10.</span> Install Munin</h3>
-<div class="outline-text-3" id="text-4-10">
+<div id="outline-container-org6dd00a7" class="outline-3">
+<h3 id="org6dd00a7"><span class="section-number-3">4.11.</span> Install Munin</h3>
+<div class="outline-text-3" id="text-4-11">
 <p>
 The abbey is experimenting with Munin.  NAGIOS is all about notifying
 the Sys. Admin. of failed services.  Munin is more about tracking
@@ -1653,6 +1766,19 @@ trends in resource usage.
           address {{ kessel_addr }}
     dest: /etc/munin/munin-conf.d/zzz-site.cfg
   notify: Restart Munin.
+
+- name: Start Munin.
+  become: yes
+  systemd:
+    service: munin
+    state: started
+  tags: actualizer
+
+- name: Enable Munin
+  become: yes
+  systemd:
+    service: munin
+    enabled: yes
 </code></pre>
 </div>
 
@@ -1688,9 +1814,9 @@ next task configures <code>libsensors</code> to ignore them.
 </div>
 </div>
 </div>
-<div id="outline-container-org1b82bb0" class="outline-3">
-<h3 id="org1b82bb0"><span class="section-number-3">4.11.</span> Install Analog</h3>
-<div class="outline-text-3" id="text-4-11">
+<div id="outline-container-orgcceb87e" class="outline-3">
+<h3 id="orgcceb87e"><span class="section-number-3">4.12.</span> Install Analog</h3>
+<div class="outline-text-3" id="text-4-12">
 <p>
 The abbey's public web site's access and error logs are emailed
 regularly to <code>webmaster</code>, who saves them in <q>/Logs/apache2-public/</q>
@@ -1765,9 +1891,9 @@ at <code>http://www/doc/analog/</code>.
 </div>
 </div>
 </div>
-<div id="outline-container-orgcad9c9a" class="outline-3">
-<h3 id="orgcad9c9a"><span class="section-number-3">4.12.</span> Add Monkey to Web Server Group</h3>
-<div class="outline-text-3" id="text-4-12">
+<div id="outline-container-org61569ee" class="outline-3">
+<h3 id="org61569ee"><span class="section-number-3">4.13.</span> Add Monkey to Web Server Group</h3>
+<div class="outline-text-3" id="text-4-13">
 <p>
 Monkey needs to be in <code>www-data</code> so that it can run
 <q>/WWW/live/Photos/Private/cronjob</q> to publish photos from multiple
@@ -1788,9 +1914,9 @@ user cloud accounts, found in files owned by <code>www-data</code>, files like
 </div>
 </div>
 </div>
-<div id="outline-container-orgdd37bf0" class="outline-3">
-<h3 id="orgdd37bf0"><span class="section-number-3">4.13.</span> Install netpbm For Photo Processing</h3>
-<div class="outline-text-3" id="text-4-13">
+<div id="outline-container-orgb8c389f" class="outline-3">
+<h3 id="orgb8c389f"><span class="section-number-3">4.14.</span> Install netpbm For Photo Processing</h3>
+<div class="outline-text-3" id="text-4-14">
 <p>
 Monkey's photo processing scripts use <code>netpbm</code> commands like
 <code>jpegtopnm</code>.
@@ -1806,8 +1932,8 @@ Monkey's photo processing scripts use <code>netpbm</code> commands like
 </div>
 </div>
 </div>
-<div id="outline-container-org9f5451b" class="outline-2">
-<h2 id="org9f5451b"><span class="section-number-2">5.</span> The Abbey Gate Role</h2>
+<div id="outline-container-org50a3ca1" class="outline-2">
+<h2 id="org50a3ca1"><span class="section-number-2">5.</span> The Abbey Gate Role</h2>
 <div class="outline-text-2" id="text-5">
 <p>
 Birchwood Abbey's gate is a $110 µPC configured as A Small Institute
@@ -1819,8 +1945,8 @@ allows access to the Abbey's IoT appliances: a HomeAssistant and an
 Ecowitt hub.
 </p>
 </div>
-<div id="outline-container-orge60f0dc" class="outline-3">
-<h3 id="orge60f0dc"><span class="section-number-3">5.1.</span> The Abbey Gate's Network Interfaces</h3>
+<div id="outline-container-org705dbd5" class="outline-3">
+<h3 id="org705dbd5"><span class="section-number-3">5.1.</span> The Abbey Gate's Network Interfaces</h3>
 <div class="outline-text-3" id="text-5-1">
 <p>
 The abbey gate's <code>lan</code> interface is the PC's built-in Ethernet
@@ -1841,27 +1967,27 @@ The MAC address of each interface is set in <q>private/vars.yml</q> (see
 </p>
 </div>
 </div>
-<div id="outline-container-org2fae425" class="outline-3">
-<h3 id="org2fae425"><span class="section-number-3">5.2.</span> The Abbey's IoT Network</h3>
+<div id="outline-container-org4ae98c0" class="outline-3">
+<h3 id="org4ae98c0"><span class="section-number-3">5.2.</span> The Abbey's IoT Network</h3>
 <div class="outline-text-3" id="text-5-2">
 <p>
 To allow masquerading between the private subnets and <code>wild</code>, the
 following <code>iptables(8)</code> rules are added.  They are very similar to the
 <code>nat</code> and <code>filter</code> table rules used by a small institute to masquerade
-its <code>lan</code> to its <code>isp</code> (see the <a href="Institute/README.html#org81016c5">UFW Rules</a> of a Small Institute).
+its <code>lan</code> to its <code>isp</code> (see the <a href="Institute/README.html#org95ec5ba">UFW Rules</a> of a Small Institute).
 The campus WireGuard™ subnet is not included because the campus Wi-Fi
 hosts should be routing to the wild subnet directly and are assumed to
 be masquerading as their access point(s).
 </p>
 
 <div class="org-src-container">
-<code>iot-nat</code><pre class="src src-conf" id="org3d90360"><code>-A POSTROUTING -s {{   private_net_cidr }} -o wild -j MASQUERADE
+<code>iot-nat</code><pre class="src src-conf" id="orgda26877"><code>-A POSTROUTING -s {{   private_net_cidr }} -o wild -j MASQUERADE
 -A POSTROUTING -s {{ public_wg_net_cidr }} -o wild -j MASQUERADE
 </code></pre>
 </div>
 
 <div class="org-src-container">
-<code>iot-forward</code><pre class="src src-conf" id="org0c68876"><code>-A ufw-user-forward -i lan -o wild -j ACCEPT
+<code>iot-forward</code><pre class="src src-conf" id="org6731cd5"><code>-A ufw-user-forward -i lan -o wild -j ACCEPT
 -A ufw-user-forward -i wg0 -o wild -j ACCEPT
 </code></pre>
 </div>
@@ -1872,12 +1998,12 @@ The second rule includes the campus VPN.
 </p>
 </div>
 </div>
-<div id="outline-container-orgfd30ddd" class="outline-3">
-<h3 id="orgfd30ddd"><span class="section-number-3">5.3.</span> Configure UFW for IoT</h3>
+<div id="outline-container-org05fb5ce" class="outline-3">
+<h3 id="org05fb5ce"><span class="section-number-3">5.3.</span> Configure UFW for IoT</h3>
 <div class="outline-text-3" id="text-5-3">
 <p>
 The following tasks install the additional rules in <q>before.rules</q>
-and <q>user.rules</q> (as in <a href="Institute/README.html#orgf0f7295">Configure UFW</a>).
+and <q>user.rules</q> (as in <a href="Institute/README.html#org21789ad">Configure UFW</a>).
 </p>
 
 <div class="org-src-container">
@@ -1909,8 +2035,8 @@ and <q>user.rules</q> (as in <a href="Institute/README.html#orgf0f7295">Configur
 </div>
 </div>
 </div>
-<div id="outline-container-orgc6db098" class="outline-3">
-<h3 id="orgc6db098"><span class="section-number-3">5.4.</span> The Abbey's Starlink Configuration</h3>
+<div id="outline-container-org70d9613" class="outline-3">
+<h3 id="org70d9613"><span class="section-number-3">5.4.</span> The Abbey's Starlink Configuration</h3>
 <div class="outline-text-3" id="text-5-4">
 <p>
 The abbey connects to Starlink via Ethernet, and disables Starlink's
@@ -1958,8 +2084,8 @@ at least our local network traffic out of view of our ISPs.
 </p>
 </div>
 </div>
-<div id="outline-container-org34154b7" class="outline-3">
-<h3 id="org34154b7"><span class="section-number-3">5.5.</span> Alternate ISPs</h3>
+<div id="outline-container-org6263ec3" class="outline-3">
+<h3 id="org6263ec3"><span class="section-number-3">5.5.</span> Alternate ISPs</h3>
 <div class="outline-text-3" id="text-5-5">
 <p>
 The abbey used to use a cell phone on a USB tether to get Internet
@@ -2004,8 +2130,8 @@ service, using a <q>60-isp.yaml</q> file similar to the lines below.
 </div>
 </div>
 </div>
-<div id="outline-container-orgc01bde6" class="outline-2">
-<h2 id="orgc01bde6"><span class="section-number-2">6.</span> The Abbey Cloister Role</h2>
+<div id="outline-container-org40da079" class="outline-2">
+<h2 id="org40da079"><span class="section-number-2">6.</span> The Abbey Cloister Role</h2>
 <div class="outline-text-2" id="text-6">
 <p>
 Birchwood Abbey's cloister is a small institute campus.  The <code>campus</code>
@@ -2020,7 +2146,7 @@ tasks, namely configuration required on Raspberry Pi OS machines.
 <p>
 Wireless clients are issued keys for the cloister VPN by the <code>./abbey
 client</code> command which is currently identical to the <code>./inst client</code>
-command (described in <a href="Institute/README.html#org4c26e9f">The Client Command</a>).  The wireless, cloistered
+command (described in <a href="Institute/README.html#org8465bda">The Client Command</a>).  The wireless, cloistered
 hosts never roam, are not associated with a member, and so are
 "campus" clients, issued keys with commands like this:
 </p>
@@ -2030,8 +2156,8 @@ hosts never roam, are not associated with a member, and so are
                S+6HaTnOwwhWgUGXjSBcPAvifKw+j8BDTRfq534gNW4=
 </pre>
 </div>
-<div id="outline-container-org4b22e16" class="outline-3">
-<h3 id="org4b22e16"><span class="section-number-3">6.1.</span> Use Cloister Apt Cache</h3>
+<div id="outline-container-orgb2ba8cf" class="outline-3">
+<h3 id="orgb2ba8cf"><span class="section-number-3">6.1.</span> Use Cloister Apt Cache</h3>
 <div class="outline-text-3" id="text-6-1">
 <p>
 The Apt-Cacher:TNG program does not work well on the frontier, so is
@@ -2054,10 +2180,8 @@ local host.
 - name: Use the local Apt package cache.
   become: yes
   copy:
-    content: &gt;
-      Acquire::http::Proxy
-      <span class="org-string">"http://apt-cacher.birchwood.private.:3142"</span>;
-
+    content: |
+      Acquire::http::Proxy <span class="org-string">"http://{{ core_addr }}:3142"</span>;
       Acquire::https::Proxy <span class="org-string">"DIRECT"</span>;
     dest: /etc/apt/apt.conf.d/01proxy
     <span class="org-variable-name">mode: u</span>=rw,g=r,o=r
@@ -2065,13 +2189,13 @@ local host.
 </div>
 </div>
 </div>
-<div id="outline-container-org07b9f6b" class="outline-3">
-<h3 id="org07b9f6b"><span class="section-number-3">6.2.</span> Configure Cloister NRPE</h3>
+<div id="outline-container-orgc082038" class="outline-3">
+<h3 id="orgc082038"><span class="section-number-3">6.2.</span> Configure Cloister NRPE</h3>
 <div class="outline-text-3" id="text-6-2">
 <p>
 Each cloistered host is a small institute campus host and thus is
 already running an NRPE server (a NAGIOS Remote Plugin Executor
-server) with a custom <code>inst_sensors</code> monitor (described in <a href="Institute/README.html#org75dd85d">Configure
+server) with a custom <code>inst_sensors</code> monitor (described in <a href="Institute/README.html#orgf9a3257">Configure
 NRPE</a> of <a href="Institute/README.html">A Small Institute</a>).  The abbey adds one complication: yet
 another <code>check_sensors</code> variant, <code>abbey_pisensors</code>, installed on
 Raspberry Pis (architecture <code>aarch64</code>) only.
@@ -2110,8 +2234,8 @@ Raspberry Pis (architecture <code>aarch64</code>) only.
 </div>
 </div>
 </div>
-<div id="outline-container-org2fb1171" class="outline-3">
-<h3 id="org2fb1171"><span class="section-number-3">6.3.</span> Install Munin Node</h3>
+<div id="outline-container-orgad93d79" class="outline-3">
+<h3 id="orgad93d79"><span class="section-number-3">6.3.</span> Install Munin Node</h3>
 <div class="outline-text-3" id="text-6-3">
 <p>
 Each cloistered host is a Munin node.
@@ -2129,7 +2253,7 @@ Each cloistered host is a Munin node.
     regexp: <span class="org-string">"^allow [^]{{ core_addr|regex_escape }}[$]$"</span>
     line: <span class="org-string">"allow ^{{ core_addr|regex_escape }}$"</span>
     path: /etc/munin/munin-node.conf
-  notify: Restart Munin node.
+  notify: Restart Munin Node.
 
 - name: Add {{ ansible_user }} to munin group.
   become: yes
@@ -2137,6 +2261,30 @@ Each cloistered host is a Munin node.
     name: <span class="org-string">"{{ ansible_user }}"</span>
     append: yes
     groups: munin
+
+- name: Start Munin Node.
+  become: yes
+  systemd:
+    service: munin-node
+    state: started
+  tags: actualizer
+
+- name: Enable Munin Node.
+  become: yes
+  systemd:
+    service: munin-node
+    enabled: yes
+</code></pre>
+</div>
+
+<div class="org-src-container">
+<a href="roles_t/abbey-cloister/handlers/main.yml"><q>roles_t/abbey-cloister/handlers/main.yml</q></a><pre class="src src-conf"><code>
+- name: Restart Munin Node.
+  become: yes
+  systemd:
+    service: munin-node
+    state: restarted
+  tags: actualizer
 </code></pre>
 </div>
 
@@ -2162,8 +2310,8 @@ them.
 </div>
 </div>
 </div>
-<div id="outline-container-orge084336" class="outline-3">
-<h3 id="orge084336"><span class="section-number-3">6.4.</span> Install Emacs</h3>
+<div id="outline-container-orgf21806d" class="outline-3">
+<h3 id="orgf21806d"><span class="section-number-3">6.4.</span> Install Emacs</h3>
 <div class="outline-text-3" id="text-6-4">
 <p>
 The monks of the abbey are masters of the staff and Emacs.
@@ -2179,8 +2327,8 @@ The monks of the abbey are masters of the staff and Emacs.
 </div>
 </div>
 </div>
-<div id="outline-container-orga4545a2" class="outline-2">
-<h2 id="orga4545a2"><span class="section-number-2">7.</span> The Abbey Weather Role</h2>
+<div id="outline-container-orgcc421f1" class="outline-2">
+<h2 id="orgcc421f1"><span class="section-number-2">7.</span> The Abbey Weather Role</h2>
 <div class="outline-text-2" id="text-7">
 <p>
 Birchwood Abbey now uses Home Assistant to record and display weather
@@ -2207,8 +2355,8 @@ entities.  These were labeled and organized on an "Abbey" dashboard.
 </p>
 </div>
 </div>
-<div id="outline-container-orge47adfe" class="outline-2">
-<h2 id="orge47adfe"><span class="section-number-2">8.</span> The Abbey DVR Role</h2>
+<div id="outline-container-org476a6b0" class="outline-2">
+<h2 id="org476a6b0"><span class="section-number-2">8.</span> The Abbey DVR Role</h2>
 <div class="outline-text-2" id="text-8">
 <p>
 The abbey uses AgentDVR to record video from PoE IP HD security
@@ -2216,8 +2364,8 @@ cameras.  It runs as user <code>agentdvr</code> and keeps all of its
 configuration and recordings in <q>/home/agentdvr/</q>.
 </p>
 </div>
-<div id="outline-container-org32af853" class="outline-3">
-<h3 id="org32af853"><span class="section-number-3">8.1.</span> Install AgentDVR</h3>
+<div id="outline-container-org2e582ee" class="outline-3">
+<h3 id="org2e582ee"><span class="section-number-3">8.1.</span> Install AgentDVR</h3>
 <div class="outline-text-3" id="text-8-1">
 <p>
 AgentDVR is installed according to the iSpy web site's latest
@@ -2241,8 +2389,8 @@ executes several <code>sudo</code> commands.  These commands can be run by the
 <code>agentdvr</code> account if it has (temporary) authorization.
 </p>
 </div>
-<div id="outline-container-orge165e78" class="outline-4">
-<h4 id="orge165e78"><span class="section-number-4">8.1.1.</span> Prepare for AgentDVR Installation</h4>
+<div id="outline-container-orga0c30b5" class="outline-4">
+<h4 id="orga0c30b5"><span class="section-number-4">8.1.1.</span> Prepare for AgentDVR Installation</h4>
 <div class="outline-text-4" id="text-8-1-1">
 <p>
 The following commands are manually executed to create the <code>agentdvr</code>
@@ -2270,8 +2418,8 @@ sudo mv ~/01agentdvr /etc/sudoers.d/
 </div>
 </div>
 </div>
-<div id="outline-container-orgefe9eb8" class="outline-4">
-<h4 id="orgefe9eb8"><span class="section-number-4">8.1.2.</span> Execute AgentDVR Installation</h4>
+<div id="outline-container-org69cb21c" class="outline-4">
+<h4 id="org69cb21c"><span class="section-number-4">8.1.2.</span> Execute AgentDVR Installation</h4>
 <div class="outline-text-4" id="text-8-1-2">
 <p>
 With the above preparations, the system administrator can get a shell
@@ -2292,8 +2440,8 @@ Ansible is run again.
 </p>
 </div>
 </div>
-<div id="outline-container-orgefc95f3" class="outline-4">
-<h4 id="orgefc95f3"><span class="section-number-4">8.1.3.</span> Complete AgentDVR Installation</h4>
+<div id="outline-container-org8f0657d" class="outline-4">
+<h4 id="org8f0657d"><span class="section-number-4">8.1.3.</span> Complete AgentDVR Installation</h4>
 <div class="outline-text-4" id="text-8-1-3">
 <p>
 When Ansible is run a second time, after the installation script, it
@@ -2316,8 +2464,8 @@ sudo rm /etc/sudoers.d/01agentdvr
 </div>
 </div>
 </div>
-<div id="outline-container-org234a2e1" class="outline-3">
-<h3 id="org234a2e1"><span class="section-number-3">8.2.</span> Configure User <code>agentdvr</code></h3>
+<div id="outline-container-org4c3c66a" class="outline-3">
+<h3 id="org4c3c66a"><span class="section-number-3">8.2.</span> Configure User <code>agentdvr</code></h3>
 <div class="outline-text-3" id="text-8-2">
 <p>
 AgentDVR runs as the system user <code>agentdvr</code>, which is configured here.
@@ -2356,8 +2504,8 @@ restoration of AgentDVR.)
 </div>
 </div>
 </div>
-<div id="outline-container-orga791f26" class="outline-3">
-<h3 id="orga791f26"><span class="section-number-3">8.3.</span> Test For <q>AgentDVR/</q></h3>
+<div id="outline-container-org8415a95" class="outline-3">
+<h3 id="org8415a95"><span class="section-number-3">8.3.</span> Test For <q>AgentDVR/</q></h3>
 <div class="outline-text-3" id="text-8-3">
 <p>
 The following task probes for the <q>/home/agentdvr/AgentDVR/</q>
@@ -2380,8 +2528,8 @@ remaining installation steps are skipped unless
 </div>
 </div>
 </div>
-<div id="outline-container-org039773e" class="outline-3">
-<h3 id="org039773e"><span class="section-number-3">8.4.</span> Create AgentDVR Service</h3>
+<div id="outline-container-org3063f3a" class="outline-3">
+<h3 id="org3063f3a"><span class="section-number-3">8.4.</span> Create AgentDVR Service</h3>
 <div class="outline-text-3" id="text-8-4">
 <p>
 This service definition came from the template downloaded (from <a href="https://raw.githubusercontent.com/ispysoftware/agent-install-scripts/main/v2/AgentDVR.service">here</a>)
@@ -2418,27 +2566,34 @@ by <q>install.sh</q>.
       [<span class="org-type">Install</span>]
       <span class="org-variable-name">WantedBy</span>=multi-user.target
     dest: /etc/systemd/system/AgentDVR.service
+  notify:
+  - Reload systemd.
+  - Restart AgentDVR.
 
-- name: Start AgentDVR.service.
+- name: Enable AgentDVR.service.
   become: yes
   systemd:
     service: AgentDVR
-    state: started
+    enabled: yes
   when: agentdvr.stat.exists
-  tags: actualizer
+</code></pre>
+</div>
 
-- name: Enable AgentDVR.service.
+<div class="org-src-container">
+<a href="roles_t/abbey-front/handlers/main.yml"><q>roles_t/abbey-front/handlers/main.yml</q></a><pre class="src src-conf"><code>
+- name: Restart AgentDVR.
   become: yes
   systemd:
     service: AgentDVR
-    enabled: yes
+    state: restarted
   when: agentdvr.stat.exists
+  tags: actualizer
 </code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgdf1974b" class="outline-3">
-<h3 id="orgdf1974b"><span class="section-number-3">8.5.</span> Create AgentDVR Storage</h3>
+<div id="outline-container-orgef1a08c" class="outline-3">
+<h3 id="orgef1a08c"><span class="section-number-3">8.5.</span> Create AgentDVR Storage</h3>
 <div class="outline-text-3" id="text-8-5">
 <p>
 The abbey uses a separate volume to store surveillance recordings,
@@ -2472,8 +2627,8 @@ location do not fail.
 </div>
 </div>
 </div>
-<div id="outline-container-orgda7ae1e" class="outline-3">
-<h3 id="orgda7ae1e"><span class="section-number-3">8.6.</span> Install Custom NAGIOS Monitor <code>abbey_dvr</code></h3>
+<div id="outline-container-org53a1fb9" class="outline-3">
+<h3 id="org53a1fb9"><span class="section-number-3">8.6.</span> Install Custom NAGIOS Monitor <code>abbey_dvr</code></h3>
 <div class="outline-text-3" id="text-8-6">
 <p>
 DVR hosts install a custom NRPE plugin named <code>abbey_dvr</code> to monitor
@@ -2506,11 +2661,11 @@ the storage available on <q>/DVR/</q>.
 </div>
 </div>
 </div>
-<div id="outline-container-orgedf7836" class="outline-3">
-<h3 id="orgedf7836"><span class="section-number-3">8.7.</span> Configure IP Cameras</h3>
+<div id="outline-container-org943b187" class="outline-3">
+<h3 id="org943b187"><span class="section-number-3">8.7.</span> Configure IP Cameras</h3>
 <div class="outline-text-3" id="text-8-7">
 <p>
-A new security camera is setup as described in <a href="#org8f8c5fa">Cloistering</a>, after
+A new security camera is setup as described in <a href="#org66cd4b1">Cloistering</a>, after
 which the camera should be accessible by name on the abbey networks.
 Assuming <code>ping -c1 new</code> works, the camera's web interface will be
 accessible at <code>http://new/</code>.
@@ -2533,8 +2688,8 @@ protocol) is nice but optional.</li>
 </ul>
 </div>
 </div>
-<div id="outline-container-org5174d9b" class="outline-3">
-<h3 id="org5174d9b"><span class="section-number-3">8.8.</span> Configure AgentDVR's Cameras</h3>
+<div id="outline-container-org07765cc" class="outline-3">
+<h3 id="org07765cc"><span class="section-number-3">8.8.</span> Configure AgentDVR's Cameras</h3>
 <div class="outline-text-3" id="text-8-8">
 <p>
 After Ansible has configured and started the AgentDVR service, its web
@@ -2573,8 +2728,8 @@ AgentDVR's Live View.
 </p>
 </div>
 </div>
-<div id="outline-container-org4634264" class="outline-3">
-<h3 id="org4634264"><span class="section-number-3">8.9.</span> Configure AgentDVR's Default Storage</h3>
+<div id="outline-container-org7a1cf56" class="outline-3">
+<h3 id="org7a1cf56"><span class="section-number-3">8.9.</span> Configure AgentDVR's Default Storage</h3>
 <div class="outline-text-3" id="text-8-9">
 <p>
 AgentDVR's web interface is also used to configure a default storage
@@ -2586,8 +2741,8 @@ pressed before the task is complete.
 </p>
 </div>
 </div>
-<div id="outline-container-org509d777" class="outline-3">
-<h3 id="org509d777"><span class="section-number-3">8.10.</span> Configure AgentDVR's Recordings</h3>
+<div id="outline-container-org78f365b" class="outline-3">
+<h3 id="org78f365b"><span class="section-number-3">8.10.</span> Configure AgentDVR's Recordings</h3>
 <div class="outline-text-3" id="text-8-10">
 <p>
 After a default storage location has been configured, AgentDVR's
@@ -2618,8 +2773,8 @@ parameters are set (in the Recording and Storage tabs).
 </ul>
 </div>
 </div>
-<div id="outline-container-orgec04b1d" class="outline-3">
-<h3 id="orgec04b1d"><span class="section-number-3">8.11.</span> Restore AgentDVR</h3>
+<div id="outline-container-orge424487" class="outline-3">
+<h3 id="orge424487"><span class="section-number-3">8.11.</span> Restore AgentDVR</h3>
 <div class="outline-text-3" id="text-8-11">
 <p>
 When restoring <q>/home/</q> from a backup copy, the user accounts are
@@ -2635,8 +2790,8 @@ installs the system service configuration file and starts the service.
 </div>
 </div>
 </div>
-<div id="outline-container-org800724f" class="outline-2">
-<h2 id="org800724f"><span class="section-number-2">9.</span> The Abbey TVR Role</h2>
+<div id="outline-container-org0a40381" class="outline-2">
+<h2 id="org0a40381"><span class="section-number-2">9.</span> The Abbey TVR Role</h2>
 <div class="outline-text-2" id="text-9">
 <p>
 The abbey has a few TV tuners and a subscription to <a href="https://schedulesdirect.org/">Schedules Direct</a>
@@ -2651,14 +2806,14 @@ configured to serve MythTV pages at e.g. <code>http://new/mythweb/</code>.
 </p>
 
 <p>
-A new TVR machine needs only <a href="#org8f8c5fa">Cloistering</a> to prepare it for
+A new TVR machine needs only <a href="#org66cd4b1">Cloistering</a> to prepare it for
 Ansible.  As part of that process, it should be added to the <code>tvrs</code>
 group in the <q>hosts</q> file.  An existing server can become a TVR
 machine by adding it to the <code>tvrs</code> group.
 </p>
 </div>
-<div id="outline-container-org9d82305" class="outline-3">
-<h3 id="org9d82305"><span class="section-number-3">9.1.</span> Include Abbey Variables</h3>
+<div id="outline-container-orga49742f" class="outline-3">
+<h3 id="orga49742f"><span class="section-number-3">9.1.</span> Include Abbey Variables</h3>
 <div class="outline-text-3" id="text-9-1">
 <p>
 Private variables in <q>private/vars-abbey.yml</q> are needed, as in the
@@ -2674,8 +2829,8 @@ directory, <q>playbooks/</q>.
 </div>
 </div>
 </div>
-<div id="outline-container-org4003f1d" class="outline-3">
-<h3 id="org4003f1d"><span class="section-number-3">9.2.</span> Manually Build and Install MythTV</h3>
+<div id="outline-container-org0b99938" class="outline-3">
+<h3 id="org0b99938"><span class="section-number-3">9.2.</span> Manually Build and Install MythTV</h3>
 <div class="outline-text-3" id="text-9-2">
 <p>
 Neither Debian nor the MythTV project provide binary packages of
@@ -2704,8 +2859,8 @@ sudo apt install mythtv-backend
 </div>
 </div>
 </div>
-<div id="outline-container-org57498c9" class="outline-3">
-<h3 id="org57498c9"><span class="section-number-3">9.3.</span> Restore MythTV</h3>
+<div id="outline-container-org1eafc15" class="outline-3">
+<h3 id="org1eafc15"><span class="section-number-3">9.3.</span> Restore MythTV</h3>
 <div class="outline-text-3" id="text-9-3">
 <p>
 Restoring MythTV from a backup copy to a fresh TVR host:
@@ -2733,8 +2888,8 @@ The <q>.mythtv/config.xml</q> file should provide the DB particulars
 </ul>
 </div>
 </div>
-<div id="outline-container-org0642dda" class="outline-3">
-<h3 id="org0642dda"><span class="section-number-3">9.4.</span> Manually Load DB Timezone Info</h3>
+<div id="outline-container-org54d3b6b" class="outline-3">
+<h3 id="org54d3b6b"><span class="section-number-3">9.4.</span> Manually Load DB Timezone Info</h3>
 <div class="outline-text-3" id="text-9-4">
 <p>
 Starting with MythTV version 0.26, the time zone tables must be loaded
@@ -2758,8 +2913,8 @@ e.g. <code>2022-09-13 20:15:41</code>.
 </div>
 </div>
 </div>
-<div id="outline-container-orgbcb3462" class="outline-3">
-<h3 id="orgbcb3462"><span class="section-number-3">9.5.</span> Create MythTV Storage Area</h3>
+<div id="outline-container-org18496a1" class="outline-3">
+<h3 id="org18496a1"><span class="section-number-3">9.5.</span> Create MythTV Storage Area</h3>
 <div class="outline-text-3" id="text-9-5">
 <p>
 The backend does not have a default storage area for its recordings.
@@ -2783,8 +2938,8 @@ creates that directory and ensures it has appropriate permissions.
 </div>
 </div>
 </div>
-<div id="outline-container-orgce84d45" class="outline-3">
-<h3 id="orgce84d45"><span class="section-number-3">9.6.</span> Configure MythTV Backend</h3>
+<div id="outline-container-org1c294ef" class="outline-3">
+<h3 id="org1c294ef"><span class="section-number-3">9.6.</span> Configure MythTV Backend</h3>
 <div class="outline-text-3" id="text-9-6">
 <p>
 With MythTV built and installed, the post-installation tasks
@@ -2800,12 +2955,12 @@ at <code>http://new:6544</code> and make the following selections.
 </ul>
 </div>
 </div>
-<div id="outline-container-org0938d33" class="outline-3">
-<h3 id="org0938d33"><span class="section-number-3">9.7.</span> Configure Tuner</h3>
+<div id="outline-container-org7ca881c" class="outline-3">
+<h3 id="org7ca881c"><span class="section-number-3">9.7.</span> Configure Tuner</h3>
 <div class="outline-text-3" id="text-9-7">
 <p>
 The abbey has a Silicon Dust Homerun HDTV Duo (with two tuners).  It
-is setup as described in <a href="#org8f8c5fa">Cloistering</a>, after which the tuner is
+is setup as described in <a href="#org66cd4b1">Cloistering</a>, after which the tuner is
 accessible by name (e.g. <code>new</code>) on the cloister network.  Assuming
 <code>ping -c1 new</code> works, the tuner should be accessible via the
 <code>hdhomerun_config_gui</code> command, a graphical interface contributed to
@@ -2816,8 +2971,8 @@ tuner's domain name or IP address can also be entered.
 </p>
 </div>
 </div>
-<div id="outline-container-org1ef9aa1" class="outline-3">
-<h3 id="org1ef9aa1"><span class="section-number-3">9.8.</span> Add HDHomerun and Mr.Antenna</h3>
+<div id="outline-container-org16d6b6b" class="outline-3">
+<h3 id="org16d6b6b"><span class="section-number-3">9.8.</span> Add HDHomerun and Mr.Antenna</h3>
 <div class="outline-text-3" id="text-9-8">
 <p>
 In MythTV Setup:
@@ -2860,8 +3015,8 @@ any case, do <i>not</i> run <code>mythfilldatabase</code>.</li>
 </ul>
 </div>
 </div>
-<div id="outline-container-org84f12cd" class="outline-3">
-<h3 id="org84f12cd"><span class="section-number-3">9.9.</span> Scan for New Channels</h3>
+<div id="outline-container-orgf23d3fd" class="outline-3">
+<h3 id="orgf23d3fd"><span class="section-number-3">9.9.</span> Scan for New Channels</h3>
 <div class="outline-text-3" id="text-9-9">
 <p>
 In MythTV Backend, the website on Core's port 6544, e.g.
@@ -2882,8 +3037,8 @@ In MythTV Backend, the website on Core's port 6544, e.g.
 </ul>
 </div>
 </div>
-<div id="outline-container-orgba70a88" class="outline-3">
-<h3 id="orgba70a88"><span class="section-number-3">9.10.</span> Configure XMLTV</h3>
+<div id="outline-container-org1222df8" class="outline-3">
+<h3 id="org1222df8"><span class="section-number-3">9.10.</span> Configure XMLTV</h3>
 <div class="outline-text-3" id="text-9-10">
 <p>
 The <code>xmltv</code> package, specifically its <code>tv_grab_zz_sdjson</code> program, is
@@ -2918,7 +3073,7 @@ the list of "inputs" available in a postal code typically ends with
 the OTA (over the air) broadcasts.
 </p>
 
-<pre class="example" id="orgbb39bf5">
+<pre class="example" id="orgecde88f">
 $ tv_grab_zz_sdjson --configure --config-file .mythtv/Mr.Antenna.xml
 Cache file for lineups, schedules and programs.
 Cache file: [/home/mythtv/.xmltv/tv_grab_zz_sdjson.cache]
@@ -2968,8 +3123,8 @@ backend is running, so it is not run until then.
 </p>
 </div>
 </div>
-<div id="outline-container-orgeeeaf00" class="outline-3">
-<h3 id="orgeeeaf00"><span class="section-number-3">9.11.</span> Debug XMLTV</h3>
+<div id="outline-container-orgef98e7b" class="outline-3">
+<h3 id="orgef98e7b"><span class="section-number-3">9.11.</span> Debug XMLTV</h3>
 <div class="outline-text-3" id="text-9-11">
 <p>
 If the <code>mythfilldatabase</code> command fails or expected listings do not
@@ -3008,14 +3163,14 @@ Running a similar command (without <code>--quiet</code>) might be more revealing
 </div>
 </div>
 </div>
-<div id="outline-container-orge42a939" class="outline-3">
-<h3 id="orge42a939"><span class="section-number-3">9.12.</span> Change Broadcast Area</h3>
+<div id="outline-container-org43b95cb" class="outline-3">
+<h3 id="org43b95cb"><span class="section-number-3">9.12.</span> Change Broadcast Area</h3>
 <div class="outline-text-3" id="text-9-12">
 <p>
 The abbey changes location almost weekly, so its HDTV broadcast area
 changes frequently.  At the start of a long stay the administrator
 uses the MythTV Setup program to scan for the new area's channels, as
-described in <a href="#org84f12cd">Scan for New Channels</a>.
+described in <a href="#orgf23d3fd">Scan for New Channels</a>.
 </p>
 
 <p>
@@ -3033,7 +3188,7 @@ program as user <code>mythtv</code>.
 
 <p>
 The program will prompt for the zip code and offer a list of "inputs"
-available in that area, as described in <a href="#orgba70a88">Configure XMLTV</a>.
+available in that area, as described in <a href="#org1222df8">Configure XMLTV</a>.
 </p>
 
 <p>
@@ -3047,14 +3202,14 @@ Lastly, the administrator runs an immediate update (again as the
 </div>
 
 <p>
-If the command fails, consult <a href="#orgeeeaf00">Debug XMLTV</a>.  Else, the listings appear
+If the command fails, consult <a href="#orgef98e7b">Debug XMLTV</a>.  Else, the listings appear
 in MythTV Backend's "Program Guide" page.
 </p>
 </div>
 </div>
 </div>
-<div id="outline-container-orgaa3d276" class="outline-2">
-<h2 id="orgaa3d276"><span class="section-number-2">10.</span> The Ansible Configuration</h2>
+<div id="outline-container-org72723fe" class="outline-2">
+<h2 id="org72723fe"><span class="section-number-2">10.</span> The Ansible Configuration</h2>
 <div class="outline-text-2" id="text-10">
 <p>
 The abbey's Ansible configuration, like that of <a href="Institute/README.html">A Small Institute</a>, is
@@ -3081,7 +3236,7 @@ specific versions.
 </p>
 
 <p>
-NOTE: if you have not read at least the <a href="Institute/README.html#orga71113c">Overview</a> of <a href="Institute/README.html">A Small Institute</a>
+NOTE: if you have not read at least the <a href="Institute/README.html#org60861c5">Overview</a> of <a href="Institute/README.html">A Small Institute</a>
 you are lost.
 </p>
 
@@ -3111,8 +3266,8 @@ rest are built up piecemeal by (tangled from) this document,
 <q>README.org</q>, and <a href="Institute/README.html"><q>Institute/README.org</q></a>.
 </p>
 </div>
-<div id="outline-container-org1bde724" class="outline-3">
-<h3 id="org1bde724"><span class="section-number-3">10.1.</span> <q>ansible.cfg</q></h3>
+<div id="outline-container-org7ab0f36" class="outline-3">
+<h3 id="org7ab0f36"><span class="section-number-3">10.1.</span> <q>ansible.cfg</q></h3>
 <div class="outline-text-3" id="text-10-1">
 <p>
 This is much like the example (test) institutional configuration file,
@@ -3129,11 +3284,11 @@ except the roles are found in <q>Institute/roles/</q> as well as <q>roles/</q>.
 </div>
 </div>
 </div>
-<div id="outline-container-org35abcea" class="outline-3">
-<h3 id="org35abcea"><span class="section-number-3">10.2.</span> <q>hosts</q></h3>
+<div id="outline-container-org81aa71b" class="outline-3">
+<h3 id="org81aa71b"><span class="section-number-3">10.2.</span> <q>hosts</q></h3>
 <div class="outline-text-3" id="text-10-2">
 <div class="org-src-container">
-<a href="hosts"><q>hosts</q></a><pre class="src src-conf" id="org51b692b"><code>all:
+<a href="hosts"><q>hosts</q></a><pre class="src src-conf" id="org2a7459c"><code>all:
   vars:
     ansible_user: sysadm
     ansible_ssh_extra_args: -i Secret/ssh_admin/id_rsa
@@ -3142,6 +3297,9 @@ except the roles are found in <q>Institute/roles/</q> as well as <q>roles/</q>.
 </span>    droplet:
       ansible_host: 159.65.75.60
       ansible_become_password: <span class="org-string">"{{ become_droplet }}"</span>
+    debdrop:
+      ansible_host: 138.68.252.171
+      ansible_become_password: <span class="org-string">"{{ become_debdrop }}"</span>
     anoat:
       ansible_host: anoat.birchwood.private
       ansible_become_password: <span class="org-string">"{{ become_anoat }}"</span>
@@ -3155,10 +3313,13 @@ except the roles are found in <q>Institute/roles/</q> as well as <q>roles/</q>.
     dantooine:
       ansible_host: dantooine.birchwood.private
       ansible_become_password: <span class="org-string">"{{ become_dantooine }}"</span>
+    ord-mantell:
+      ansible_host: ord-mantell-w.birchwood.private
+      ansible_become_password: <span class="org-string">"{{ become_ord_mantell }}"</span>
     <span class="org-comment-delimiter"># </span><span class="org-comment">Notebooks
-</span>    endor:
-      ansible_host: endor.birchwood.private
-      ansible_become_password: <span class="org-string">"{{ become_endor }}"</span>
+</span>    felucia:
+      ansible_host: felucia.birchwood.private
+      ansible_become_password: <span class="org-string">"{{ become_felucia }}"</span>
     sullust:
       ansible_host: 127.0.0.1
       ansible_become_password: <span class="org-string">"{{ become_sullust }}"</span>
@@ -3172,6 +3333,7 @@ except the roles are found in <q>Institute/roles/</q> as well as <q>roles/</q>.
     front:
       hosts:
         droplet:
+        debdrop:
     gate:
       hosts:
         anoat:
@@ -3183,6 +3345,7 @@ except the roles are found in <q>Institute/roles/</q> as well as <q>roles/</q>.
         anoat:
         dantooine:
         kessel:
+        ord-mantell:
     dvrs:
       hosts:
         dantooine:
@@ -3193,22 +3356,24 @@ except the roles are found in <q>Institute/roles/</q> as well as <q>roles/</q>.
       hosts:
         dantooine:
         kessel:
+        ord-mantell:
     notebooks:
       hosts:
-        endor:
+        felucia:
         sullust:
     builders:
       hosts:
         dantooine:
-        endor:
+        felucia:
         kessel:
+        ord-mantell:
         sullust:
 </code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org2fb08a9" class="outline-3">
-<h3 id="org2fb08a9"><span class="section-number-3">10.3.</span> <q>playbooks/site.yml</q></h3>
+<div id="outline-container-orgc65a79f" class="outline-3">
+<h3 id="orgc65a79f"><span class="section-number-3">10.3.</span> <q>playbooks/site.yml</q></h3>
 <div class="outline-text-3" id="text-10-3">
 <p>
 This playbook provisions the entire network by applying first the
@@ -3249,17 +3414,17 @@ institutional roles, then the liturgical roles.
 </div>
 </div>
 </div>
-<div id="outline-container-orgdea09a3" class="outline-2">
-<h2 id="orgdea09a3"><span class="section-number-2">11.</span> The Abbey Commands</h2>
+<div id="outline-container-org4b0a2dc" class="outline-2">
+<h2 id="org4b0a2dc"><span class="section-number-2">11.</span> The Abbey Commands</h2>
 <div class="outline-text-2" id="text-11">
 <p>
 The <code>./abbey</code> script encodes the abbey's canonical procedures.  It
-includes <a href="Institute/README.html#org342bdb6">The Institute Commands</a> and adds a few abbey-specific
+includes <a href="Institute/README.html#org2fa987a">The Institute Commands</a> and adds a few abbey-specific
 sub-commands.
 </p>
 </div>
-<div id="outline-container-org446c5a5" class="outline-3">
-<h3 id="org446c5a5"><span class="section-number-3">11.1.</span> Abbey Command Overview</h3>
+<div id="outline-container-org11f8513" class="outline-3">
+<h3 id="org11f8513"><span class="section-number-3">11.1.</span> Abbey Command Overview</h3>
 <div class="outline-text-3" id="text-11-1">
 <p>
 Institutional sub-commands:
@@ -3288,8 +3453,8 @@ and <code>_architecture</code> for all hosts.</dd>
 </dl>
 </div>
 </div>
-<div id="outline-container-orgf6c367b" class="outline-3">
-<h3 id="orgf6c367b"><span class="section-number-3">11.2.</span> Abbey Command Script</h3>
+<div id="outline-container-org2c28ec7" class="outline-3">
+<h3 id="org2c28ec7"><span class="section-number-3">11.2.</span> Abbey Command Script</h3>
 <div class="outline-text-3" id="text-11-2">
 <p>
 The script begins with the following prefix and trampolines.
@@ -3302,7 +3467,8 @@ The script begins with the following prefix and trampolines.
 </span>
 <span class="org-keyword">use</span> <span class="org-constant">strict</span>;
 
-<span class="org-keyword">if</span> (grep { $<span class="org-variable-name">_</span> eq $<span class="org-variable-name">ARGV</span>[0] } qw<span class="org-string">(CA config new old pass client)</span>) {
+<span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0]
+    &amp;&amp; grep { $<span class="org-variable-name">_</span> eq $<span class="org-variable-name">ARGV</span>[0] } qw<span class="org-string">(CA config new old pass client)</span>) {
   <span class="org-keyword">exec</span> <span class="org-string">"./Institute/inst"</span>, @<span class="org-perl-non-scalar-variable">ARGV</span>;
 }
 </code></pre>
@@ -3312,7 +3478,7 @@ The script begins with the following prefix and trampolines.
 The small institute's <code>./inst</code> command expects to be running in
 <q>Institute/</q>, not <q>./</q>, but it only references <q>public/</q>, <q>private/</q>,
 <q>Secret/</q> and <q>playbooks/check-inst-vars.yml</q>, and will find the abbey
-specific versions of these.  The <code>roles_path</code> setting in <a href="#org1bde724"><q>ansible.cfg</q></a>
+specific versions of these.  The <code>roles_path</code> setting in <a href="#org7ab0f36"><q>ansible.cfg</q></a>
 effectively merges the institutional roles into the distinctly named
 abbey specific roles.  The roles likewise reference files with
 relative names, and will find the abbey specific <q>private/</q>
@@ -3326,13 +3492,17 @@ code block "duplicates" the action of the institute's
 </p>
 
 <div class="org-src-container">
-<a href="playbooks/check-inst-vars.yml"><q>playbooks/check-inst-vars.yml</q></a><pre class="src src-conf"><code>- import_playbook: ../Institute/playbooks/check-inst-vars.yml
+<a href="playbooks/check-inst-vars.yml"><q>playbooks/check-inst-vars.yml</q></a><pre class="src src-conf"><code>- hosts: localhost
+  gather_facts: no
+  tasks:
+  - import_role:
+      name: check-inst-vars
 </code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org617c88e" class="outline-3">
-<h3 id="org617c88e"><span class="section-number-3">11.3.</span> The Upgrade Command</h3>
+<div id="outline-container-org26884d7" class="outline-3">
+<h3 id="org26884d7"><span class="section-number-3">11.3.</span> The Upgrade Command</h3>
 <div class="outline-text-3" id="text-11-3">
 <p>
 The script implements an <code>upgrade</code> sub-command that runs <code>apt update</code>
@@ -3352,7 +3522,7 @@ a limit pattern.  For example:
 
 <div class="org-src-container">
 <a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">if</span> ($<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"upgrade"</span>) {
+<span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"upgrade"</span>) {
   shift;
   <span class="org-keyword">my</span> @<span class="org-perl-non-scalar-variable">args</span> = ( <span class="org-string">"-e"</span>, <span class="org-string">"\@Secret/become.yml"</span> );
   <span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"-n"</span>) {
@@ -3397,8 +3567,8 @@ a limit pattern.  For example:
 </div>
 </div>
 </div>
-<div id="outline-container-orgd4568a6" class="outline-3">
-<h3 id="orgd4568a6"><span class="section-number-3">11.4.</span> The Reboots Command</h3>
+<div id="outline-container-orgd697aef" class="outline-3">
+<h3 id="orgd697aef"><span class="section-number-3">11.4.</span> The Reboots Command</h3>
 <div class="outline-text-3" id="text-11-4">
 <p>
 The script implements a <code>reboots</code> sub-command that looks for
@@ -3406,7 +3576,7 @@ The script implements a <code>reboots</code> sub-command that looks for
 </p>
 
 <div class="org-src-container">
-<a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> ($<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"reboots"</span>) {
+<a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"reboots"</span>) {
   <span class="org-keyword">exec</span> (<span class="org-string">"ansible-playbook"</span>, <span class="org-string">"-e"</span>, <span class="org-string">"\@Secret/become.yml"</span>,
         <span class="org-string">"playbooks/reboots.yml"</span>);
 }
@@ -3429,8 +3599,8 @@ The script implements a <code>reboots</code> sub-command that looks for
 </div>
 </div>
 </div>
-<div id="outline-container-orgace0a9c" class="outline-3">
-<h3 id="orgace0a9c"><span class="section-number-3">11.5.</span> The Versions Command</h3>
+<div id="outline-container-orgac85b61" class="outline-3">
+<h3 id="orgac85b61"><span class="section-number-3">11.5.</span> The Versions Command</h3>
 <div class="outline-text-3" id="text-11-5">
 <p>
 The script implements a <code>versions</code> sub-command that reports the
@@ -3438,7 +3608,7 @@ operating system version of all abbey managed machines.
 </p>
 
 <div class="org-src-container">
-<a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> ($<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"versions"</span>) {
+<a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"versions"</span>) {
   <span class="org-keyword">exec</span> (<span class="org-string">"ansible-playbook"</span>, <span class="org-string">"-e"</span>, <span class="org-string">"\@Secret/become.yml"</span>,
         <span class="org-string">"playbooks/versarch.yml"</span>);
 }
@@ -3457,8 +3627,8 @@ operating system version of all abbey managed machines.
 </div>
 </div>
 </div>
-<div id="outline-container-org4db8014" class="outline-3">
-<h3 id="org4db8014"><span class="section-number-3">11.6.</span> The Facts Command</h3>
+<div id="outline-container-org8a4fb33" class="outline-3">
+<h3 id="org8a4fb33"><span class="section-number-3">11.6.</span> The Facts Command</h3>
 <div class="outline-text-3" id="text-11-6">
 <p>
 The script implements a <code>facts</code> sub-command to collect the Ansible
@@ -3466,7 +3636,7 @@ The script implements a <code>facts</code> sub-command to collect the Ansible
 </p>
 
 <div class="org-src-container">
-<a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> ($<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"facts"</span>) {
+<a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"facts"</span>) {
   <span class="org-keyword">my</span> $<span class="org-variable-name">line</span> = (<span class="org-string">"ansible all -m gather_facts -e \@Secret/become.yml"</span>
               . <span class="org-string">" &gt;facts"</span>);
   print <span class="org-string">"$line\n"</span>;
@@ -3478,8 +3648,8 @@ The script implements a <code>facts</code> sub-command to collect the Ansible
 </div>
 </div>
 </div>
-<div id="outline-container-orgacf6398" class="outline-3">
-<h3 id="orgacf6398"><span class="section-number-3">11.7.</span> The TZ Command</h3>
+<div id="outline-container-orgc63ebb2" class="outline-3">
+<h3 id="orgc63ebb2"><span class="section-number-3">11.7.</span> The TZ Command</h3>
 <div class="outline-text-3" id="text-11-7">
 <p>
 The abbey changes location almost weekly, so its timezone changes
@@ -3505,7 +3675,7 @@ last host in the previous play.
 </p>
 
 <div class="org-src-container">
-<a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> ($<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"tz"</span>) {
+<a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"tz"</span>) {
   <span class="org-keyword">exec</span> (<span class="org-string">"ansible-playbook"</span>, <span class="org-string">"-e"</span>, <span class="org-string">"\@Secret/become.yml"</span>,
         <span class="org-string">"playbooks/timezone.yml"</span>);
 }
@@ -3558,8 +3728,8 @@ last host in the previous play.
 </div>
 </div>
 </div>
-<div id="outline-container-org2cdf302" class="outline-3">
-<h3 id="org2cdf302"><span class="section-number-3">11.8.</span> Abbey Command Help</h3>
+<div id="outline-container-org0bc04b7" class="outline-3">
+<h3 id="org0bc04b7"><span class="section-number-3">11.8.</span> Abbey Command Help</h3>
 <div class="outline-text-3" id="text-11-8">
 <div class="org-src-container">
 <a href="abbey"><q>abbey</q></a><pre class="src src-perl"><code><span class="org-keyword">my</span> $<span class="org-variable-name">ops</span> = (<span class="org-string">"config,new,old,pass,client,"</span>
@@ -3570,8 +3740,8 @@ last host in the previous play.
 </div>
 </div>
 </div>
-<div id="outline-container-org8f8c5fa" class="outline-2">
-<h2 id="org8f8c5fa"><span class="section-number-2">12.</span> Cloistering</h2>
+<div id="outline-container-org66cd4b1" class="outline-2">
+<h2 id="org66cd4b1"><span class="section-number-2">12.</span> Cloistering</h2>
 <div class="outline-text-2" id="text-12">
 <p>
 This is how a new machine is brought into the cloister.  The process
@@ -3580,8 +3750,8 @@ narrows down to the common preparation of all machines administered by
 Ansible.
 </p>
 </div>
-<div id="outline-container-orgceca1ac" class="outline-3">
-<h3 id="orgceca1ac"><span class="section-number-3">12.1.</span> IoT Devices</h3>
+<div id="outline-container-orge4f11c6" class="outline-3">
+<h3 id="orge4f11c6"><span class="section-number-3">12.1.</span> IoT Devices</h3>
 <div class="outline-text-3" id="text-12-1">
 <p>
 A wireless IoT device (smart TV, Blu-ray deck, etc.) cannot install
@@ -3597,8 +3767,8 @@ given a private domain name as described in the following steps.
 </p>
 
 <ul class="org-ul">
-<li><a href="#orge0e82e4">Add to Core DHCP</a></li>
-<li><a href="#org546f3ac">Create Wired Domain Name</a></li>
+<li><a href="#org4597011">Add to Core DHCP</a></li>
+<li><a href="#org60e0ec7">Create Wired Domain Name</a></li>
 </ul>
 
 <p>
@@ -3608,12 +3778,12 @@ last step:
 </p>
 
 <ul class="org-ul">
-<li><a href="#org7cdfa7a">Create Wireless Domain Name</a></li>
+<li><a href="#org3976eb7">Create Wireless Domain Name</a></li>
 </ul>
 </div>
 </div>
-<div id="outline-container-org1e5d2b6" class="outline-3">
-<h3 id="org1e5d2b6"><span class="section-number-3">12.2.</span> Raspberry Pis</h3>
+<div id="outline-container-org548caea" class="outline-3">
+<h3 id="org548caea"><span class="section-number-3">12.2.</span> Raspberry Pis</h3>
 <div class="outline-text-3" id="text-12-2">
 <p>
 The abbey's Raspberry Pi runs the Raspberry Pi OS desktop off an NVMe
@@ -3621,31 +3791,40 @@ SSD.  A fresh install should go something like this:
 </p>
 
 <ul class="org-ul">
-<li>Write the disk image, <q>2023-12-05-raspios-bookworm-arm64.img.xz</q>, to
-the SSD and plug it into the Pi.  Leave the µSD card socket empty.</li>
+<li>Write the disk image, <q>2025-12-04-raspios-trixie-arm64-full.img.xz</q>,
+to the SSD and plug it into the Pi.  If the SSD is not readily
+accessible, write the disk image to a USB HD (thumb drive) or µSD
+card and insert it.</li>
 <li>Attach an HDMI monitor, a USB keyboard/mouse, and the cloister
 Ethernet, and power up.</li>
 <li>Answer first-boot installation questions:
 <ul class="org-ul">
 <li>Language: English (USA)</li>
 <li>Keyboard: English (USA)</li>
-<li>root password: &lt;blank&gt;</li>
-<li>new user name: System Administrator</li>
 <li>new username: sysadm</li>
 <li>new password: &lt;password&gt;</li>
 </ul></li>
-<li><a href="#orge0e82e4">Add to Core DHCP</a></li>
-<li><a href="#org546f3ac">Create Wired Domain Name</a></li>
-<li>Log in as <code>sysadm</code> on the console.</li>
+<li><a href="#org4597011">Add to Core DHCP</a></li>
+<li><a href="#org60e0ec7">Create Wired Domain Name</a></li>
+<li>Launch the desktop.</li>
+<li>If the desktop is running on a USB HD (thumb drive) or μSD card, use
+the Raspberry Pi Imager app in Accessories in the main menu.  Choose
+to install the 64-bit OS on the inaccessible SSD.  Rebooted without
+the USB HD or μSD card inserted and then answer the first-boot
+installation questions again.</li>
+<li>Right click on the desktop (background) and choose Preferences.  In
+the Control Centre choose Interfaces in the left side bar and toggle
+SSH on.</li>
+
 <li>Run <code>sudo raspi-config</code> and use the following menu items.
 <ul class="org-ul">
 <li>S4 Hostname (Set name for this computer on a network): new</li>
 <li>I1 SSH (Enable/disable remote command line access using SSH): enable</li>
 <li>A1 Expand Filesystem (Ensures that all of the SD card is available)</li>
 </ul></li>
-<li><a href="#org3648a3e">Update From Cloister Apt Cache</a></li>
-<li><a href="#org0a0b514">Authorize Remote Administration</a></li>
-<li><a href="#org2c82833">Configure with Ansible</a></li>
+<li><a href="#org7dac27c">Update From Cloister Apt Cache</a></li>
+<li><a href="#org712443e">Authorize Remote Administration</a></li>
+<li><a href="#org0455894">Configure with Ansible</a></li>
 </ul>
 
 <p>
@@ -3654,14 +3833,14 @@ steps are taken.
 </p>
 
 <ul class="org-ul">
-<li><a href="#orgf9b93eb">Connect to Cloister Wi-Fi</a></li>
-<li><a href="#orgac2ff07">Connect to Cloister VPN</a></li>
-<li><a href="#org7cdfa7a">Create Wireless Domain Name</a></li>
+<li><a href="#org6ea1bda">Connect to Cloister Wi-Fi</a></li>
+<li><a href="#org8a6aeb9">Connect to Cloister VPN</a></li>
+<li><a href="#org3976eb7">Create Wireless Domain Name</a></li>
 </ul>
 </div>
 </div>
-<div id="outline-container-org6696a14" class="outline-3">
-<h3 id="org6696a14"><span class="section-number-3">12.3.</span> PCs</h3>
+<div id="outline-container-orgb389fa1" class="outline-3">
+<h3 id="orgb389fa1"><span class="section-number-3">12.3.</span> PCs</h3>
 <div class="outline-text-3" id="text-12-3">
 <p>
 Most of the abbey's machines, like Core and Gate, are general-purpose
@@ -3670,26 +3849,25 @@ follows.
 </p>
 
 <ul class="org-ul">
-<li>Write the disk image, e.g. <q>debian-12.11.0-amd64-netinst.iso</q>, to a
-USB drive and connect it to the PC.</li>
+<li>Write the disk image, e.g. <q>debian-live-13.2.0-amd64-cinnamon.iso</q>,
+to a USB drive and connect it to the PC.</li>
 <li>Connect an HDMI monitor, a USB keyboard/mouse, and the cloister
 Ethernet, and power up.  Choose to boot from the USB drive.</li>
+<li><a href="#org4597011">Add to Core DHCP</a></li>
+<li><a href="#org60e0ec7">Create Wired Domain Name</a></li>
 <li>Answer first-boot installation questions as detailed in the
 preparation of <a href="Institute/README.org*A Test Machine">A Test Machine</a> for a Small Institute.</li>
-<li><a href="#orge0e82e4">Add to Core DHCP</a></li>
-<li><a href="#org546f3ac">Create Wired Domain Name</a></li>
 <li>Log in as <code>sysadm</code> on the console.</li>
-<li><a href="#org3648a3e">Update From Cloister Apt Cache</a></li>
+<li><a href="#org7dac27c">Update From Cloister Apt Cache</a></li>
 <li><p>
-Install OpenSSH, unless it already was when included in the initial
-Software selection during the Debian installation.  Run the
-following if unsure.
+Install <code>openssh-server</code>, unless it was included in the
+distribution.  Run the following if unsure.
 </p>
 <pre class="example">
 sudo apt install openssh-server
 </pre></li>
-<li><a href="#org0a0b514">Authorize Remote Administration</a></li>
-<li><a href="#org2c82833">Configure with Ansible</a></li>
+<li><a href="#org712443e">Authorize Remote Administration</a></li>
+<li><a href="#org0455894">Configure with Ansible</a></li>
 </ul>
 
 <p>
@@ -3698,14 +3876,14 @@ steps are taken.
 </p>
 
 <ul class="org-ul">
-<li><a href="#orgf9b93eb">Connect to Cloister Wi-Fi</a></li>
-<li><a href="#orgac2ff07">Connect to Cloister VPN</a></li>
-<li><a href="#org7cdfa7a">Create Wireless Domain Name</a></li>
+<li><a href="#org6ea1bda">Connect to Cloister Wi-Fi</a></li>
+<li><a href="#org8a6aeb9">Connect to Cloister VPN</a></li>
+<li><a href="#org3976eb7">Create Wireless Domain Name</a></li>
 </ul>
 </div>
 </div>
-<div id="outline-container-orge0e82e4" class="outline-3">
-<h3 id="orge0e82e4"><span class="section-number-3">12.4.</span> Add to Core DHCP</h3>
+<div id="outline-container-org4597011" class="outline-3">
+<h3 id="org4597011"><span class="section-number-3">12.4.</span> Add to Core DHCP</h3>
 <div class="outline-text-3" id="text-12-4">
 <p>
 When a new machine is connected to the cloister Ethernet, its MAC
@@ -3716,14 +3894,13 @@ provide network addresses to new devices automatically.
 <p>
 IoT devices (IP cameras, HDTV tuners, etc.) often have their MAC
 address printed on their case or mentioned in a configuration page.
-The MAC address <i>must</i> also appear in the device's DHCP Discover
-broadcasts, which are logged to <q>/var/log/daemon.log</q> on Core.  As a
-last (or first!) resort, the following command line should reveal the
-new device's MAC.
+The MAC address will also appear in the device's DHCP Discover
+broadcasts.  The following command displays the last 5 messages logged
+by the DHCP daemon and then waits for more.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><code>tail -100 /var/log/daemon.log | grep DISCOVER
+<pre class="src src-sh"><code>journalctl -t dhcpd -n 5 -f
 </code></pre>
 </div>
 
@@ -3766,12 +3943,12 @@ reporting <code>1 packets transmitted, 1 received, 0% packet loss...</code>.
 </div>
 </div>
 </div>
-<div id="outline-container-org546f3ac" class="outline-3">
-<h3 id="org546f3ac"><span class="section-number-3">12.5.</span> Create Wired Domain Name</h3>
+<div id="outline-container-org60e0ec7" class="outline-3">
+<h3 id="org60e0ec7"><span class="section-number-3">12.5.</span> Create Wired Domain Name</h3>
 <div class="outline-text-3" id="text-12-5">
 <p>
 A wired device is assigned an IP address when it is added to Core's
-DHCP configuration (as in <a href="#orge0e82e4">Add to Core DHCP</a>).  A private domain name is
+DHCP configuration (as in <a href="#org4597011">Add to Core DHCP</a>).  A private domain name is
 then associated with this address.  If the device is intended to
 operate wirelessly, the name for its address is modified with a <code>-w</code>
 suffix.  Thus <code>new-w.small.private</code> would be the name of the new
@@ -3814,8 +3991,8 @@ resolvectl query 192.168.56.4
 </div>
 </div>
 </div>
-<div id="outline-container-org3648a3e" class="outline-3">
-<h3 id="org3648a3e"><span class="section-number-3">12.6.</span> Update From Cloister Apt Cache</h3>
+<div id="outline-container-org7dac27c" class="outline-3">
+<h3 id="org7dac27c"><span class="section-number-3">12.6.</span> Update From Cloister Apt Cache</h3>
 <div class="outline-text-3" id="text-12-6">
 <ul class="org-ul">
 <li>Log in as <code>sysadm</code> on the console.</li>
@@ -3823,8 +4000,7 @@ resolvectl query 192.168.56.4
 Create <q>/etc/apt/apt.conf.d/01proxy</q>.
 </p>
 <pre class="example">
-D=apt-cacher.small.private.
-echo "Acquire::http::Proxy \"http://$D:3142\";" \
+echo "Acquire::http::Proxy \"http://192.168.56.1:3142\";" \
 | sudo tee /etc/apt/apt.conf.d/01proxy
 </pre></li>
 <li><p>
@@ -3838,8 +4014,8 @@ sudo reboot
 </ul>
 </div>
 </div>
-<div id="outline-container-org0a0b514" class="outline-3">
-<h3 id="org0a0b514"><span class="section-number-3">12.7.</span> Authorize Remote Administration</h3>
+<div id="outline-container-org712443e" class="outline-3">
+<h3 id="org712443e"><span class="section-number-3">12.7.</span> Authorize Remote Administration</h3>
 <div class="outline-text-3" id="text-12-7">
 <p>
 To remotely administer <code>new-w</code>, Ansible must be authorized to login as
@@ -3873,11 +4049,11 @@ key.
 </div>
 </div>
 </div>
-<div id="outline-container-org2c82833" class="outline-3">
-<h3 id="org2c82833"><span class="section-number-3">12.8.</span> Configure with Ansible</h3>
+<div id="outline-container-org0455894" class="outline-3">
+<h3 id="org0455894"><span class="section-number-3">12.8.</span> Configure with Ansible</h3>
 <div class="outline-text-3" id="text-12-8">
 <p>
-With remote administration authorized and tested (as in <a href="#org0a0b514">Authorize
+With remote administration authorized and tested (as in <a href="#org712443e">Authorize
 Remote Administration</a>), and the machine connected to the cloister
 Ethernet, the configuration of <code>new-w</code> can be completed by Ansible.
 Note that if the machine is staying on the cloister Ethernet, its
@@ -3885,7 +4061,7 @@ domain name will be <code>new</code> (having had no <code>-w</code> suffix added
 </p>
 
 <p>
-First <code>new-w</code> is added to Ansible's inventory in <a href="#org35abcea"><q>hosts</q></a>.  A <code>new-w</code>
+First <code>new-w</code> is added to Ansible's inventory in <a href="#org81aa71b"><q>hosts</q></a>.  A <code>new-w</code>
 section is added to the list of all hosts, and an empty section of the
 same name is added to the list of <code>campus</code> hosts.  If the machine uses
 the usual privileged account name, <code>sysadm</code>, the <code>ansible_user</code> key is
@@ -3933,8 +4109,8 @@ configuration files.
 </div>
 </div>
 </div>
-<div id="outline-container-orgf9b93eb" class="outline-3">
-<h3 id="orgf9b93eb"><span class="section-number-3">12.9.</span> Connect to Cloister Wi-Fi</h3>
+<div id="outline-container-org6ea1bda" class="outline-3">
+<h3 id="org6ea1bda"><span class="section-number-3">12.9.</span> Connect to Cloister Wi-Fi</h3>
 <div class="outline-text-3" id="text-12-9">
 <p>
 On an IoT device, or a Debian or Android "desktop", the cloister Wi-Fi
@@ -3975,8 +4151,8 @@ desktop connected to the Wi-Fi using the following <code>ping</code> command.
 </div>
 </div>
 </div>
-<div id="outline-container-orgac2ff07" class="outline-3">
-<h3 id="orgac2ff07"><span class="section-number-3">12.10.</span> Connect to Cloister VPN</h3>
+<div id="outline-container-org8a6aeb9" class="outline-3">
+<h3 id="org8a6aeb9"><span class="section-number-3">12.10.</span> Connect to Cloister VPN</h3>
 <div class="outline-text-3" id="text-12-10">
 <p>
 Wireless devices (with the cloister Wi-Fi password) can get an IP
@@ -3989,14 +4165,14 @@ however, are <i>not</i> accessible except via the cloister VPN.
 
 <p>
 Connections to the cloister VPN are authorized by the <code>./abbey
-client...</code> command (aka <a href="Institute/README.html#org4c26e9f">The Client Command</a>), which registers a new
+client...</code> command (aka <a href="Institute/README.html#org8465bda">The Client Command</a>), which registers a new
 client's public key and installs new WireGuard™ configurations on the
 servers.  Private keys are kept on the clients (e.g. in
 <q>/etc/wireguard/private-key</q>).
 </p>
 </div>
-<div id="outline-container-org5c70c2a" class="outline-4">
-<h4 id="org5c70c2a"><span class="section-number-4">12.10.1.</span> Campus Desktops and Servers</h4>
+<div id="outline-container-orge0f2773" class="outline-4">
+<h4 id="orge0f2773"><span class="section-number-4">12.10.1.</span> Campus Desktops and Servers</h4>
 <div class="outline-text-4" id="text-12-10-1">
 <p>
 Wireless Debian desktops (with NetworkManager) as well as servers
@@ -4082,8 +4258,8 @@ sudo systemctl enable wg-quick@wg0
 </ul>
 </div>
 </div>
-<div id="outline-container-org8fc3f18" class="outline-4">
-<h4 id="org8fc3f18"><span class="section-number-4">12.10.2.</span> Private Desktops</h4>
+<div id="outline-container-org9284b30" class="outline-4">
+<h4 id="org9284b30"><span class="section-number-4">12.10.2.</span> Private Desktops</h4>
 <div class="outline-text-4" id="text-12-10-2">
 <p>
 Member notebooks are private machines not remotely administered by the
@@ -4195,8 +4371,8 @@ password is included in <q>Secret/become.yml</q>.
 </p>
 </div>
 </div>
-<div id="outline-container-orgae5f81f" class="outline-4">
-<h4 id="orgae5f81f"><span class="section-number-4">12.10.3.</span> Android</h4>
+<div id="outline-container-org8722577" class="outline-4">
+<h4 id="org8722577"><span class="section-number-4">12.10.3.</span> Android</h4>
 <div class="outline-text-4" id="text-12-10-3">
 <p>
 Android phones and tablets are authorized to connect to the cloister
@@ -4233,8 +4409,8 @@ public VPN.</li>
 </div>
 </div>
 </div>
-<div id="outline-container-org7cdfa7a" class="outline-3">
-<h3 id="org7cdfa7a"><span class="section-number-3">12.11.</span> Create Wireless Domain Name</h3>
+<div id="outline-container-org3976eb7" class="outline-3">
+<h3 id="org3976eb7"><span class="section-number-3">12.11.</span> Create Wireless Domain Name</h3>
 <div class="outline-text-3" id="text-12-11">
 <p>
 A wireless machine is assigned a Wi-Fi address when it connects to the
@@ -4289,7 +4465,7 @@ be added to <q>private/db.campus_vpn</q>.)
 </div>
 <div id="postamble" class="status">
 <p class="author">Author: Matt Birkholz</p>
-<p class="date">Created: 2025-11-23 Sun 13:07</p>
+<p class="date">Created: 2026-01-02 Fri 15:07</p>
 <p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
 </div>
 </body>