Restart dnsmasq after a render, since a reload never applied one
tests / runner-env (confined) (pull_request_target) Successful in 59s
tests / tests (pull_request_target) Successful in 2m4s
tests / compose-schema (pull_request_target) Successful in 1m10s
tests / runner-env (privileged) (pull_request_target) Successful in 1m3s

The default reload command was systemctl reload dnsmasq, which is a SIGHUP.
dnsmasq does not re-read its config files on one, so a name added to a
declaration was installed and never loaded: jobs could not resolve it until
dnsmasq restarted for some other reason, while show and check both reported the
file as current.

The installer no longer offers the old value back, and a v4 note covers hosts
that have it, including the one restart render cannot do for them: it only
runs the command when the file changes, and on those hosts it already has.
This commit is contained in:
2026-10-10 21:34:22 -07:00
parent b953973626
commit b115fb977a
6 changed files with 68 additions and 12 deletions
+1 -1
View File
@@ -1 +1 @@
3
4
+12 -8
View File
@@ -85,7 +85,7 @@ declare -A CFG=(
[upstream]=""
[out]="/etc/dnsmasq.d/ci-allow.conf"
[ref]="main"
[reload]="systemctl reload dnsmasq"
[reload]="systemctl restart dnsmasq"
)
read_config() {
@@ -143,7 +143,7 @@ declare -A HINT=(
[upstream]="the resolver dnsmasq forwards ALLOWED queries to - the one that knows the answers, not this dnsmasq and not the bridge gateway. Whatever this host already resolves with: grep nameserver /etc/resolv.conf, or - if that says 127.0.0.53 - resolvectl status"
[out]="where the generated allowlist is written, e.g. /etc/dnsmasq.d/ci-allow.conf"
[ref]="the branch treated as operator-approved, normally main"
[reload]="the command that reloads the resolver, e.g. systemctl reload dnsmasq"
[reload]="the command that makes the resolver read the new allowlist, e.g. systemctl restart dnsmasq - not reload, which is a SIGHUP and does not re-read config files"
[token_file]="a file holding a read-only forge API token, mode 0600 - from the forge's Settings -> Applications page, NOT a runner registration token"
[repos_file]="one owner/repo per line - the repositories allowed to widen this runner's allowlist"
[base_file]="names allowed regardless of any project declaration, one per line"
@@ -1079,12 +1079,16 @@ case "$cmd" in
install -m 0644 "$new" "${CFG[out]}"
# Order matters. Flush first, then reload: the reload is a SIGHUP,
# which clears dnsmasq's cache, so the next query for a name that is
# still allowed goes upstream and puts its address back. Reloading
# first would leave a cached answer that repopulates nothing, and names
# that are still on the list would be unreachable until their TTL ran
# out.
# A RESTART, NOT A SIGHUP. SIGHUP clears the cache and re-reads hosts
# files, but not the config: a name added to the allowlist stayed
# unresolvable until dnsmasq happened to restart, while show and check
# both reported the file on disk as up to date.
#
# Order matters. Flush first, then restart: the restart empties
# dnsmasq's cache, so the next query for a name that is still allowed
# goes upstream and puts its address back. Restarting first would
# leave a cached answer that repopulates nothing, and names that are
# still on the list would be unreachable until their TTL ran out.
#
# Only on a removal. Flushing whenever anything changed would empty the
# set every time a name was added, and a job mid-run would find a
+3 -1
View File
@@ -69,4 +69,6 @@ out = /etc/dnsmasq.d/ci-allow.conf
# pull request can write gives up the entire point of this program.
ref = main
reload = systemctl reload dnsmasq
# Restart, not reload. A reload is a SIGHUP, and dnsmasq does not re-read
# its config files on one, so a newly allowed name would not resolve.
reload = systemctl restart dnsmasq
+5 -1
View File
@@ -787,7 +787,11 @@ say "resolver is reloaded. The defaults are right unless you have a reason."
say
ask_cfg out "Generated allowlist path" out /etc/dnsmasq.d/ci-allow.conf
ask_cfg ref "Branch treated as operator-approved" ref main
ask_cfg reload "Command that reloads the resolver" reload "systemctl reload dnsmasq"
# The old default is not offered back. A reload is a SIGHUP, which does not make
# dnsmasq re-read its config, so a host carrying it never applied a new name.
reload="$(cfg_get reload)"
case "$reload" in ""|"systemctl reload dnsmasq") reload="systemctl restart dnsmasq" ;; esac
ask reload "Command that reloads the resolver" "$reload"
say
# --- write ------------------------------------------------------------------
+1 -1
View File
@@ -641,7 +641,7 @@ IPSETEOF
}
@test "the flush happens before the reload, not after" {
# The reload is a SIGHUP, which clears dnsmasq's cache. Flushing after it
# The reload is a restart, which clears dnsmasq's cache. Flushing after it
# would leave cached answers that repopulate nothing, so names still on the
# list would be unreachable until their TTL ran out.
stub_ipset
+46
View File
@@ -0,0 +1,46 @@
---
version: 4
title: New allowlist names take effect without waiting for a restart
layers: guest
tiers: confined
snapshot: required
---
# v4: new allowlist names take effect without waiting for a restart
Confined tier only. One config line and one restart.
## Why
`render` applied a changed allowlist with `systemctl reload dnsmasq`. A reload
is a SIGHUP, and dnsmasq does not re-read its config files on one: it clears its
cache and re-reads hosts files only. A name added to a declaration was written to
`/etc/dnsmasq.d/ci-allow.conf` and never loaded, so jobs failed to resolve it
until dnsmasq happened to restart.
Nothing reported it. `show` prints the file and `check` compares the file, and
both were right about the file.
## 1. Change the command
In `/etc/dejima-ci/config`:
```
reload = systemctl restart dnsmasq
```
Or re-run `sudo ./install.sh`, which now offers that in place of the old value.
## 2. Restart dnsmasq once
```sh
sudo systemctl restart dnsmasq
```
**`render` does not do this for you.** It runs the command only when the
allowlist changes, and on a host that has been rendering all along the file is
already current. Whatever was added since dnsmasq last started stays unresolvable
until this.
**Re-snapshot before this tier's next scheduled rollback**, or the old command
comes back with it.