mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-03 04:38:48 +00:00
fix(provider-msp): leave first-run platform running
Start the provider services after licensed compose validation so the printed bootstrap and portal link have a live control plane. Correct the first-run prompt to name only operator-provided values and retain an install contract regression test. Change-source: pulse-maintainer
This commit is contained in:
parent
08b4fa835c
commit
12ffa72a96
3 changed files with 78 additions and 16 deletions
|
|
@ -529,26 +529,16 @@ ensure_env_file() {
|
|||
|
||||
Created ${env_path} from .env.example.
|
||||
|
||||
Edit it now and set required values:
|
||||
- DOMAIN
|
||||
Edit it now and set the three values only you can supply:
|
||||
- DOMAIN (client workspaces are served at https://<client-id>.DOMAIN)
|
||||
- ACME_EMAIL
|
||||
- CF_DNS_API_TOKEN (with the default ACME_DNS_PROVIDER=cloudflare; for any
|
||||
other Traefik dnsChallenge provider, set ACME_DNS_PROVIDER and put that
|
||||
provider's credential variables in dns-credentials.env)
|
||||
- TRAEFIK_IMAGE (digest pinned)
|
||||
- DOCKER_SOCKET_PROXY_IMAGE (digest pinned)
|
||||
- CONTROL_PLANE_IMAGE (digest pinned)
|
||||
- CP_PULSE_IMAGE (digest pinned)
|
||||
- PULSE_PROVIDER_MSP_DATA_DIR
|
||||
- PULSE_PROVIDER_MSP_DOCKER_NETWORK
|
||||
- PULSE_PROVIDER_MSP_DOCKER_SUBNET
|
||||
- PULSE_PROVIDER_MSP_DOCKER_SOCKET
|
||||
- PULSE_PROVIDER_MSP_ROOT_SPACECHECK_DIR
|
||||
- PULSE_PROVIDER_MSP_DOCKER_SPACECHECK_DIR
|
||||
- CP_TRUSTED_PROXY_CIDRS
|
||||
|
||||
setup.sh will generate CP_ADMIN_KEY and CP_ENTITLEMENT_SIGNING_PRIVATE_KEY if they
|
||||
are still blank.
|
||||
Everything else has a working default. setup.sh resolves the image pins to
|
||||
digests and generates CP_ADMIN_KEY and CP_ENTITLEMENT_SIGNING_PRIVATE_KEY while
|
||||
they are blank.
|
||||
|
||||
EOF
|
||||
|
||||
|
|
@ -750,6 +740,24 @@ pull_provider_images() {
|
|||
done
|
||||
}
|
||||
|
||||
start_provider_services() {
|
||||
# Leave the platform running. The next steps setup prints (bootstrap, then
|
||||
# the portal sign-in link) only work against a running control plane; a
|
||||
# setup that stopped at "prepared" handed a first-time provider a sign-in
|
||||
# link that answered 404 until something else happened to start it.
|
||||
log "starting provider MSP services"
|
||||
(cd "${PULSE_PROVIDER_MSP_INSTALL_DIR}" && docker compose up -d traefik docker-socket-proxy control-plane)
|
||||
|
||||
local attempt
|
||||
for attempt in $(seq 1 30); do
|
||||
if (cd "${PULSE_PROVIDER_MSP_INSTALL_DIR}" && docker compose ps --services --status running 2>/dev/null) | grep -qx control-plane; then
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
die "control plane did not reach running state; inspect: cd ${PULSE_PROVIDER_MSP_INSTALL_DIR} && docker compose logs control-plane"
|
||||
}
|
||||
|
||||
run_install_proof_if_requested() {
|
||||
local mode
|
||||
mode="$(echo "${PULSE_PROVIDER_MSP_RUN_INSTALL_PROOF}" | tr '[:upper:]' '[:lower:]')"
|
||||
|
|
@ -786,7 +794,7 @@ print_summary() {
|
|||
|
||||
cat <<EOF
|
||||
|
||||
Pulse Provider MSP setup prepared.
|
||||
Pulse Provider MSP is running.
|
||||
|
||||
Paths:
|
||||
- Deploy dir: ${PULSE_PROVIDER_MSP_INSTALL_DIR}
|
||||
|
|
@ -850,6 +858,7 @@ main() {
|
|||
# signal rather than a record created before setup can succeed.
|
||||
ensure_eval_license
|
||||
validate_compose_config
|
||||
start_provider_services
|
||||
run_install_proof_if_requested
|
||||
print_summary
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2416,6 +2416,20 @@ artifact-selection behaviour.
|
|||
|
||||
## Current State
|
||||
|
||||
### Provider MSP setup leaves the platform running
|
||||
|
||||
`deploy/provider-msp/setup.sh` now ends by starting `traefik`,
|
||||
`docker-socket-proxy` and `control-plane` and waits for the control plane to
|
||||
run before printing its summary. It previously stopped at "setup prepared"
|
||||
with only the bootstrap command as the next step, so a first-time provider's
|
||||
sign-in link answered `404` until `run-install-proof.sh` or a manual
|
||||
`docker compose up -d` happened to start the control plane. The first-run
|
||||
message also names only the three values a provider must supply (`DOMAIN`,
|
||||
`ACME_EMAIL`, and the DNS-01 credential) instead of listing fourteen, most of
|
||||
which have working defaults or are generated. PR #2212 reports a v6.4.1
|
||||
first-run 404 and a 200 after starting the platform; this assigned candidate
|
||||
has not repeated that live-host proof.
|
||||
|
||||
### Provider MSP operations accept a renewed licence
|
||||
|
||||
`provider-msp preflight`, `proof`, `recover` and `backup` treat a licence
|
||||
|
|
|
|||
|
|
@ -593,3 +593,42 @@ func TestProviderMSPTraefikEnvIsMinimalAndDNSProviderOverridable(t *testing.T) {
|
|||
t.Fatal("CF_DNS_API_TOKEN is back in the unconditional required-env list; it must be required only when ACME_DNS_PROVIDER is cloudflare")
|
||||
}
|
||||
}
|
||||
|
||||
// setup.sh used to finish at "setup prepared" without starting the control
|
||||
// plane, so the bootstrap sign-in link it printed as the next step answered
|
||||
// 404 until the install proof or a manual compose up happened to start it.
|
||||
// Setup must bring the provider services up after the final compose
|
||||
// validation, wait for the control plane, and only then run the optional
|
||||
// install proof and print the summary.
|
||||
func TestProviderMSPSetupLeavesPlatformRunning(t *testing.T) {
|
||||
scriptBytes, err := os.ReadFile(repoFile("deploy", "provider-msp", "setup.sh"))
|
||||
if err != nil {
|
||||
t.Fatalf("read provider MSP setup: %v", err)
|
||||
}
|
||||
script := string(scriptBytes)
|
||||
|
||||
assertContainsAll(t, script,
|
||||
"start_provider_services() {",
|
||||
"docker compose up -d traefik docker-socket-proxy control-plane",
|
||||
"docker compose ps --services --status running",
|
||||
"grep -qx control-plane",
|
||||
"control plane did not reach running state",
|
||||
"Pulse Provider MSP is running.",
|
||||
)
|
||||
assertNotContainsAny(t, script, "Pulse Provider MSP setup prepared.")
|
||||
|
||||
sequence := " ensure_eval_license\n validate_compose_config\n start_provider_services\n run_install_proof_if_requested\n print_summary\n"
|
||||
if !strings.Contains(script, sequence) {
|
||||
t.Fatal("setup must start provider services after the licensed compose validation and before the install proof and summary")
|
||||
}
|
||||
|
||||
// The first-run prompt names only what a provider must supply.
|
||||
first := script[strings.Index(script, "Edit it now and set"):]
|
||||
first = first[:strings.Index(first, "EOF")]
|
||||
for _, generatedOrDefaulted := range []string{"TRAEFIK_IMAGE", "CP_PULSE_IMAGE", "PULSE_PROVIDER_MSP_DOCKER_SUBNET", "CP_TRUSTED_PROXY_CIDRS"} {
|
||||
if strings.Contains(first, " - "+generatedOrDefaulted) {
|
||||
t.Fatalf("first-run prompt still lists %s as a value the provider must set", generatedOrDefaulted)
|
||||
}
|
||||
}
|
||||
assertContainsAll(t, first, "DOMAIN", "ACME_EMAIL", "CF_DNS_API_TOKEN")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue