fix(bootstrap): offsite_enabled 改为先取变量再匹配,重跑不再因 SIGPIPE 竞态误删 off-site timer
This commit is contained in:
3 files changed
+26
-8
No files matched your search
+10
-5
@@ -3227,9 +3227,8 @@ auth_hostname() {
|
|||||||
# auth_lines is the body of the [auth] section this run writes: the carried keys, after
|
# auth_lines is the body of the [auth] section this run writes: the carried keys, after
|
||||||
# the two hostnames derived from the root domain when the carry lacks them. A first
|
# the two hostnames derived from the root domain when the carry lacks them. A first
|
||||||
# install gets exactly the two derived lines; a re-run reproduces the carried section.
|
# install gets exactly the two derived lines; a re-run reproduces the carried section.
|
||||||
# The keys are matched in a here-string, never `printf | grep -q`: grep exits at the
|
# The keys are matched in a here-string, never `printf | grep -q` (see offsite_enabled):
|
||||||
# match, printf dies of SIGPIPE on the lines after it, pipefail fails the test, and a
|
# a lost race there wrote a second admin_hostname, and the duplicate key broke the file.
|
||||||
# second admin_hostname then breaks the file (see postgres_installed).
|
|
||||||
auth_lines() {
|
auth_lines() {
|
||||||
local carried
|
local carried
|
||||||
carried="$(persisted_auth_lines)"
|
carried="$(persisted_auth_lines)"
|
||||||
@@ -3352,9 +3351,15 @@ offsite_block() {
|
|||||||
if [ -n "$FELIS_OFFSITE_DB_KEEP" ]; then printf 'db_keep = %s\n' "$FELIS_OFFSITE_DB_KEEP"; fi
|
if [ -n "$FELIS_OFFSITE_DB_KEEP" ]; then printf 'db_keep = %s\n' "$FELIS_OFFSITE_DB_KEEP"; fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# offsite_enabled: the [offsite] section this run writes names a bucket.
|
# offsite_enabled: the [offsite] section this run writes names a bucket. The section is
|
||||||
|
# read into a variable before matching (as in postgres_installed): in `offsite_block |
|
||||||
|
# grep -q` grep exits at the bucket line, the lines after it then kill offsite_block with
|
||||||
|
# SIGPIPE, and pipefail made that "no bucket". A re-run that lost the race removed the
|
||||||
|
# off-site timer and ended with NO OFF-SITE COPY on a host that has one.
|
||||||
offsite_enabled() {
|
offsite_enabled() {
|
||||||
offsite_block | grep -Eq '^[[:space:]]*bucket[[:space:]]*=[[:space:]]*"[^"]+"'
|
local block
|
||||||
|
block="$(offsite_block)"
|
||||||
|
grep -Eq '^[[:space:]]*bucket[[:space:]]*=[[:space:]]*"[^"]+"' <<<"$block"
|
||||||
}
|
}
|
||||||
|
|
||||||
write_felis_toml() {
|
write_felis_toml() {
|
||||||
|
|||||||
@@ -1577,8 +1577,8 @@ DNS.2 = play.example.org' "$out"
|
|||||||
|
|
||||||
# The hostnames on the section's first lines and the section far past one pipe buffer:
|
# The hostnames on the section's first lines and the section far past one pipe buffer:
|
||||||
# a `printf | grep -q` or `| awk exit` over it has the reader exit while printf is still
|
# a `printf | grep -q` or `| awk exit` over it has the reader exit while printf is still
|
||||||
# writing, which is certain here and a scheduling race on a real host. The config must
|
# writing, which is certain here and a scheduling race on a real host (offsite_enabled
|
||||||
# still carry each name once, and
|
# lost it, see the off-site section). The config must still carry each name once, and
|
||||||
# the helpers must fail nothing along the way (the installer logs every failed command).
|
# the helpers must fail nothing along the way (the installer logs every failed command).
|
||||||
{ printf '[auth]\nadmin_hostname = "ops.example.org"\npanel_hostname = "play.example.org"\n'
|
{ printf '[auth]\nadmin_hostname = "ops.example.org"\npanel_hostname = "play.example.org"\n'
|
||||||
seq 1 200000 | sed 's/.*/k& = "v"/'; } > "$adir/felis.host.toml"
|
seq 1 200000 | sed 's/.*/k& = "v"/'; } > "$adir/felis.host.toml"
|
||||||
@@ -1879,6 +1879,15 @@ case "$out" in
|
|||||||
*) echo "PASS the carried [offsite] stops at the next section" ;;
|
*) echo "PASS the carried [offsite] stops at the next section" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# A re-run found a configured bucket "missing" and removed the off-site timer: grep -q
|
||||||
|
# stopped at the bucket line while offsite_block was still writing, and pipefail turned
|
||||||
|
# the SIGPIPE into "no bucket". The section far past one pipe buffer with the bucket near
|
||||||
|
# its top makes the lost race certain.
|
||||||
|
{ printf '[offsite]\nbucket = "kept"\nendpoint = "https://s3.example"\n'
|
||||||
|
seq 1 200000 | sed 's/.*/prefix = "p&"/'; } > "$odir/felis.host.toml"
|
||||||
|
out="$(run_offsite 'if offsite_enabled; then echo ENABLED; else echo "OFF (exit $?)"; fi')"
|
||||||
|
expect "a configured bucket is found in a long [offsite] section" "ENABLED" "$out"
|
||||||
|
|
||||||
# First configured install: the key is generated, the file is private, the key is shown once.
|
# First configured install: the key is generated, the file is private, the key is shown once.
|
||||||
rm -f "$odir/felis.host.toml"
|
rm -f "$odir/felis.host.toml"
|
||||||
out="$(FELIS_OFFSITE_ENDPOINT=https://s3.example FELIS_OFFSITE_BUCKET=felis \
|
out="$(FELIS_OFFSITE_ENDPOINT=https://s3.example FELIS_OFFSITE_BUCKET=felis \
|
||||||
|
|||||||
@@ -2054,7 +2054,11 @@ a generated encryption key in `/etc/felis/offsite.env` (mode 0600), and
|
|||||||
sealed objects, and without the key they cannot be read. A later re-run keeps
|
sealed objects, and without the key they cannot be read. A later re-run keeps
|
||||||
the key; it refuses a `FELIS_OFFSITE_KEY` that differs from the one in
|
the key; it refuses a `FELIS_OFFSITE_KEY` that differs from the one in
|
||||||
`offsite.env`, since every object already in the bucket is sealed with it.
|
`offsite.env`, since every object already in the bucket is sealed with it.
|
||||||
Without a bucket the installer ends with `NO OFF-SITE COPY`.
|
Without a bucket the installer ends with `NO OFF-SITE COPY`. Installers before
|
||||||
|
the fix for a pipe race in reading `[offsite]` could also end that way on a
|
||||||
|
host that has a bucket, and removed `felis-offsite.timer` as they did; a re-run
|
||||||
|
of the current installer puts it back. `systemctl list-timers felis-offsite.timer`
|
||||||
|
shows whether the timer is there. [SH-TESTED] [VM-TESTED: a re-run that lost the race]
|
||||||
|
|
||||||
What runs:
|
What runs:
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user