refactor progress
This commit is contained in:
149
scripts/ci/workflows/deploy_relay.py
Executable file
149
scripts/ci/workflows/deploy_relay.py
Executable file
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
|
||||
|
||||
from ci_steps import ADD_KNOWN_HOSTS_SCRIPT, record_deploy_commit_script
|
||||
from ci_workflow import parse_step_env_args
|
||||
from ci_utils import run_step
|
||||
|
||||
|
||||
STEPS: dict[str, str] = {
|
||||
"compile": """
|
||||
set -euo pipefail
|
||||
cd fluxer_relay
|
||||
rebar3 as prod compile
|
||||
""",
|
||||
"add_known_hosts": ADD_KNOWN_HOSTS_SCRIPT,
|
||||
"record_deploy_commit": record_deploy_commit_script(
|
||||
include_env=False,
|
||||
include_sentry=False,
|
||||
),
|
||||
"deploy": """
|
||||
set -euo pipefail
|
||||
|
||||
CONTAINER_ID="$(ssh "${SERVER}" "docker ps -q --filter label=com.docker.swarm.service.name=fluxer_relay_app | head -1")"
|
||||
if [ -z "${CONTAINER_ID}" ]; then
|
||||
echo "::error::No running container found for service fluxer_relay_app"
|
||||
ssh "${SERVER}" "docker ps --filter 'name=fluxer_relay_app' --format '{{.ID}} {{.Names}} {{.Status}}'" || true
|
||||
exit 1
|
||||
fi
|
||||
echo "Container: ${CONTAINER_ID}"
|
||||
|
||||
LOCAL_MD5_LINES="$(
|
||||
erl -noshell -eval '
|
||||
Files = filelib:wildcard("fluxer_relay/_build/prod/lib/fluxer_relay/ebin/*.beam"),
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
{ok, {M, Md5}} = beam_lib:md5(F),
|
||||
Hex = binary:encode_hex(Md5, lowercase),
|
||||
io:format("~s ~s ~s~n", [atom_to_list(M), binary_to_list(Hex), F])
|
||||
end,
|
||||
Files
|
||||
),
|
||||
halt().'
|
||||
)"
|
||||
|
||||
REMOTE_MD5_LINES="$(
|
||||
ssh "${SERVER}" "docker exec ${CONTAINER_ID} /opt/fluxer_relay/bin/fluxer_relay eval '
|
||||
Mods = hot_reload:get_loaded_modules(),
|
||||
lists:foreach(
|
||||
fun(M) ->
|
||||
case hot_reload:get_module_info(M) of
|
||||
{ok, Info} ->
|
||||
V = maps:get(loaded_md5, Info),
|
||||
S = case V of
|
||||
null -> \"null\";
|
||||
B when is_binary(B) -> binary_to_list(B)
|
||||
end,
|
||||
io:format(\"~s ~s~n\", [atom_to_list(M), S]);
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end,
|
||||
Mods
|
||||
),
|
||||
ok.
|
||||
' " | tr -d '\r'
|
||||
)"
|
||||
|
||||
LOCAL_MD5_FILE="$(mktemp)"
|
||||
REMOTE_MD5_FILE="$(mktemp)"
|
||||
CHANGED_FILE_LIST="$(mktemp)"
|
||||
CHANGED_MAIN_LIST="$(mktemp)"
|
||||
CHANGED_SELF_LIST="$(mktemp)"
|
||||
RELOAD_RESULT_MAIN="$(mktemp)"
|
||||
RELOAD_RESULT_SELF="$(mktemp)"
|
||||
trap 'rm -f "${LOCAL_MD5_FILE}" "${REMOTE_MD5_FILE}" "${CHANGED_FILE_LIST}" "${CHANGED_MAIN_LIST}" "${CHANGED_SELF_LIST}" "${RELOAD_RESULT_MAIN}" "${RELOAD_RESULT_SELF}"' EXIT
|
||||
|
||||
printf '%s' "${LOCAL_MD5_LINES}" > "${LOCAL_MD5_FILE}"
|
||||
printf '%s' "${REMOTE_MD5_LINES}" > "${REMOTE_MD5_FILE}"
|
||||
|
||||
python3 scripts/ci/erlang_hot_reload.py diff-md5 \
|
||||
"${LOCAL_MD5_FILE}" \
|
||||
"${REMOTE_MD5_FILE}" \
|
||||
"${CHANGED_FILE_LIST}"
|
||||
|
||||
mapfile -t CHANGED_FILES < "${CHANGED_FILE_LIST}"
|
||||
|
||||
if [ "${#CHANGED_FILES[@]}" -eq 0 ]; then
|
||||
echo "No BEAM changes detected, nothing to hot-reload."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Changed modules count: ${#CHANGED_FILES[@]}"
|
||||
|
||||
while IFS= read -r p; do
|
||||
[ -n "${p}" ] || continue
|
||||
m="$(basename "${p}")"
|
||||
m="${m%.beam}"
|
||||
if [ "${m}" = "hot_reload" ] || [ "${m}" = "hot_reload_handler" ]; then
|
||||
printf '%s\n' "${p}" >> "${CHANGED_SELF_LIST}"
|
||||
else
|
||||
printf '%s\n' "${p}" >> "${CHANGED_MAIN_LIST}"
|
||||
fi
|
||||
done < "${CHANGED_FILE_LIST}"
|
||||
|
||||
build_json() {
|
||||
python3 scripts/ci/erlang_hot_reload.py build-json "$1"
|
||||
}
|
||||
|
||||
strict_verify() {
|
||||
python3 scripts/ci/erlang_hot_reload.py verify --mode strict
|
||||
}
|
||||
|
||||
self_verify() {
|
||||
python3 scripts/ci/erlang_hot_reload.py verify --mode self
|
||||
}
|
||||
|
||||
if [ -s "${CHANGED_SELF_LIST}" ]; then
|
||||
if ! build_json "${CHANGED_SELF_LIST}" | ssh "${SERVER}" "docker exec -i ${CONTAINER_ID} curl -sS -X POST -H 'Authorization: Bearer ${RELAY_ADMIN_SECRET}' -H 'Content-Type: application/json' --data @- http://localhost:8081/_admin/reload" | tee "${RELOAD_RESULT_SELF}" | self_verify; then
|
||||
echo "::group::Hot reload response (self)"
|
||||
cat "${RELOAD_RESULT_SELF}" || true
|
||||
echo "::endgroup::"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -s "${CHANGED_MAIN_LIST}" ]; then
|
||||
if ! build_json "${CHANGED_MAIN_LIST}" | ssh "${SERVER}" "docker exec -i ${CONTAINER_ID} curl -sS -X POST -H 'Authorization: Bearer ${RELAY_ADMIN_SECRET}' -H 'Content-Type: application/json' --data @- http://localhost:8081/_admin/reload" | tee "${RELOAD_RESULT_MAIN}" | strict_verify; then
|
||||
echo "::group::Hot reload response (main)"
|
||||
cat "${RELOAD_RESULT_MAIN}" || true
|
||||
echo "::endgroup::"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
""",
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
args = parse_step_env_args(include_server_ip=True)
|
||||
run_step(STEPS, args.step)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user