Skip to content

Commit 8728f6c

Browse files
YuryHrytsukmrnicegyu11
authored andcommitted
Introduce rolling docker config / secret update concept 🎉 🚀 (ITISFoundation#952)
* fixes * update comment
1 parent 51e23c4 commit 8728f6c

File tree

6 files changed

+69
-10
lines changed

6 files changed

+69
-10
lines changed

scripts/common.Makefile

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,39 @@ clean-default: .check_clean ## Cleans all outputs
207207
export DEPLOYMENT_API_DOMAIN_TESTING_CAPTURE_TRAEFIK_RULE='${DEPLOYMENT_API_DOMAIN_TESTING_CAPTURE_TRAEFIK_RULE}'; \
208208
export DEPLOYMENT_FQDNS_CAPTURE_INVITATIONS='${DEPLOYMENT_FQDNS_CAPTURE_INVITATIONS}'; \
209209
export DOLLAR='$$'; \
210+
$(if $(STACK_NAME),export STACK_NAME='$(STACK_NAME)';) \
210211
set +o allexport; \
211212
envsubst < $< > .env
212213
214+
ifdef STACK_NAME
215+
216+
.PHONY: prune-docker-stack-configs-default
217+
prune-docker-stack-configs-default: ## Clean all unused stack configs
218+
@# Since the introduction of rolling docker config updates old
219+
@# [docker config] versions are kept. This target removes them
220+
@# https://github.com/docker/cli/issues/203
221+
@#
222+
@# This should be run before stack update in order to
223+
@# keep previous config version for potential rollback
224+
@#
225+
@# This will not clean "external" configs. To achieve this extend
226+
@# this target in related Makefiles.
227+
@#
228+
@# Long live Kubernetes ConfigMaps!
229+
230+
@for id in $$(docker config ls --filter "label=com.docker.stack.namespace=${STACK_NAME}" --format '{{.ID}}'); do \
231+
docker config rm "$$id" >/dev/null 2>&1 || true; \
232+
done
233+
234+
.PHONY: prune-docker-stack-secrets-default
235+
prune-docker-stack-secrets-default: ## Clean all unused stack secrets
236+
@# Same as for configs
237+
238+
@for id in $$(docker secret ls --filter "label=com.docker.stack.namespace=${STACK_NAME}" --format '{{.ID}}'); do \
239+
docker secret rm "$$id" >/dev/null 2>&1 || true; \
240+
done
241+
242+
endif
213243
214244
# Helpers -------------------------------------------------
215245
.PHONY: .init
@@ -253,13 +283,16 @@ venv: $(REPO_BASE_DIR)/.venv/bin/activate ## Creates a python virtual environmen
253283
ifeq ($(shell test -f j2cli_customization.py && echo -n yes),yes)
254284
255285
define jinja
256-
$(REPO_BASE_DIR)/.venv/bin/j2 --format=env $(1) $(2) -o $(3) --customize j2cli_customization.py
286+
$(REPO_BASE_DIR)/.venv/bin/j2 --format=env $(1) $(2) -o $(3) \
287+
--filters $(REPO_BASE_DIR)/scripts/j2cli_global_filters.py \
288+
--customize j2cli_customization.py
257289
endef
258290
259291
else
260292
261293
define jinja
262-
$(REPO_BASE_DIR)/.venv/bin/j2 --format=env $(1) $(2) -o $(3)
294+
$(REPO_BASE_DIR)/.venv/bin/j2 --format=env $(1) $(2) -o $(3) \
295+
--filters $(REPO_BASE_DIR)/scripts/j2cli_global_filters.py
263296
endef
264297
265298
endif

scripts/j2cli_global_filters.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
def sha256file(filepath):
2+
import hashlib
3+
4+
_hash = hashlib.sha256()
5+
6+
# https://stackoverflow.com/a/22058673/12124525
7+
with open(filepath, "rb") as f:
8+
while True:
9+
data = f.read(65536)
10+
if not data:
11+
break
12+
13+
_hash.update(data)
14+
15+
return _hash.hexdigest()
16+
17+
18+
def substring(value, start, end):
19+
return value[start:end]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
!docker-compose.yml
1+
docker-compose.yml
22
*.secret
Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,37 @@
11
.DEFAULT_GOAL := help
22

3-
4-
53
# Internal VARIABLES ------------------------------------------------
64
# STACK_NAME defaults to name of the current directory. Should not to be changed if you follow GitOps operating procedures.
75
STACK_NAME = $(notdir $(shell pwd))
86
TEMP_COMPOSE=.stack.${STACK_NAME}.yaml
97
REPO_BASE_DIR := $(shell git rev-parse --show-toplevel)
108

9+
DOCKER_STACK_DEPLOY_COMMON_DEPENDENCIES = .api_env.secret \
10+
prune-docker-stack-configs \
11+
prune-docker-stack-secrets
12+
1113
# TARGETS --------------------------------------------------
1214
include ${REPO_BASE_DIR}/scripts/common.Makefile
1315

1416
.PHONY: up-aws ## Deploys stack on aws
15-
up-aws: .init .env ${TEMP_COMPOSE}-aws .api_env.secret
17+
up-aws: .init .env ${TEMP_COMPOSE}-aws ${DOCKER_STACK_DEPLOY_COMMON_DEPENDENCIES}
1618
@docker stack deploy --with-registry-auth --prune --compose-file ${TEMP_COMPOSE}-aws ${STACK_NAME}
1719

1820
.PHONY: up-master ## Deploys stack on master
19-
up-master: .init .env ${TEMP_COMPOSE}-master .api_env.secret
21+
up-master: .init .env ${TEMP_COMPOSE}-master ${DOCKER_STACK_DEPLOY_COMMON_DEPENDENCIES}
2022
@docker stack deploy --with-registry-auth --prune --compose-file ${TEMP_COMPOSE}-master ${STACK_NAME}
2123

2224
.PHONY: up-local ## Deploys stack on local
23-
up-local: .init .env ${TEMP_COMPOSE}-local .api_env.secret
25+
up-local: .init .env ${TEMP_COMPOSE}-local ${DOCKER_STACK_DEPLOY_COMMON_DEPENDENCIES}
2426
@docker stack deploy --with-registry-auth --prune --compose-file ${TEMP_COMPOSE}-local ${STACK_NAME}
2527

2628
# Helpers -------------------------------------------------
2729

30+
docker-compose.yml: .env .api_env.secret
31+
@$(call jinja, docker-compose.yml.j2, .env, docker-compose.yml.unlinted) && \
32+
$(_yq) docker-compose.yml.unlinted > docker-compose.yml; \
33+
rm docker-compose.yml.unlinted >/dev/null 2>&1;
34+
2835
.PHONY: ${TEMP_COMPOSE}-aws
2936
${TEMP_COMPOSE}-aws: docker-compose.yml docker-compose.aws.yml
3037
@${REPO_BASE_DIR}/scripts/docker-stack-config.bash -e .env $< docker-compose.aws.yml > $@
@@ -37,6 +44,5 @@ ${TEMP_COMPOSE}-master: docker-compose.yml docker-compose.master.yml
3744
${TEMP_COMPOSE}-local: docker-compose.yml docker-compose.local.yml
3845
@${REPO_BASE_DIR}/scripts/docker-stack-config.bash -e .env $< docker-compose.local.yml > $@
3946

40-
4147
.api_env.secret: .env template.api_env ## resolves '.api_env.secret' using '.env'
4248
@set -o allexport; source $<; set +o allexport; envsubst < $(word 2,$^) > $@

services/appmotion_gateway/docker-compose.yml renamed to services/appmotion_gateway/docker-compose.yml.j2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ configs:
103103
# SEE https://docs.docker.com/compose/compose-file/05-services/#configs
104104
api_env_config:
105105
file: ./.api_env.secret
106+
name: ${STACK_NAME}_api_env_config_{{ "./.api_env.secret" | sha256file | substring(0,10) }} # rolling update on content change
106107

107108
volumes:
108109
# SEE https://docs.docker.com/compose/compose-file/07-volumes/

services/appmotion_gateway/template.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ DEPLOYMENT_FQDNS_APPMOTION_CAPTURE_TRAEFIK_RULE='${DEPLOYMENT_FQDNS_APPMOTION_CA
2020
APPMOTION_NETWORK=${APPMOTION_NETWORK}
2121
MONITORING_DOMAIN=${MONITORING_DOMAIN}
2222
PUBLIC_NETWORK=${PUBLIC_NETWORK}
23-
SWARM_STACK_NAME=${SWARM_STACK_NAME}
23+
STACK_NAME=${STACK_NAME}
2424
MACHINE_FQDN=${MACHINE_FQDN}

0 commit comments

Comments
 (0)