fix(ci): smoke through service namespace (#1)
quality-gate / quality (push) Successful in 2m26s
quality-gate / container (push) Successful in 1m34s

This commit is contained in:
KyuubiYoru
2026-07-17 02:16:21 +02:00
parent 4423503bba
commit 589f802e2e
4 changed files with 17 additions and 29 deletions
+3 -8
View File
@@ -178,21 +178,16 @@ jobs:
docker compose -f "$compose_file" up --no-build --detach docker compose -f "$compose_file" up --no-build --detach
container_id="$(docker compose -f "$compose_file" ps -q rendezvous)" container_id="$(docker compose -f "$compose_file" ps -q rendezvous)"
test -n "$container_id" test -n "$container_id"
compose_network="$(docker inspect "$container_id" | jq -er \
'.[0].NetworkSettings.Networks | keys[0]')"
service_ip="$(docker inspect "$container_id" | jq -er \
--arg network "$compose_network" \
'.[0].NetworkSettings.Networks[$network].IPAddress')"
test "$(docker inspect --format '{{.Config.User}}' "$container_id")" = "1654:1654" test "$(docker inspect --format '{{.Config.User}}' "$container_id")" = "1654:1654"
test "$(docker inspect --format '{{.HostConfig.ReadonlyRootfs}}' "$container_id")" = "true" test "$(docker inspect --format '{{.HostConfig.ReadonlyRootfs}}' "$container_id")" = "true"
test "$(docker inspect --format '{{range .Mounts}}{{if eq .Destination "/app/appsettings.Production.json"}}{{.RW}}{{end}}{{end}}' "$container_id")" = "false" test "$(docker inspect --format '{{range .Mounts}}{{if eq .Destination "/app/appsettings.Production.json"}}{{.RW}}{{end}}{{end}}' "$container_id")" = "false"
test "$(docker inspect --format '{{range .Mounts}}{{if eq .Destination "/run/secrets/rendezvous-signing-key"}}{{.RW}}{{end}}{{end}}' "$container_id")" = "false" test "$(docker inspect --format '{{range .Mounts}}{{if eq .Destination "/run/secrets/rendezvous-signing-key"}}{{.RW}}{{end}}{{end}}' "$container_id")" = "false"
docker run --rm \ docker run --rm \
--network "$compose_network" \ --network "container:${container_id}" \
--user "$(id -u):$(id -g)" \ --user "$(id -u):$(id -g)" \
--env HOME=/tmp \ --env HOME=/tmp \
--env RENDEZVOUS_SMOKE_HTTP_URL="http://${service_ip}:8080/" \ --env RENDEZVOUS_SMOKE_HTTP_URL=http://127.0.0.1:8080/ \
--env RENDEZVOUS_SMOKE_UDP_ENDPOINT="${service_ip}:9050" \ --env RENDEZVOUS_SMOKE_UDP_ENDPOINT=127.0.0.1:9050 \
--env RENDEZVOUS_PUBLISHER_CREDENTIAL \ --env RENDEZVOUS_PUBLISHER_CREDENTIAL \
--volume "$runner_workspace_source:/source:ro" \ --volume "$runner_workspace_source:/source:ro" \
--workdir /source \ --workdir /source \
+3 -8
View File
@@ -140,17 +140,12 @@ jobs:
docker compose -f deploy/compose/compose.yaml up --detach --no-build docker compose -f deploy/compose/compose.yaml up --detach --no-build
container_id="$(docker compose -f deploy/compose/compose.yaml ps -q rendezvous)" container_id="$(docker compose -f deploy/compose/compose.yaml ps -q rendezvous)"
test -n "$container_id" test -n "$container_id"
compose_network="$(docker inspect "$container_id" | jq -er \
'.[0].NetworkSettings.Networks | keys[0]')"
service_ip="$(docker inspect "$container_id" | jq -er \
--arg network "$compose_network" \
'.[0].NetworkSettings.Networks[$network].IPAddress')"
docker run --rm \ docker run --rm \
--network "$compose_network" \ --network "container:${container_id}" \
--user "$(id -u):$(id -g)" \ --user "$(id -u):$(id -g)" \
--env HOME=/tmp \ --env HOME=/tmp \
--env RENDEZVOUS_SMOKE_HTTP_URL="http://${service_ip}:8080/" \ --env RENDEZVOUS_SMOKE_HTTP_URL=http://127.0.0.1:8080/ \
--env RENDEZVOUS_SMOKE_UDP_ENDPOINT="${service_ip}:9050" \ --env RENDEZVOUS_SMOKE_UDP_ENDPOINT=127.0.0.1:9050 \
--env RENDEZVOUS_PUBLISHER_CREDENTIAL \ --env RENDEZVOUS_PUBLISHER_CREDENTIAL \
--volume "$runner_workspace_source:/source:ro" \ --volume "$runner_workspace_source:/source:ro" \
--workdir /source \ --workdir /source \
+8 -8
View File
@@ -49,14 +49,14 @@ Compose, then point `RENDEZVOUS_SMOKE_HTTP_URL` and
and production-advertised service ports remain 8080/9050. Sibling-container CI and production-advertised service ports remain 8080/9050. Sibling-container CI
runners may also set `RENDEZVOUS_CONFIG_SOURCE` and runners may also set `RENDEZVOUS_CONFIG_SOURCE` and
`RENDEZVOUS_SECRET_SOURCE` to host-visible absolute bind-source paths; local `RENDEZVOUS_SECRET_SOURCE` to host-visible absolute bind-source paths; local
operators should normally keep the checked-in relative defaults. CI starts its operators should normally keep the checked-in relative defaults. CI runs its
ephemeral smoke client directly on the isolated Compose network; it does not ephemeral smoke client as a sidecar in the service container's network namespace
widen the default loopback HTTP publication. It mints the disposable publisher to avoid runner-specific bridge and host-routing policy; it does not widen the
credential while the generated key is still owner-private, then makes the key default loopback HTTP publication. It mints the disposable publisher credential
read-only for the non-root service container. Automation probes readiness once while the generated key is still owner-private, then makes the key read-only for
per second and allows up to three minutes for a cold, resource-constrained image the non-root service container. Automation probes readiness once per second and
to become ready; the protocol smoke retains its separate, stricter scenario allows up to three minutes for a cold, resource-constrained image to become
timeout. ready; the protocol smoke retains its separate, stricter scenario timeout.
`deploy/compose/appsettings.Production.json` is a local/private-bridge smoke `deploy/compose/appsettings.Production.json` is a local/private-bridge smoke
profile, not an Internet template: TCP is published only on host loopback, the profile, not an Internet template: TCP is published only on host loopback, the
@@ -178,15 +178,13 @@ public sealed class ReleaseCompatibilityTests
{ {
string workflow = File.ReadAllText(Path.Combine(root, ".gitea/workflows", workflowName)); string workflow = File.ReadAllText(Path.Combine(root, ".gitea/workflows", workflowName));
Assert.Contains("GITHUB_RUN_ID", workflow, StringComparison.Ordinal); Assert.Contains("GITHUB_RUN_ID", workflow, StringComparison.Ordinal);
Assert.Contains("compose_network", workflow, StringComparison.Ordinal); Assert.Contains("--network \"container:${container_id}\"", workflow, StringComparison.Ordinal);
Assert.Contains("--network \"$compose_network\"", workflow, StringComparison.Ordinal);
Assert.Contains("publisher_credential", workflow, StringComparison.Ordinal); Assert.Contains("publisher_credential", workflow, StringComparison.Ordinal);
Assert.Contains("RENDEZVOUS_PUBLISHER_CREDENTIAL", workflow, StringComparison.Ordinal); Assert.Contains("RENDEZVOUS_PUBLISHER_CREDENTIAL", workflow, StringComparison.Ordinal);
Assert.Contains("for attempt in {1..180}", workflow, StringComparison.Ordinal); Assert.Contains("for attempt in {1..180}", workflow, StringComparison.Ordinal);
Assert.Contains("sleep 1", workflow, StringComparison.Ordinal); Assert.Contains("sleep 1", workflow, StringComparison.Ordinal);
Assert.Contains("service_ip", workflow, StringComparison.Ordinal); Assert.Contains("http://127.0.0.1:8080/", workflow, StringComparison.Ordinal);
Assert.Contains("http://${service_ip}:8080/", workflow, StringComparison.Ordinal); Assert.Contains("127.0.0.1:9050", workflow, StringComparison.Ordinal);
Assert.Contains("${service_ip}:9050", workflow, StringComparison.Ordinal);
Assert.Contains("RENDEZVOUS_HTTP_HOST_PORT", workflow, StringComparison.Ordinal); Assert.Contains("RENDEZVOUS_HTTP_HOST_PORT", workflow, StringComparison.Ordinal);
Assert.Contains("RENDEZVOUS_UDP_HOST_PORT", workflow, StringComparison.Ordinal); Assert.Contains("RENDEZVOUS_UDP_HOST_PORT", workflow, StringComparison.Ordinal);
Assert.Contains("RENDEZVOUS_SMOKE_HTTP_URL", workflow, StringComparison.Ordinal); Assert.Contains("RENDEZVOUS_SMOKE_HTTP_URL", workflow, StringComparison.Ordinal);