11TOPDIR =$(PWD )
22GH_ORG_LC =robertkielty
33REGISTRY ?= ghcr.io
4- IMAGE ?= $(REGISTRY ) /$(GH_ORG_LC ) /maintainerd:latest
5- SYNC_IMAGE ?= $(REGISTRY ) /$(GH_ORG_LC ) /maintainerd-sync:latest
4+ GIT_SHA ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
5+ BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr '/_' '--')
6+ BUILD_DATE ?= $(shell date -u '+% a-% b-% d-% Y' | tr '[:lower:]' '[:upper:]')
7+ TAG ?= $(BRANCH ) -$(GIT_SHA ) -$(BUILD_DATE )
8+ IMAGE ?= $(REGISTRY ) /$(GH_ORG_LC ) /maintainerd:$(TAG )
9+ IMAGE_LATEST ?= $(REGISTRY ) /$(GH_ORG_LC ) /maintainerd:latest
10+ SYNC_IMAGE ?= $(REGISTRY ) /$(GH_ORG_LC ) /maintainerd-sync:$(TAG )
11+ SYNC_IMAGE_LATEST ?= $(REGISTRY ) /$(GH_ORG_LC ) /maintainerd-sync:latest
612WHOAMI =$(shell whoami)
713
814# Helpful context string for logs
@@ -35,18 +41,18 @@ GHCR_TOKEN ?= $(GITHUB_GHCR_TOKEN)
3541
3642
3743# ---- Image ----
38- .PHONY : image-build
39- image-build :
44+ .PHONY : mntrd- image-build
45+ mntrd- image-build :
4046 @echo " Building container image: $( IMAGE) "
41- @docker buildx build -t $(IMAGE ) -f Dockerfile .
47+ @docker buildx build -t $(IMAGE ) -f Dockerfile --target maintainerd .
4248
4349.PHONY : sync-image-build
4450sync-image-build :
4551 @echo " Building sync image: $( SYNC_IMAGE) "
46- @docker buildx build -t $(SYNC_IMAGE ) -f deploy/sync/ Dockerfile .
52+ @docker buildx build -t $(SYNC_IMAGE ) -f Dockerfile --target sync .
4753
48- .PHONY : image-push
49- image-push : image-build
54+ .PHONY : mntrd- image-push
55+ mntrd- image-push : mntrd- image-build
5056 @echo " Ensuring docker is logged in to $( REGISTRY) (uses GHCR_TOKEN if set)"
5157 @if [ -n " $( GHCR_TOKEN) " ]; then \
5258 echo " Logging into $( REGISTRY) as $( GHCR_USER) using token from GHCR_TOKEN" ; \
@@ -56,9 +62,12 @@ image-push: image-build
5662 fi
5763 @echo " Pushing image: $( IMAGE) "
5864 @docker push $(IMAGE )
65+ @echo " Tagging and pushing latest: $( IMAGE_LATEST) "
66+ @docker tag $(IMAGE ) $(IMAGE_LATEST )
67+ @docker push $(IMAGE_LATEST )
5968
60- .PHONY : image-deploy
61- image-deploy : image-push
69+ .PHONY : mntrd- image-deploy
70+ mntrd- image-deploy : mntrd- image-push
6271 @echo " Image pushed. Attempting rollout on context $( CTX_STR) ."
6372 @CTX_FLAG=" $( if $( KUBECONTEXT) ,--context $( KUBECONTEXT) ) " ; \
6473 if kubectl $$ CTX_FLAG config current-context > /dev/null 2>&1 ; then \
@@ -83,6 +92,9 @@ sync-image-push: sync-image-build
8392 fi
8493 @echo " Pushing image: $( SYNC_IMAGE) "
8594 @docker push $(SYNC_IMAGE )
95+ @echo " Tagging and pushing latest: $( SYNC_IMAGE_LATEST) "
96+ @docker tag $(SYNC_IMAGE ) $(SYNC_IMAGE_LATEST )
97+ @docker push $(SYNC_IMAGE_LATEST )
8698
8799.PHONY : sync-image-deploy
88100sync-image-deploy : sync-image-push
@@ -93,7 +105,7 @@ sync-image-deploy: sync-image-push
93105 fi ; \
94106 if ! kubectl -n $( NAMESPACE) $$ CTX_FLAG get cronjob/maintainer-sync > /dev/null 2>&1 ; then \
95107 echo " CronJob/maintainer-sync not found in namespace $( NAMESPACE) ." ; \
96- echo " Hint: apply deploy/manifests/sync.yaml or run 'make sync-apply' (or 'make manifests-apply')." ; \
108+ echo " Hint: apply deploy/manifests/cronjob.yaml + deploy/manifests/ sync-rbac .yaml or run 'make sync-apply' (or 'make manifests-apply')." ; \
97109 exit 1; \
98110 fi ; \
99111 kubectl -n $(NAMESPACE ) $$ CTX_FLAG set image cronjob/maintainer-sync ' *=$(SYNC_IMAGE)' ; \
@@ -103,14 +115,50 @@ sync-image-deploy: sync-image-push
103115.PHONY : sync-apply
104116sync-apply :
105117 @echo " Applying sync resources in namespace $( NAMESPACE) [ctx=$( CTX_STR) ]"
106- @kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) apply -f deploy/manifests/sync.yaml
107-
108- .PHONY : image
109- image : image-build
118+ @kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) apply -f deploy/manifests/cronjob.yaml -f deploy/manifests/sync-rbac.yaml
119+
120+ .PHONY : sync-run
121+ sync-run :
122+ @bash -c ' set -euo pipefail; \
123+ job=" maintainer-sync-manual-$$ (date +%s)" ; \
124+ echo " Creating sync job $$ job in namespace $( NAMESPACE) [ctx=$( CTX_STR) ]" ; \
125+ kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) create job --from=cronjob/maintainer-sync $$ job; \
126+ '
127+
128+ .PHONY : migrate-schema
129+ migrate-schema :
130+ @echo " Running schema migration job in namespace $( NAMESPACE) [ctx=$( CTX_STR) ]"
131+ @kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) apply -f deploy/manifests/maintainerd-migrate-schema-job.yaml
132+
133+ .PHONY : migrate-schema-safe
134+ migrate-schema-safe :
135+ @bash -c ' set -euo pipefail; \
136+ echo " Scaling Deployment/maintainerd to 0 for schema migration [ctx=$( CTX_STR) ]" ; \
137+ kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) scale deploy/maintainerd --replicas=0; \
138+ echo " Resolving PVC attachment node for maintainerd-db [ctx=$( CTX_STR) ]" ; \
139+ pv=" $$ (kubectl -n $( NAMESPACE) $( if $( KUBECONTEXT) ,--context $( KUBECONTEXT) ) get pvc maintainerd-db -o jsonpath=" {.spec.volumeName}" )" ; \
140+ node=" $$ (kubectl get volumeattachment -o jsonpath=" {range .items[? (@.spec.source.persistentVolumeName==\" $$ {pv}\" )]}{.spec.nodeName}{end}" )" ; \
141+ kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) delete job maintainerd-migrate --ignore-not-found; \
142+ if [ -n " $$ {node}" ]; then \
143+ echo " Running schema migration job pinned to node $$ {node} [ctx=$( CTX_STR) ]" ; \
144+ kubectl create -f deploy/manifests/maintainerd-migrate-schema-job.yaml --dry-run=client -o json | \
145+ kubectl patch --local -f - -p " {\" spec\" :{\" template\" :{\" spec\" :{\" nodeName\" :\" $$ {node}\" }}}}" -o json | \
146+ kubectl apply -f -; \
147+ else \
148+ echo " No attachment node found; running migration job without pinning [ctx=$( CTX_STR) ]" ; \
149+ kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) apply -f deploy/manifests/maintainerd-migrate-schema-job.yaml; \
150+ fi ; \
151+ kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) wait --for=condition=complete job/maintainerd-migrate --timeout=300s; \
152+ echo " Scaling Deployment/maintainerd back to 1 [ctx=$( CTX_STR) ]" ; \
153+ kubectl -n $(NAMESPACE ) $(if $(KUBECONTEXT ) ,--context $(KUBECONTEXT ) ) scale deploy/maintainerd --replicas=1; \
154+ '
155+
156+ .PHONY : mntrd-image
157+ mntrd-image : mntrd-image-build
110158 @true
111159
112- .PHONY : image-run
113- image-run : image
160+ .PHONY : mntrd- image-run
161+ mntrd- image-run : mntrd- image
114162 @docker run -ti --rm $(IMAGE )
115163
116164# ---- Config ----
@@ -146,15 +194,20 @@ help:
146194 @echo " make lint -> run linters (requires golangci-lint)"
147195 @echo " "
148196 @echo " == Deployment =="
197+ @echo " Image tags: <branch>-<shortsha>-<DAY-MON-DD-YYYY> (UTC), plus latest"
149198 @echo " make secrets -> build $( ENVOUT) from $( ENVSRC) and apply both Secrets"
150199 @echo " make env -> build $( ENVOUT) from $( ENVSRC) "
151200 @echo " make apply-env -> create/update $( ENV_SECRET_NAME) from $( ENVOUT) "
152201 @echo " make apply-creds -> create/update $( CREDS_SECRET_NAME) from $( CREDS_FILE) "
153202 @echo " make clean-env -> remove $( ENVOUT) "
154203 @echo " make print -> show which keys would be loaded (without values)"
155- @echo " make image-build -> build container image $( IMAGE) locally"
156- @echo " make image-push -> build and push $( IMAGE) (uses GHCR_TOKEN/GITHUB_GHCR_TOKEN + GHCR_USER/DOCKER_REGISTRY_USERNAME for ghcr login)"
157- @echo " make image-deploy -> build, push, and restart Deployment in $( NAMESPACE) "
204+ @echo " make mntrd-image-build -> build maintainerd image $( IMAGE) locally"
205+ @echo " make mntrd-image-push -> build and push $( IMAGE) (uses GHCR_TOKEN/GITHUB_GHCR_TOKEN + GHCR_USER/DOCKER_REGISTRY_USERNAME for ghcr login)"
206+ @echo " make mntrd-image-deploy -> build, push, and restart Deployment in $( NAMESPACE) "
207+ @echo " make sync-apply -> apply CronJob + RBAC for the sync job"
208+ @echo " make sync-run -> trigger a manual sync job and tail logs"
209+ @echo " make migrate-schema -> run one-off schema migration job"
210+ @echo " make migrate-schema-safe -> scale down, run migration pinned to attached node, scale back up"
158211 @echo " make ensure-ns -> ensure namespace $( NAMESPACE) exists"
159212 @echo " make apply-ghcr-secret -> create/update docker-registry Secret 'ghcr-secret'"
160213 @echo " make manifests-apply -> kubectl apply -f deploy/manifests (prod-only)"
0 commit comments