Merge pull request 'fix: [nomad-step-3] S3.4 — wire --with woodpecker + deploy ordering + OAuth seed (#937)' (#943) from fix/issue-937-2 into main
This commit is contained in:
commit
a7a046b81a
2 changed files with 135 additions and 38 deletions
134
bin/disinto
134
bin/disinto
|
|
@ -82,7 +82,7 @@ Init options:
|
|||
--ci-id <n> Woodpecker CI repo ID (default: 0 = no CI)
|
||||
--forge-url <url> Forge base URL (default: http://localhost:3000)
|
||||
--backend <value> Orchestration backend: docker (default) | nomad
|
||||
--with <services> (nomad) Deploy services: forgejo[,...] (S1.3)
|
||||
--with <services> (nomad) Deploy services: forgejo,woodpecker[,...] (S1.3, S3.4)
|
||||
--empty (nomad) Bring up cluster only, no jobs (S0.4)
|
||||
--bare Skip compose generation (bare-metal setup)
|
||||
--build Use local docker build instead of registry images (dev mode)
|
||||
|
|
@ -784,16 +784,24 @@ _disinto_init_nomad() {
|
|||
|
||||
if [ -n "$with_services" ]; then
|
||||
# Vault seed plan (S2.6, #928): one line per service whose
|
||||
# tools/vault-seed-<svc>.sh ships. Services without a seeder are
|
||||
# silently skipped — the real-run loop below mirrors this,
|
||||
# making `--with woodpecker` in Step 3 auto-invoke
|
||||
# tools/vault-seed-woodpecker.sh once that file lands without
|
||||
# any further change to bin/disinto.
|
||||
# tools/vault-seed-<svc>.sh ships. Sub-services (woodpecker-server,
|
||||
# woodpecker-agent) map to their parent seeder (vault-seed-woodpecker.sh).
|
||||
# Deduplicated so the seeder runs once even when both sub-services
|
||||
# are present.
|
||||
local seed_hdr_printed=false
|
||||
local _seed_seen=""
|
||||
local IFS=','
|
||||
for svc in $with_services; do
|
||||
svc=$(echo "$svc" | xargs) # trim whitespace
|
||||
local seed_script="${FACTORY_ROOT}/tools/vault-seed-${svc}.sh"
|
||||
# Map sub-services to parent seed name
|
||||
local seed_name="$svc"
|
||||
case "$svc" in
|
||||
woodpecker-server|woodpecker-agent) seed_name="woodpecker" ;;
|
||||
esac
|
||||
# Deduplicate
|
||||
if echo ",$_seed_seen," | grep -q ",$seed_name,"; then continue; fi
|
||||
_seed_seen="${_seed_seen:+${_seed_seen},}${seed_name}"
|
||||
local seed_script="${FACTORY_ROOT}/tools/vault-seed-${seed_name}.sh"
|
||||
if [ -x "$seed_script" ]; then
|
||||
if [ "$seed_hdr_printed" = false ]; then
|
||||
echo "── Vault seed dry-run ─────────────────────────────────"
|
||||
|
|
@ -806,16 +814,18 @@ _disinto_init_nomad() {
|
|||
|
||||
echo "── Deploy services dry-run ────────────────────────────"
|
||||
echo "[deploy] services to deploy: ${with_services}"
|
||||
for svc in $with_services; do
|
||||
svc=$(echo "$svc" | xargs) # trim whitespace
|
||||
# Validate known services first
|
||||
case "$svc" in
|
||||
forgejo) ;;
|
||||
*)
|
||||
echo "Error: unknown service '${svc}' — known: forgejo" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Build ordered deploy list: only include services present in with_services
|
||||
local DEPLOY_ORDER=""
|
||||
for ordered_svc in forgejo woodpecker-server woodpecker-agent; do
|
||||
if echo ",$with_services," | grep -q ",$ordered_svc,"; then
|
||||
DEPLOY_ORDER="${DEPLOY_ORDER:+${DEPLOY_ORDER} }${ordered_svc}"
|
||||
fi
|
||||
done
|
||||
echo "[deploy] deployment order: ${DEPLOY_ORDER}"
|
||||
|
||||
local IFS=' '
|
||||
for svc in $DEPLOY_ORDER; do
|
||||
local jobspec_path="${FACTORY_ROOT}/nomad/jobs/${svc}.hcl"
|
||||
if [ ! -f "$jobspec_path" ]; then
|
||||
echo "Error: jobspec not found: ${jobspec_path}" >&2
|
||||
|
|
@ -937,18 +947,27 @@ _disinto_init_nomad() {
|
|||
# sets VAULT_ADDR in the child process regardless of sudoers policy.
|
||||
if [ -n "$with_services" ]; then
|
||||
local vault_addr="${VAULT_ADDR:-http://127.0.0.1:8200}"
|
||||
local _seed_seen=""
|
||||
local IFS=','
|
||||
for svc in $with_services; do
|
||||
svc=$(echo "$svc" | xargs) # trim whitespace
|
||||
local seed_script="${FACTORY_ROOT}/tools/vault-seed-${svc}.sh"
|
||||
# Map sub-services to parent seed name (S3.4)
|
||||
local seed_name="$svc"
|
||||
case "$svc" in
|
||||
woodpecker-server|woodpecker-agent) seed_name="woodpecker" ;;
|
||||
esac
|
||||
# Deduplicate
|
||||
if echo ",$_seed_seen," | grep -q ",$seed_name,"; then continue; fi
|
||||
_seed_seen="${_seed_seen:+${_seed_seen},}${seed_name}"
|
||||
local seed_script="${FACTORY_ROOT}/tools/vault-seed-${seed_name}.sh"
|
||||
if [ -x "$seed_script" ]; then
|
||||
echo ""
|
||||
echo "── Seeding Vault for ${svc} ───────────────────────────"
|
||||
echo "── Seeding Vault for ${seed_name} ───────────────────────────"
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
VAULT_ADDR="$vault_addr" "$seed_script" || exit $?
|
||||
else
|
||||
if ! command -v sudo >/dev/null 2>&1; then
|
||||
echo "Error: vault-seed-${svc}.sh must run as root and sudo is not installed" >&2
|
||||
echo "Error: vault-seed-${seed_name}.sh must run as root and sudo is not installed" >&2
|
||||
exit 1
|
||||
fi
|
||||
sudo -n -- env "VAULT_ADDR=$vault_addr" "$seed_script" || exit $?
|
||||
|
|
@ -961,23 +980,18 @@ _disinto_init_nomad() {
|
|||
if [ -n "$with_services" ]; then
|
||||
echo ""
|
||||
echo "── Deploying services ─────────────────────────────────"
|
||||
local -a deploy_cmd=("$deploy_sh")
|
||||
# Split comma-separated service list into positional args
|
||||
local IFS=','
|
||||
for svc in $with_services; do
|
||||
svc=$(echo "$svc" | xargs) # trim whitespace
|
||||
if ! echo "$svc" | grep -qE '^[a-zA-Z0-9_-]+$'; then
|
||||
echo "Error: invalid service name '${svc}' — must match ^[a-zA-Z0-9_-]+$" >&2
|
||||
exit 1
|
||||
|
||||
# Build ordered deploy list (S3.4): forgejo → woodpecker-server → woodpecker-agent
|
||||
local DEPLOY_ORDER=""
|
||||
for ordered_svc in forgejo woodpecker-server woodpecker-agent; do
|
||||
if echo ",$with_services," | grep -q ",$ordered_svc,"; then
|
||||
DEPLOY_ORDER="${DEPLOY_ORDER:+${DEPLOY_ORDER} }${ordered_svc}"
|
||||
fi
|
||||
# Validate known services FIRST (before jobspec check)
|
||||
case "$svc" in
|
||||
forgejo) ;;
|
||||
*)
|
||||
echo "Error: unknown service '${svc}' — known: forgejo" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local -a deploy_cmd=("$deploy_sh")
|
||||
local IFS=' '
|
||||
for svc in $DEPLOY_ORDER; do
|
||||
# Check jobspec exists
|
||||
local jobspec_path="${FACTORY_ROOT}/nomad/jobs/${svc}.hcl"
|
||||
if [ ! -f "$jobspec_path" ]; then
|
||||
|
|
@ -1012,9 +1026,15 @@ _disinto_init_nomad() {
|
|||
echo "Imported: (none — seed kv/disinto/* manually before deploying secret-dependent services)"
|
||||
fi
|
||||
echo "Deployed: ${with_services}"
|
||||
if echo "$with_services" | grep -q "forgejo"; then
|
||||
if echo ",$with_services," | grep -q ",forgejo,"; then
|
||||
echo "Ports: forgejo: 3000"
|
||||
fi
|
||||
if echo ",$with_services," | grep -q ",woodpecker-server,"; then
|
||||
echo " woodpecker-server: 8000"
|
||||
fi
|
||||
if echo ",$with_services," | grep -q ",woodpecker-agent,"; then
|
||||
echo " woodpecker-agent: (agent connected)"
|
||||
fi
|
||||
echo "────────────────────────────────────────────────────────"
|
||||
fi
|
||||
|
||||
|
|
@ -1100,6 +1120,46 @@ disinto_init() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Normalize --with services (S3.4): expand 'woodpecker' shorthand to
|
||||
# 'woodpecker-server,woodpecker-agent', auto-include forgejo when
|
||||
# woodpecker is requested (OAuth dependency), and validate all names.
|
||||
if [ -n "$with_services" ]; then
|
||||
# Expand 'woodpecker' (bare) → 'woodpecker-server,woodpecker-agent'.
|
||||
# Must not match already-expanded 'woodpecker-server'/'woodpecker-agent'.
|
||||
local expanded=""
|
||||
local IFS=','
|
||||
for _svc in $with_services; do
|
||||
_svc=$(echo "$_svc" | xargs)
|
||||
case "$_svc" in
|
||||
woodpecker) _svc="woodpecker-server,woodpecker-agent" ;;
|
||||
esac
|
||||
expanded="${expanded:+${expanded},}${_svc}"
|
||||
done
|
||||
with_services="$expanded"
|
||||
unset IFS
|
||||
|
||||
# Auto-include forgejo when woodpecker is requested
|
||||
if echo ",$with_services," | grep -q ",woodpecker-server,\|,woodpecker-agent," \
|
||||
&& ! echo ",$with_services," | grep -q ",forgejo,"; then
|
||||
echo "Note: --with woodpecker implies --with forgejo (OAuth dependency)"
|
||||
with_services="forgejo,${with_services}"
|
||||
fi
|
||||
|
||||
# Validate all service names are known
|
||||
local IFS=','
|
||||
for _svc in $with_services; do
|
||||
_svc=$(echo "$_svc" | xargs)
|
||||
case "$_svc" in
|
||||
forgejo|woodpecker-server|woodpecker-agent) ;;
|
||||
*)
|
||||
echo "Error: unknown service '${_svc}' — known: forgejo, woodpecker-server, woodpecker-agent" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
unset IFS
|
||||
fi
|
||||
|
||||
# --import-* flag validation (S2.5). These three flags form an import
|
||||
# triple and must be consistent before dispatch: sops encryption is
|
||||
# useless without the age key to decrypt it, so either both --import-sops
|
||||
|
|
|
|||
|
|
@ -215,7 +215,44 @@ setup_file() {
|
|||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --with unknown-service --dry-run
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"unknown service"* ]]
|
||||
[[ "$output" == *"known: forgejo"* ]]
|
||||
[[ "$output" == *"known: forgejo, woodpecker-server, woodpecker-agent"* ]]
|
||||
}
|
||||
|
||||
# S3.4: woodpecker auto-expansion and forgejo auto-inclusion
|
||||
@test "disinto init --backend=nomad --with woodpecker auto-expands to server+agent" {
|
||||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --with woodpecker --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"services to deploy: forgejo,woodpecker-server,woodpecker-agent"* ]]
|
||||
[[ "$output" == *"deployment order: forgejo woodpecker-server woodpecker-agent"* ]]
|
||||
}
|
||||
|
||||
@test "disinto init --backend=nomad --with woodpecker auto-includes forgejo with note" {
|
||||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --with woodpecker --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Note: --with woodpecker implies --with forgejo"* ]]
|
||||
}
|
||||
|
||||
@test "disinto init --backend=nomad --with forgejo,woodpecker expands woodpecker" {
|
||||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --with forgejo,woodpecker --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
# Order follows input: forgejo first, then woodpecker expanded
|
||||
[[ "$output" == *"services to deploy: forgejo,woodpecker-server,woodpecker-agent"* ]]
|
||||
[[ "$output" == *"deployment order: forgejo woodpecker-server woodpecker-agent"* ]]
|
||||
}
|
||||
|
||||
@test "disinto init --backend=nomad --with woodpecker seeds both forgejo and woodpecker" {
|
||||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --with woodpecker --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"tools/vault-seed-forgejo.sh --dry-run"* ]]
|
||||
[[ "$output" == *"tools/vault-seed-woodpecker.sh --dry-run"* ]]
|
||||
}
|
||||
|
||||
@test "disinto init --backend=nomad --with forgejo,woodpecker deploys all three services" {
|
||||
run "$DISINTO_BIN" init placeholder/repo --backend=nomad --with forgejo,woodpecker --dry-run
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"[deploy] [dry-run] nomad job validate"*"forgejo.hcl"* ]]
|
||||
[[ "$output" == *"[deploy] [dry-run] nomad job validate"*"woodpecker-server.hcl"* ]]
|
||||
[[ "$output" == *"[deploy] [dry-run] nomad job validate"*"woodpecker-agent.hcl"* ]]
|
||||
}
|
||||
|
||||
@test "disinto init --backend=nomad --with forgejo (flag=value syntax) works" {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue