Skip to content

Commit 267010f

Browse files
writes version to db, wait for migration
1 parent 00f22bd commit 267010f

File tree

5 files changed

+99
-15
lines changed

5 files changed

+99
-15
lines changed

start.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
create_jwks_secret_if_not_existing,
77
check_and_pull_exec_env_images,
88
wait_until_refinery_is_ready,
9+
wait_until_postgres_migration_is_exited,
10+
)
11+
from util.postgres_helper import (
12+
create_database_dump,
13+
update_db_versions,
14+
wait_until_postgres_is_ready,
915
)
10-
from util.postgres_helper import create_database_dump, wait_until_postgres_is_ready
1116
from util.template_processor import process_docker_compose_template
1217
from util.update_helper import (
1318
is_any_service_version_changed,
@@ -47,6 +52,8 @@
4752
print("Starting all containers...", flush=True)
4853
subprocess.call(["docker-compose", "-f", DOCKER_COMPOSE, "up", "-d"])
4954

55+
wait_until_postgres_migration_is_exited()
56+
5057
wait_until_db_and_updater_service_are_ready()
5158
if run_updates:
5259
print("Service versions have changed.", flush=True)
@@ -64,6 +71,9 @@
6471
else:
6572
print("Refinery is not ready!", flush=True)
6673

74+
# write current versions to db
75+
update_db_versions()
76+
6777
print("UI: http://localhost:4455/app/")
6878
print(f"Minio: {minio_endpoint}")
6979
print("MailHog: http://localhost:4436/")

util/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
}
1111
JWKS_PATH = "/refinery/oathkeeper/jwks.json"
1212
PG_CONTAINER = "graphql-postgres"
13+
POSTGRES_MIGRATE_CONTAINER = "postgres-migrate"
1314
SERVICE_VERSIONS = "/refinery/versions.json"
1415
SETTINGS = "/refinery/settings.json"

util/docker_helper.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
import time
66
from typing import Any, Tuple
77

8-
from util.constants import EXEC_ENVS, SERVICE_VERSIONS, JWKS_PATH
8+
from util.constants import (
9+
EXEC_ENVS,
10+
SERVICE_VERSIONS,
11+
JWKS_PATH,
12+
POSTGRES_MIGRATE_CONTAINER,
13+
)
914

1015
client = docker.from_env()
1116

@@ -80,7 +85,7 @@ def is_uvicorn_application_started(container_name: str) -> bool:
8085
try:
8186
container = client.containers.list(filters={"name": container_name})[0]
8287
return "Application startup complete." in container.logs().decode("utf-8")
83-
except docker.errors.ImageNotFound:
88+
except IndexError:
8489
return False
8590

8691

@@ -90,11 +95,27 @@ def is_ui_service_ready(container_name: str) -> bool:
9095
return "Configuration complete; ready for start up" in container.logs().decode(
9196
"utf-8"
9297
)
93-
except docker.errors.ImageNotFound:
98+
except IndexError:
9499
return False
95100

96101

97-
def wait_until_refinery_is_ready(timeout: int = 60) -> None:
102+
def wait_until_postgres_migration_is_exited(timeout: int = 600) -> bool:
103+
start_time = time.time()
104+
105+
while start_time + timeout > time.time():
106+
try:
107+
container = client.containers.list(
108+
filters={"name": POSTGRES_MIGRATE_CONTAINER}
109+
)[0]
110+
if container.status == "exited":
111+
return True
112+
except Exception:
113+
return False
114+
time.sleep(1)
115+
return False
116+
117+
118+
def wait_until_refinery_is_ready(timeout: int = 60) -> bool:
98119
start_time = time.time()
99120

100121
while start_time + timeout > time.time():

util/postgres_helper.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
import json
12
import os
23
import time
34
from datetime import datetime
4-
from util.constants import BACKUP_DIR, CONNECTION_STRING, PG_CONTAINER
5+
from typing import Dict
6+
from zipfile import ZipFile
7+
from util.constants import BACKUP_DIR, CONNECTION_STRING, PG_CONTAINER, SERVICE_VERSIONS
58
from util.docker_helper import exec_command_on_container
69

710

8-
def create_database_dump():
11+
def create_database_dump() -> bool:
912
exit_code, result = exec_command_on_container(
1013
PG_CONTAINER, f"pg_dump -d {CONNECTION_STRING}"
1114
)
@@ -14,22 +17,23 @@ def create_database_dump():
1417

1518
now = datetime.now()
1619
timestamp = now.strftime("%m_%d_%Y_%H_%M_%S")
17-
backup_path = os.path.join(BACKUP_DIR, f"db_dump_{timestamp}.sql")
20+
backup_zip = os.path.join(BACKUP_DIR, f"db_dump_{timestamp}.zip")
21+
backup_fname = os.path.join(BACKUP_DIR, f"db_dump_{timestamp}.sql")
1822

1923
if not os.path.exists(BACKUP_DIR):
2024
os.makedirs(BACKUP_DIR)
2125

22-
with open(backup_path, "wb") as f:
23-
f.write(result)
26+
with ZipFile(backup_zip, "w") as zf:
27+
zf.writestr(backup_fname, result)
2428

2529
return True
2630

2731

28-
def get_psql_command(sql: str):
32+
def get_psql_command(sql: str) -> str:
2933
return f'psql -d {CONNECTION_STRING} -c "{sql}" -qtAX'
3034

3135

32-
def wait_until_postgres_is_ready(timeout: int = 300):
36+
def wait_until_postgres_is_ready(timeout: int = 300) -> bool:
3337
start_time = time.time()
3438

3539
while start_time + timeout > time.time():
@@ -40,7 +44,7 @@ def wait_until_postgres_is_ready(timeout: int = 300):
4044
return False
4145

4246

43-
def get_db_versions():
47+
def get_db_versions() -> Dict[str, str]:
4448
exit_code, result = exec_command_on_container(
4549
PG_CONTAINER,
4650
get_psql_command("SELECT service, installed_version FROM app_version"),
@@ -52,3 +56,47 @@ def get_db_versions():
5256
service, installed_version = line.split("|")
5357
versions[service] = installed_version
5458
return versions
59+
60+
61+
def update_db_versions() -> bool:
62+
63+
with open(SERVICE_VERSIONS, "r") as f:
64+
current_versions = json.load(f)
65+
db_versions = get_db_versions()
66+
67+
# update existing service versions
68+
sql_commands = []
69+
for service, db_version in db_versions.items():
70+
current_version = current_versions[service].lstrip("v")
71+
if current_version != db_version:
72+
sql_commands.append(
73+
f"""
74+
UPDATE app_version
75+
SET installed_version = '{current_version}'
76+
WHERE service = '{service}';
77+
"""
78+
)
79+
if sql_commands:
80+
exit_code, _ = exec_command_on_container(
81+
PG_CONTAINER,
82+
get_psql_command("\n".join(sql_commands)),
83+
)
84+
if exit_code != 0:
85+
return False
86+
87+
# add new service versions
88+
for service, version in current_versions.items():
89+
if service not in db_versions:
90+
sql_commands.append(
91+
f"""
92+
INSERT INTO app_version (service, installed_version)
93+
VALUES ('{service}', '{version.lstrip("v")}');
94+
"""
95+
)
96+
if sql_commands:
97+
exit_code, _ = exec_command_on_container(
98+
PG_CONTAINER, get_psql_command("\n".join(sql_commands))
99+
)
100+
if exit_code != 0:
101+
return False
102+
return True

util/update_helper.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ def is_any_service_version_changed() -> bool:
1414

1515
any_service_updated = False
1616
for service, version in db_versions.items():
17-
if is_newer(version, current_versions[service].lstrip("v")):
18-
print(service, flush=True)
17+
if is_newer(current_versions[service].lstrip("v"), version):
1918
any_service_updated = True
2019
break
2120
return any_service_updated
@@ -40,6 +39,11 @@ def __is_newer_int(v1: List[int], v2: List[int]) -> bool:
4039

4140

4241
def updater_service_update_to_newest():
42+
# the updater service is part of the docker-compose stack and therefore located
43+
# in a differrent network than alfred. Therefore, the updater service can not
44+
# be reached via the alfred network. Therefore, we need to use the docker
45+
# exec command to update the updater service.
46+
# The following command executes the update_to_current command on the updater service.
4347
exit_code, output = exec_command_on_container(
4448
"refinery-updater", "python -c 'import app; app.update_to_newest()'"
4549
)

0 commit comments

Comments
 (0)