diff --git a/deployments/copyparty/deploy.sh b/deployments/copyparty/deploy.sh index 4dc9a25..5b42f0c 100644 --- a/deployments/copyparty/deploy.sh +++ b/deployments/copyparty/deploy.sh @@ -210,13 +210,25 @@ chown "$PUID:$PGID" "$DATA_DIR" ENV_FILE="$STACK_DIR/.env" set_env() { # : update KEY in .env, or append if absent - local key="$1" val="$2" esc - esc=${val//\\/\\\\}; esc=${esc//|/\\|}; esc=${esc//&/\\&} - if grep -qE "^${key}=" "$ENV_FILE"; then - sed -i -e "s|^${key}=.*|${key}=${esc}|" "$ENV_FILE" - else - printf '%s=%s\n' "$key" "$val" >> "$ENV_FILE" + # The value goes through the ENVIRONMENT, never interpolated into a sed + # script. Interpolating it corrupts any value containing & (sed expands it to + # the whole match) and aborts the run on one containing the s||| delimiter -- + # which is reachable for an OIDC secret, a password or a URL query string. + local key="$1" val="$2" tmp + if [[ ! -f "$ENV_FILE" ]]; then + printf '%s=%s +' "$key" "$val" >> "$ENV_FILE" + return 0 fi + tmp="$(mktemp)" + _SE_KEY="$key" _SE_VAL="$val" awk ' + BEGIN { k = ENVIRON["_SE_KEY"]; v = ENVIRON["_SE_VAL"]; seen = 0 } + !seen && index($0, k "=") == 1 { print k "=" v; seen = 1; next } + { print } + END { if (!seen) print k "=" v } + ' "$ENV_FILE" > "$tmp" + cat "$tmp" > "$ENV_FILE" # rewrite in place: keeps the original mode/owner + rm -f "$tmp" } # Pin COPYPARTY_TAG to the newest release so the running version is explicit. @@ -445,178 +457,182 @@ EOF # build.sh. exit 0 __ARCHIVE_BELOW__ -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 -VKYylalMZSrT/036L64TOhwAoAAA +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 diff --git a/deployments/copyparty/update.sh b/deployments/copyparty/update.sh index f17eb56..bd8c093 100644 --- a/deployments/copyparty/update.sh +++ b/deployments/copyparty/update.sh @@ -83,14 +83,26 @@ osfam() { # --------------------------------------------------------------------------- ENV_FILE="$STACK_DIR/.env" env_get() { [[ -f "$ENV_FILE" ]] && grep -E "^$1=" "$ENV_FILE" | head -n1 | cut -d= -f2- || true; } -env_set() { # - local key="$1" val="$2" esc - esc=${val//\\/\\\\}; esc=${esc//|/\\|}; esc=${esc//&/\\&} - if grep -qE "^${key}=" "$ENV_FILE"; then - sed -i -e "s|^${key}=.*|${key}=${esc}|" "$ENV_FILE" - else - printf '%s=%s\n' "$key" "$val" >> "$ENV_FILE" +env_set() { # : update KEY in .env, or append if absent + # The value goes through the ENVIRONMENT, never interpolated into a sed + # script. Interpolating it corrupts any value containing & (sed expands it to + # the whole match) and aborts the run on one containing the s||| delimiter -- + # which is reachable for an OIDC secret, a password or a URL query string. + local key="$1" val="$2" tmp + if [[ ! -f "$ENV_FILE" ]]; then + printf '%s=%s +' "$key" "$val" >> "$ENV_FILE" + return 0 fi + tmp="$(mktemp)" + _SE_KEY="$key" _SE_VAL="$val" awk ' + BEGIN { k = ENVIRON["_SE_KEY"]; v = ENVIRON["_SE_VAL"]; seen = 0 } + !seen && index($0, k "=") == 1 { print k "=" v; seen = 1; next } + { print } + END { if (!seen) print k "=" v } + ' "$ENV_FILE" > "$tmp" + cat "$tmp" > "$ENV_FILE" # rewrite in place: keeps the original mode/owner + rm -f "$tmp" } # strip a leading v and anything after the X.Y.Z core diff --git a/deployments/headscale/deploy.sh b/deployments/headscale/deploy.sh index 67a22ce..d884918 100644 --- a/deployments/headscale/deploy.sh +++ b/deployments/headscale/deploy.sh @@ -258,14 +258,25 @@ install -m 0640 "$SCRIPT_DIR/Caddyfile" "$STACK_DIR/Caddyfile" # .env set_env() { # : update KEY in .env, or append if absent - local key="$1" val="$2" esc - esc=${val//\/\\}; esc=${esc//|/\|}; esc=${esc//&/\&} - if grep -qE "^${key}=" "$ENV_FILE"; then - sed -i -e "s|^${key}=.*|${key}=${esc}|" "$ENV_FILE" - else + # The value goes through the ENVIRONMENT, never interpolated into a sed + # script. Interpolating it corrupts any value containing & (sed expands it to + # the whole match) and aborts the run on one containing the s||| delimiter -- + # which is reachable for an OIDC secret, a password or a URL query string. + local key="$1" val="$2" tmp + if [[ ! -f "$ENV_FILE" ]]; then printf '%s=%s ' "$key" "$val" >> "$ENV_FILE" + return 0 fi + tmp="$(mktemp)" + _SE_KEY="$key" _SE_VAL="$val" awk ' + BEGIN { k = ENVIRON["_SE_KEY"]; v = ENVIRON["_SE_VAL"]; seen = 0 } + !seen && index($0, k "=") == 1 { print k "=" v; seen = 1; next } + { print } + END { if (!seen) print k "=" v } + ' "$ENV_FILE" > "$tmp" + cat "$tmp" > "$ENV_FILE" # rewrite in place: keeps the original mode/owner + rm -f "$tmp" } if [[ ! -f "$ENV_FILE" ]]; then diff --git a/deployments/pocket-id/deploy.sh b/deployments/pocket-id/deploy.sh index 82e990b..64448d0 100644 --- a/deployments/pocket-id/deploy.sh +++ b/deployments/pocket-id/deploy.sh @@ -181,14 +181,25 @@ install -m 0640 "$SCRIPT_DIR/docker-compose.yml" "$STACK_DIR/docker-compose.yml" ENV_FILE="$STACK_DIR/.env" set_env() { # : update KEY in .env, or append if absent - local key="$1" val="$2" esc - esc=${val//\/\\}; esc=${esc//|/\|}; esc=${esc//&/\&} - if grep -qE "^${key}=" "$ENV_FILE"; then - sed -i -e "s|^${key}=.*|${key}=${esc}|" "$ENV_FILE" - else + # The value goes through the ENVIRONMENT, never interpolated into a sed + # script. Interpolating it corrupts any value containing & (sed expands it to + # the whole match) and aborts the run on one containing the s||| delimiter -- + # which is reachable for an OIDC secret, a password or a URL query string. + local key="$1" val="$2" tmp + if [[ ! -f "$ENV_FILE" ]]; then printf '%s=%s ' "$key" "$val" >> "$ENV_FILE" + return 0 fi + tmp="$(mktemp)" + _SE_KEY="$key" _SE_VAL="$val" awk ' + BEGIN { k = ENVIRON["_SE_KEY"]; v = ENVIRON["_SE_VAL"]; seen = 0 } + !seen && index($0, k "=") == 1 { print k "=" v; seen = 1; next } + { print } + END { if (!seen) print k "=" v } + ' "$ENV_FILE" > "$tmp" + cat "$tmp" > "$ENV_FILE" # rewrite in place: keeps the original mode/owner + rm -f "$tmp" } if [[ ! -f "$ENV_FILE" ]]; then diff --git a/deployments/squid/deploy.sh b/deployments/squid/deploy.sh index fe2161e..0fadd59 100644 --- a/deployments/squid/deploy.sh +++ b/deployments/squid/deploy.sh @@ -192,13 +192,25 @@ install -m 0644 "$SCRIPT_DIR/cache-domains.regex" "$STACK_DIR/cache-domains.rege ENV_FILE="$STACK_DIR/.env" set_env() { # : update KEY in .env, or append if absent - local key="$1" val="$2" esc - esc=${val//\\/\\\\}; esc=${esc//|/\\|}; esc=${esc//&/\\&} - if grep -qE "^${key}=" "$ENV_FILE"; then - sed -i -e "s|^${key}=.*|${key}=${esc}|" "$ENV_FILE" - else - printf '%s=%s\n' "$key" "$val" >> "$ENV_FILE" + # The value goes through the ENVIRONMENT, never interpolated into a sed + # script. Interpolating it corrupts any value containing & (sed expands it to + # the whole match) and aborts the run on one containing the s||| delimiter -- + # which is reachable for an OIDC secret, a password or a URL query string. + local key="$1" val="$2" tmp + if [[ ! -f "$ENV_FILE" ]]; then + printf '%s=%s +' "$key" "$val" >> "$ENV_FILE" + return 0 fi + tmp="$(mktemp)" + _SE_KEY="$key" _SE_VAL="$val" awk ' + BEGIN { k = ENVIRON["_SE_KEY"]; v = ENVIRON["_SE_VAL"]; seen = 0 } + !seen && index($0, k "=") == 1 { print k "=" v; seen = 1; next } + { print } + END { if (!seen) print k "=" v } + ' "$ENV_FILE" > "$tmp" + cat "$tmp" > "$ENV_FILE" # rewrite in place: keeps the original mode/owner + rm -f "$tmp" } if [[ ! -f "$ENV_FILE" ]]; then