diff --git a/Makefile b/Makefile index f96a616..73bff35 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,13 @@ KEYS := \ F4BF5C81EC78A5DD341C91EEDC4B7D1F52E0BA4D EXTRA_ARGS := +GPG_TTY ?= $(shell tty) +PLATFORM ?= linux/amd64 +PROGRESS ?= auto +REGISTRY ?= git.distrust.co/public +VERSION := latest + +include $(PWD)/src/make/macros.mk .DEFAULT_GOAL := .PHONY: default @@ -126,20 +133,14 @@ config/$(ENVIRONMENT).tfbackend: $(OUT_DIGEST) infra/backend/$(ENVIRONMENT).tfst -state $(ENVIRONMENT).tfstate' \ ) -out/tools-image.digest: Containerfile.tools | out - docker build -f Containerfile.tools -q . > $@ +build-tools: REVISION = $(shell git rev-list -1 HEAD -- images/tools) +build-tools: SOURCE_DATE_EPOCH = $(shell git log -1 --format=%ct $(REVISON)) +build-tools: images/tools/Containerfile | out + export SOURCE_DATE_EPOCH + cd images/tools + $(call build-container,tools,$(VERSION),$<,$(SOURCE_DATE_EPOCH),$(REVISION)) -GPG_TTY ?= $(shell tty) - -define run-container - docker run -it $(1) \ - -v $$PWD/.bashrc:/home/user/.bashrc:ro \ - -v $(shell gpgconf --list-dirs socketdir)/:/run/user/1000/gnupg/:ro \ - -v $(shell gpgconf --list-dirs homedir):/home/user/.gnupg:rw \ - -e SSH_AUTH_SOCK=/run/user/1000/gnupg/$(shell basename $(shell gpgconf --list-dirs agent-ssh-socket)) \ - --entrypoint $(3) \ - $(2) -endef +out/tools-image.digest: out build-tools .PHONY: plan plan: out/tools-image.digest @@ -185,25 +186,3 @@ apply: \ $(CACHE_DIR)/secrets: mkdir -p $@ -# Note: Decryption MUST reset the mod time to avoid encryption/decryption loops -# Encrypt if: -# - Both files exist, local is newer than remote -# - Only local exists -define maybe_encrypt_secret - test \( -f $(1) -a -f $(2) -a $(1) -nt $(2) \) -o \ - \( -f $(1) -a ! -f $(2) \) && \ - $(SOPS) --encrypt $(1) > $(2) || true -endef - -# Only decrypt when local files don't exist -# Unfortunately, this means we can't decrypt if the secrets update. We can't -# do that because otherwise it creates a loop. The secrets update, therefore we -# decrypt secrets, but because the modtime of the decrypted secrets is newer -# than the encrypted secrets, we want to reencrypt encrypted secrets. -define maybe_decrypt_secret - test -f $(1) -a ! -f $(2) && \ - mkdir -p `dirname $(2)` && \ - $(SOPS) --decrypt $(1) > $(2) && \ - touch -d 1970-01-01 $(2) || \ - true -endef diff --git a/Containerfile.tools b/images/tools/Containerfile similarity index 98% rename from Containerfile.tools rename to images/tools/Containerfile index d714ed8..2026c52 100644 --- a/Containerfile.tools +++ b/images/tools/Containerfile @@ -13,7 +13,7 @@ FROM stagex/user-libgcrypt@sha256:384f0e703afad6f8885ec77fb814ef182a08600a203218 FROM stagex/user-opentofu@sha256:48fb7bb6504493a95d248c571cc7f3a5cb505edd5007a5f431d3422bf40c19a4 AS user-opentofu FROM stagex/user-sops@sha256:4a1bd25239d1196bba261303ca657383e634f136f6e5fcb4e368fdb6dcda086c AS user-sops FROM stagex/user-talosctl@sha256:23ff2d686a0c251db4f8a8f07e9b18c81c64eaa07da97de5a75fccbea3e595c4 AS user-talosctl -FROM stagex/user-kubectl@sha256:878a726130e9c3ea2f41c23725b325a8a4c3c7555971c511fef099daff037753 as user-kubectl +FROM stagex/user-kubectl@sha256:878a726130e9c3ea2f41c23725b325a8a4c3c7555971c511fef099daff037753 AS user-kubectl FROM stagex/user-kustomize@sha256:b5ddc79510731ed6fb9664d2e9ed95e89ec1e58d66a23d2871ec8018c09ac0c9 AS user-kustomize FROM stagex/user-kustomize-sops@sha256:bcf69eb5e16d280e2989fb028069b8a57b14084d954a3eba3dff3921f1268913 AS user-kustomize-sops FROM stagex/user-helm@sha256:e7d2e13db8483f5356b96337308edbd5a0e602cc76c4c5ea5ed730ae6d2b2dcc AS user-helm diff --git a/src/make/macros.mk b/src/make/macros.mk new file mode 100644 index 0000000..68036cf --- /dev/null +++ b/src/make/macros.mk @@ -0,0 +1,50 @@ +# Note: Decryption MUST reset the mod time to avoid encryption/decryption loops +# Encrypt if: +# - Both files exist, local is newer than remote +# - Only local exists +define maybe_encrypt_secret + test \( -f $(1) -a -f $(2) -a $(1) -nt $(2) \) -o \ + \( -f $(1) -a ! -f $(2) \) && \ + $(SOPS) --encrypt $(1) > $(2) || true +endef + +# Only decrypt when local files don't exist +# Unfortunately, this means we can't decrypt if the secrets update. We can't +# do that because otherwise it creates a loop. The secrets update, therefore we +# decrypt secrets, but because the modtime of the decrypted secrets is newer +# than the encrypted secrets, we want to reencrypt encrypted secrets. +define maybe_decrypt_secret + test -f $(1) -a ! -f $(2) && \ + mkdir -p `dirname $(2)` && \ + $(SOPS) --decrypt $(1) > $(2) && \ + touch -d 1970-01-01 $(2) || \ + true +endef + +define run-container + docker run -it $(1) \ + -v $$PWD/.bashrc:/home/user/.bashrc:ro \ + -v $(shell gpgconf --list-dirs socketdir)/:/run/user/1000/gnupg/:ro \ + -v $(shell gpgconf --list-dirs homedir):/home/user/.gnupg:rw \ + -e SSH_AUTH_SOCK=/run/user/1000/gnupg/$(shell basename $(shell gpgconf --list-dirs agent-ssh-socket)) \ + --entrypoint $(3) \ + $(2) +endef + +define build-container + mkdir -p out/image/$(1) + SOURCE_DATE_EPOCH=$(4) docker \ + buildx \ + build \ + --tag $(REGISTRY)/$(1):$(2) \ + --output \ + name=$(1),type=oci,rewrite-timestamp=true,force-compression=true,annotation.org.opencontainers.image.revision=$(5),annotation.org.opencontainers.image.version=$(2),tar=true,dest=- \ + $(EXTRA_ARGS) \ + $(NOCACHE_FLAG) \ + $(CHECK_FLAG) \ + --platform=$(PLATFORM) \ + --progress=$(PROGRESS) \ + -f $(3) \ + $(dir $3) \ + | tar -C out/image/$(1) -mx +endef