selector: --org and --business in stack-upgrade's args-file scopes
read_args takes --org as --business in the unit flags before -- and in the serve flags after it, with per-scope duplicate and conflict refusal, and refuses a file whose serve flags name no selector or another business, as case2-unit.sh would at the render after A2 stopped the units. The serve flags are walked with case2-unit.sh's grammar so a value is never read as a selector. The file is not rewritten; only --copy's value changes, as before. A checkout without scripts/selector.sh refuses checkout-unreadable.
This commit is contained in:
1 parent
226be2e935
commit
9e458878df
2 files changed
+141
-10
No files matched your search
@@ -12,10 +12,13 @@
|
||||
# Root runs it from a root-owned checkout of the reviewed commit, never from a copy, because the
|
||||
# stack's user can write the copies. The unit values come from /etc/mosaic-stack/<instance>.args,
|
||||
# which I2's install writes: one case2-unit.sh argument per line, the serve flags after `--`. Only
|
||||
# --copy changes, and the file changes only after confirm passes. The stack's user runs its steps
|
||||
# from its own clone, <home>/src/mosaic-stack, through sudo. Root reads none of that user's output
|
||||
# but exit codes and the rehearsal's BACKUP_STORE line (sage-1653), which it copies into its step
|
||||
# log after a match against a fixed pattern and decides nothing on.
|
||||
# --copy changes, and the file changes only after confirm passes. --org is the same option as
|
||||
# --business in each of the file's two scopes, case2-unit.sh's own flags before `--` and the serve
|
||||
# flags after it: each scope takes each spelling once, a second spelling only with the same value,
|
||||
# and both scopes must name the business, the same one (rename design r2). The stack's user runs
|
||||
# its steps from its own clone, <home>/src/mosaic-stack, through sudo. Root reads none of that user's
|
||||
# output but exit codes and the rehearsal's BACKUP_STORE line (sage-1653), which it copies into its
|
||||
# step log after a match against a fixed pattern and decides nothing on.
|
||||
#
|
||||
# --no-rehearsal is for a stack whose log records no backup. The rehearsal runs either way: exit 3
|
||||
# from it (no-backup) goes on only with the flag, and exit 0 with the flag refuses
|
||||
@@ -119,6 +122,12 @@ logl "start rc=0 argv:$(printf ' %q' "$0" "${ARGV[@]}")"
|
||||
|
||||
# --- The args file and the stack's user ---
|
||||
|
||||
# The selector scopes: selector.sh defines functions only, from this root-owned checkout, as RENDER is.
|
||||
. "$REPO/scripts/selector.sh" || refuse checkout-unreadable "cannot read $REPO/scripts/selector.sh"
|
||||
args_business_ok() { [[ "$1" =~ ^[a-z0-9][a-z0-9-]*$ ]]; }
|
||||
args_outer_refused() { refuse args-unreadable "$ETC/$INSTANCE.args before --: $2"; }
|
||||
args_serve_refused() { refuse args-unreadable "$ETC/$INSTANCE.args after --: $2"; }
|
||||
|
||||
# I2's file: one case2-unit.sh argument per line, owned by root with no group or other write. Sets
|
||||
# ARGS (the lines), S_USER, S_HOME, BUSINESS, NODE, ARGS_COPY, ARGS_PROFILE and ARGS_PROXY, and the paths derived
|
||||
# from them.
|
||||
@@ -126,8 +135,12 @@ logl "start rc=0 argv:$(printf ' %q' "$0" "${ARGV[@]}")"
|
||||
# --profile wins, as there), and the current one refuses it. A2 would stop both units, and A4 and
|
||||
# render-old would both fail on the same args, so a library file holding --send after -- refuses
|
||||
# here, before anything stops. The file is never rewritten; the operator removes the line.
|
||||
# Rename r2: case2-unit.sh also refuses a file whose serve flags name no selector or another
|
||||
# business, so that refuses here too. The serve flags are read with case2-unit.sh's grammar, which
|
||||
# says which of them take a value, so a value is never taken for a selector; a token that grammar
|
||||
# lacks refuses, as the render would.
|
||||
read_args() {
|
||||
local f="$ETC/$INSTANCE.args" st i copies=0 v profile=library
|
||||
local f="$ETC/$INSTANCE.args" st i sep copies=0 v profile=library served
|
||||
[ -f "$f" ] && [ ! -L "$f" ] || refuse args-unreadable "no regular file $f"
|
||||
st="$(stat -c '%u %a' "$f")" || refuse args-unreadable "cannot stat $f"
|
||||
[ "${st% *}" = "$(id -u)" ] && (( (8#${st#* } & 8#022) == 0 )) || refuse args-unreadable "$f must be $(id -un)'s with no group or other write (it is uid ${st% *}, mode ${st#* })"
|
||||
@@ -138,10 +151,13 @@ read_args() {
|
||||
--) break ;;
|
||||
--pm) ;;
|
||||
--proxy) ARGS_PROXY=1 ;;
|
||||
--user|--home|--business|--copy|--node|--profile|--claude)
|
||||
--business|--org)
|
||||
selector_take outer id args_outer_refused args_business_ok "${ARGS[i]}" "${ARGS[i + 1]:-}"
|
||||
BUSINESS="${ARGS[i + 1]}"; i=$((i + 1)) ;;
|
||||
--user|--home|--copy|--node|--profile|--claude)
|
||||
v="${ARGS[i + 1]:-}"
|
||||
case "${ARGS[i]}" in
|
||||
--user) S_USER="$v" ;; --home) S_HOME="$v" ;; --business) BUSINESS="$v" ;; --node) NODE="$v" ;;
|
||||
--user) S_USER="$v" ;; --home) S_HOME="$v" ;; --node) NODE="$v" ;;
|
||||
--copy) ARGS_COPY="$v"; copies=$((copies + 1)) ;;
|
||||
--profile) profile="$v" ;;
|
||||
esac
|
||||
@@ -149,6 +165,7 @@ read_args() {
|
||||
*) refuse args-unreadable "$f has ${ARGS[i]} before --, which case2-unit.sh does not take" ;;
|
||||
esac
|
||||
done
|
||||
sep=$i
|
||||
[ "$copies" = 1 ] || refuse args-unreadable "$f needs exactly one --copy before --, not $copies"
|
||||
ARGS_PROFILE="$profile"
|
||||
if [ "$profile" = library ]; then
|
||||
@@ -160,6 +177,18 @@ read_args() {
|
||||
[[ "$S_USER" =~ ^[a-z_][a-z0-9_-]*$ ]] && [[ "$S_HOME" =~ ^/[A-Za-z0-9/._+-]+$ ]] && [[ "$BUSINESS" =~ ^[a-z0-9][a-z0-9-]*$ ]] &&
|
||||
[[ "$NODE" =~ ^/[A-Za-z0-9/._+-]+$ ]] && [[ "$ARGS_COPY" =~ ^[0-9a-f]{40}$ ]] ||
|
||||
refuse args-unreadable "$f lacks a plain --user, --home, --business, --node or --copy"
|
||||
for ((i = sep + 1; i < ${#ARGS[@]}; i++)); do
|
||||
case "${ARGS[i]}" in
|
||||
--business|--org)
|
||||
selector_take serve id args_serve_refused args_business_ok "${ARGS[i]}" "${ARGS[i + 1]:-}"; i=$((i + 1)) ;;
|
||||
--port|--public-host|--auth-header|--allow-user|--proof-header|--proof-file) i=$((i + 1)) ;;
|
||||
--tester-socket|--sso|--send) ;;
|
||||
*) refuse args-unreadable "$f has ${ARGS[i]} after --, which case2-unit.sh does not take" ;;
|
||||
esac
|
||||
done
|
||||
served="$(selector_value serve)"
|
||||
[ -n "$served" ] || refuse args-unreadable "$f needs --business or --org after --, as case2-unit.sh does"
|
||||
[ "$served" = "$BUSINESS" ] || refuse args-unreadable "$f names business $BUSINESS before -- and $served after it"
|
||||
COPIES_DIR="$S_HOME/.local/share/mosaic-stack/copies"
|
||||
CLONE="$S_HOME/src/mosaic-stack"
|
||||
SR="$CLONE/scripts/stack-release.sh"
|
||||
|
||||
Reference in new issue
Block a user