Fix Server release checks for the LAN-only listener [skip ci]
This commit is contained in:
+26
-15
@@ -16,6 +16,7 @@ from pathlib import Path
|
|||||||
APP = Path("/srv/pigway/apps/pigway-frame-flow")
|
APP = Path("/srv/pigway/apps/pigway-frame-flow")
|
||||||
RECOVERY = Path("/srv/pigway/recovery/frame-flow")
|
RECOVERY = Path("/srv/pigway/recovery/frame-flow")
|
||||||
CONTAINER = "pigway-frame-flow"
|
CONTAINER = "pigway-frame-flow"
|
||||||
|
ORIGIN = "http://192.0.2.10:81"
|
||||||
|
|
||||||
|
|
||||||
def run(*args):
|
def run(*args):
|
||||||
@@ -62,11 +63,16 @@ def archive_staging(backup, ctx):
|
|||||||
for tag in [
|
for tag in [
|
||||||
"pigway-frame-flow:history-ui-local-base",
|
"pigway-frame-flow:history-ui-local-base",
|
||||||
"pigway-frame-flow:final-audit-local-base",
|
"pigway-frame-flow:final-audit-local-base",
|
||||||
|
"pigway-frame-flow:0.1.9-5d2171b9be3e",
|
||||||
]:
|
]:
|
||||||
tags = run(
|
tags = run(
|
||||||
"docker", "image", "ls", "--format", "{{.Repository}}:{{.Tag}}"
|
"docker", "image", "ls", "--format", "{{.Repository}}:{{.Tag}}"
|
||||||
).splitlines()
|
).splitlines()
|
||||||
if tag in tags and tag not in references:
|
if (
|
||||||
|
tag in tags
|
||||||
|
and tag not in references
|
||||||
|
and not run("docker", "ps", "-aq", "--filter", "ancestor=" + tag)
|
||||||
|
):
|
||||||
run("docker", "image", "rm", tag)
|
run("docker", "image", "rm", tag)
|
||||||
removed.append(tag)
|
removed.append(tag)
|
||||||
return {
|
return {
|
||||||
@@ -76,6 +82,18 @@ def archive_staging(backup, ctx):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def wait_ready():
|
||||||
|
for attempt in range(30):
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(ORIGIN + "/ready", timeout=4) as r:
|
||||||
|
assert json.load(r)["status"] == "ready"
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
if attempt == 29:
|
||||||
|
raise
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
def verify_runtime(commit):
|
def verify_runtime(commit):
|
||||||
c = inspect()
|
c = inspect()
|
||||||
env = dict(s.split("=", 1) for s in c["Config"]["Env"])
|
env = dict(s.split("=", 1) for s in c["Config"]["Env"])
|
||||||
@@ -163,18 +181,9 @@ def release(lock):
|
|||||||
try:
|
try:
|
||||||
changed = True
|
changed = True
|
||||||
(APP / "compose.json").write_text(json.dumps(compose, indent=2) + "\n")
|
(APP / "compose.json").write_text(json.dumps(compose, indent=2) + "\n")
|
||||||
|
print("Restarting Frame Flow; checking " + ORIGIN + "/ready", flush=True)
|
||||||
run("systemctl", "restart", "pigway-frame-flow.service")
|
run("systemctl", "restart", "pigway-frame-flow.service")
|
||||||
for attempt in range(30):
|
wait_ready()
|
||||||
try:
|
|
||||||
with urllib.request.urlopen(
|
|
||||||
"http://127.0.0.1:81/ready", timeout=4
|
|
||||||
) as r:
|
|
||||||
assert json.load(r)["status"] == "ready"
|
|
||||||
break
|
|
||||||
except Exception:
|
|
||||||
if attempt == 29:
|
|
||||||
raise
|
|
||||||
time.sleep(2)
|
|
||||||
current = verify_runtime(commit)
|
current = verify_runtime(commit)
|
||||||
assert current["Image"] == run(
|
assert current["Image"] == run(
|
||||||
"docker", "image", "inspect", "--format", "{{.Id}}", image
|
"docker", "image", "inspect", "--format", "{{.Id}}", image
|
||||||
@@ -202,9 +211,7 @@ def release(lock):
|
|||||||
"index.html",
|
"index.html",
|
||||||
"style.css",
|
"style.css",
|
||||||
]:
|
]:
|
||||||
url = "http://127.0.0.1:81/" + (
|
url = ORIGIN + "/" + ("" if name == "index.html" else "ui/" + name)
|
||||||
"" if name == "index.html" else "ui/" + name
|
|
||||||
)
|
|
||||||
with urllib.request.urlopen(url, timeout=10) as response:
|
with urllib.request.urlopen(url, timeout=10) as response:
|
||||||
assert (
|
assert (
|
||||||
response.read()
|
response.read()
|
||||||
@@ -212,6 +219,7 @@ def release(lock):
|
|||||||
)
|
)
|
||||||
run("systemctl", "is-active", "pigway-frame-flow.service")
|
run("systemctl", "is-active", "pigway-frame-flow.service")
|
||||||
except BaseException:
|
except BaseException:
|
||||||
|
print("Release verification failed; restoring previous Compose", flush=True)
|
||||||
if changed:
|
if changed:
|
||||||
shutil.copy2(backup / "compose.before.json", APP / "compose.json")
|
shutil.copy2(backup / "compose.before.json", APP / "compose.json")
|
||||||
run("systemctl", "restart", "pigway-frame-flow.service")
|
run("systemctl", "restart", "pigway-frame-flow.service")
|
||||||
@@ -236,6 +244,9 @@ def release(lock):
|
|||||||
owner = ctx.stat()
|
owner = ctx.stat()
|
||||||
os.chown(output, owner.st_uid, owner.st_gid)
|
os.chown(output, owner.st_uid, owner.st_gid)
|
||||||
shutil.copy2(output, backup / "release-verification.json")
|
shutil.copy2(output, backup / "release-verification.json")
|
||||||
|
public_receipt = ctx.parent / "frame-release-verification.json"
|
||||||
|
shutil.copy2(output, public_receipt)
|
||||||
|
os.chown(public_receipt, owner.st_uid, owner.st_gid)
|
||||||
shutil.rmtree(ctx)
|
shutil.rmtree(ctx)
|
||||||
print(json.dumps(receipt, indent=2))
|
print(json.dumps(receipt, indent=2))
|
||||||
|
|
||||||
|
|||||||
@@ -53,3 +53,21 @@ def test_release_rejects_unsafe_runtime(release_tool, monkeypatch, unsafe):
|
|||||||
monkeypatch.setattr(release_tool, "inspect", lambda: container)
|
monkeypatch.setattr(release_tool, "inspect", lambda: container)
|
||||||
with pytest.raises(AssertionError):
|
with pytest.raises(AssertionError):
|
||||||
release_tool.verify_runtime("test")
|
release_tool.verify_runtime("test")
|
||||||
|
|
||||||
|
|
||||||
|
def test_release_readiness_retries_on_actual_listener(release_tool, monkeypatch):
|
||||||
|
import io
|
||||||
|
import urllib.error
|
||||||
|
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
def listener(url, timeout):
|
||||||
|
calls.append(url)
|
||||||
|
if url != "http://192.0.2.10:81/ready" or len(calls) == 1:
|
||||||
|
raise urllib.error.URLError("Connection refused during restart")
|
||||||
|
return io.BytesIO(b'{"status":"ready"}')
|
||||||
|
|
||||||
|
monkeypatch.setattr(release_tool.urllib.request, "urlopen", listener)
|
||||||
|
monkeypatch.setattr(release_tool.time, "sleep", lambda _: None)
|
||||||
|
release_tool.wait_ready()
|
||||||
|
assert len(calls) == 2
|
||||||
|
|||||||
Reference in New Issue
Block a user