Skip to content

Commit

Permalink
Added support for waiting for the ACME initialization to complete
Browse files Browse the repository at this point in the history
  • Loading branch information
drivera-armedia committed Jun 27, 2024
1 parent 94ac7a3 commit a75d864
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 0 deletions.
2 changes: 2 additions & 0 deletions acme-init
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,8 @@ else
err "Can't find the provisioner password file at [${ACME_PASSWORD_FILE}], did not generate any new certificates or keystores"
fi

timestamp > "${SSL_DIR}/.acme-ready"

say "👉 Updating the trusted certificates"
chown -R root:root "${ANCHORS}"
chmod -R 0440 "${ANCHORS}"
Expand Down
141 changes: 141 additions & 0 deletions acme-wait-init
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#!/bin/bash

set -euo pipefail

[ -v ACME_WAIT_TIMEOUT ] || ACME_WAIT_TIMEOUT=""
[ -n "${ACME_WAIT_TIMEOUT}" ] || ACME_WAIT_TIMEOUT="20m"

timestamp()
{
date -Ins -u
}

say()
{
echo -e "$(timestamp): ${@}"
}

doing()
{
say "👉 ${@}"
}

ok()
{
say "${@}"
}

warn()
{
say "⚠️ ${@}"
}

err()
{
say "${@}"
}

fail()
{
err "${@}"
exit ${EXIT_CODE:-1}
}

#
# This function converts numbers of seconds into
# K8s timespecs, but leaves timespec strings alone
#
secs_to_timestr()
{
local STR="${1}"
local NUM="(0|[1-9][0-9]*)"

[ -n "${STR}" ] || return 1

# If it's already a time string, return it
if [[ "${STR^^}" =~ ^(${NUM}D)?(${NUM}H)?(${NUM}M)?(${NUM}S)?$ ]] ; then
echo -n "${STR,,}"
return 0
fi

[[ "${STR}" =~ ^${NUM}$ ]] || return 1

local RET=""
local SIZE=0
local MUL=0
local SECS=${STR}
for C in D H M S ; do
MUL=$(get_time_mul "${C}")
(( SIZE = ( SECS / MUL ) ))
[ ${SIZE} -gt 0 ] && RET+="${SIZE}${C}"
(( SECS -= ( SIZE * MUL ) ))
done

echo -n ${RET,,}
return 0
}

#
# This function converts K8s timespecs into
# numbers of seconds, but leaves numbers alone
#
timestr_to_secs()
{
local STR="${1}"
local NUM="(0|[1-9][0-9]*)"

# If it's a straight-up number,
# seconds already, so just return it
if [[ "${STR}" =~ ^${NUM}$ ]] ; then
echo -e "${STR}"
return 0
fi

# It could be a time string, so parse it out
[ -n "${STR}" ] || return 1
[[ "${STR^^}" =~ ^(${NUM}D)?(${NUM}H)?(${NUM}M)?(${NUM}S)?$ ]] || return 1

local PARTS=( "${BASH_REMATCH[@]:1}" )
[ ${#PARTS[@]} -ge 1 ] || return 1

local SIZE=0
local MUL=0
local SECS=0
for (( i = 0 ; i < ${#PARTS[@]} ; i++ )) ; do
[[ "${PARTS[i]}" =~ ^${NUM}([DHMS])$ ]] || continue
SIZE=${BASH_REMATCH[1]}
MUL=$(get_time_mul "${BASH_REMATCH[2]}")
(( SECS += SIZE * MUL ))
done

echo -n ${SECS}
return 0
}

marker_exists()
{
local MARKER="${1}"
[ -e "${MARKER}" ] || return 1
[ -f "${MARKER}" ] || return 1
[ -s "${MARKER}" ] || return 1
return 0
}

[ -v SSL_DIR ] || SSL_DIR=""
[ -n "${SSL_DIR}" ] || SSL_DIR="/.ssl"

INIT_MARKER="${SSL_DIR}/.acme-ready"

ACME_WAIT_TIMEOUT_STR="$(secs_to_timestr "${ACME_WAIT_TIMEOUT}")"
START="$(date +%s)"
# Wait for all workload pods to disappear...
FIRST="true"
while ! marker_exists "${INIT_MARKER}" ; do
"${FIRST}" && say "⌛ Waiting for the ACME certificates to be initialized (up to ${ACME_WAIT_TIMEOUT_STR} total)..."
FIRST="false"

# Poke every 100ms (10 times per second)
sleep 0.1 || fail "Sleep interrupted"
done
say "✅ ACME client is initialized is ready"
exit 0

0 comments on commit a75d864

Please sign in to comment.