# Base directories IMAGES_PATH := images LIBRARY_PATH := library SYMLINK_PREFIX := library_ # Docker registry variables REGISTRY := git.unkin.net OWNER := unkin DATE_TAG := $(shell date +%Y%m%d) SUFFIX=$(shell basename $$(mktemp -u) | cut -d . -f 2) GIT_BRANCH=$(shell git symbolic-ref --short HEAD 2>/dev/null || echo $$GITHUB_HEAD_REF) GIT_COMMIT := $(shell git rev-parse --short HEAD) # Find all subdirectories under the IMAGES_PATH DIRS := $(shell find $(IMAGES_PATH) -mindepth 3 -maxdepth 3 -type d | sed 's|$(IMAGES_PATH)/||') .PHONY: list $(DIRS) .DEFAULT_GOAL := default default: clean ./ci/build.sh # Separate base images from others BASE_IMAGES = $(filter %/base,$(DIRS)) OTHER_IMAGES = $(filter-out %/base,$(DIRS)) # Make all images, ensuring base images build first all: @for dir in $(BASE_IMAGES); do \ $(MAKE) $$dir; \ done @for dir in $(OTHER_IMAGES); do \ $(MAKE) $$dir; \ done # List all directories list: @echo "Images:" @for dir in $(BASE_IMAGES); do \ echo " '$$dir'"; \ done @for dir in $(OTHER_IMAGES); do \ echo " '$$dir'"; \ done # Dynamically create targets for each directory .ONESHELL: $(DIRS): @echo "Building for $@" # Export environment export VAULT_ADDR=https://vault.service.consul:8200 export VAULT_TOKEN=$$(vault write -field=token auth/approle/login role_id=$$VAULT_ROLEID) && \ eval $$(vault kv get -format=json kv/service/packer/builder/env | jq -r '.data.data | to_entries[] | "export \(.key)=\(.value)"') @echo "Environment retrieved for $@" # Check if on master branch @if [ "$(GIT_BRANCH)" = "master" ]; then \ echo "Current branch is $(GIT_BRANCH), checking latest timestamp in consul."; \ LAST_BUILD_TIMESTAMP=$$(consul kv get infra/packer/$@/timestamp || echo "0"); \ CURRENT_TIME=$$(date +%s); \ if [ $$((CURRENT_TIME - LAST_BUILD_TIMESTAMP)) -lt 86400 ]; then \ LAST_COMMIT=$$(consul kv get infra/packer/$@/commit || echo "0"); \ if [ "$$((LAST_COMMIT))" == "$(GIT_COMMIT)" ]; then \ echo "Skipping build for $@. Same commit as last, and less than 24 hours since last build."; \ exit 0; \ fi; \ fi; \ fi # Link .hcl files @find $(LIBRARY_PATH) -name '*.hcl' -exec sh -c 'ln -sf $$PWD/{} $(IMAGES_PATH)/$@/$(SYMLINK_PREFIX)$$(basename {})' \; # Link builds @for build in $$(cat $(IMAGES_PATH)/$@/builds); do \ ln -sf ../../../../builds/$${build}.pkr.hcl $(IMAGES_PATH)/$@/library_$${build}.build.pkr.hcl; \ done # Build the image @(cd $(IMAGES_PATH)/$@ && \ export DATE=$(DATE_TAG) && \ export OS_NAME=$$(echo $@ | cut -d'/' -f1) && \ export OS_VERSION_FULL=$$(echo $@ | cut -d'/' -f2) && \ export OS_IMAGE=$$(echo $@ | cut -d'/' -f3) && \ export OS_VERSION_MAJOR=$$(echo $$OS_VERSION_FULL | cut -d'.' -f1) && \ export DOCKER_SOURCE=$$OS_NAME:$$OS_VERSION_FULL && \ export DOCKER_SERVER='git.unkin.net' && \ export INCUS_SOURCE="images:$$OS_NAME/$$OS_VERSION_MAJOR" && \ export SUFFIX=$(SUFFIX) && \ export GIT_COMMIT=$(GIT_COMMIT) && \ export GIT_BRANCH=$(GIT_BRANCH) && \ export VAULT_ADDR=https://vault.service.consul:8200 export VAULT_TOKEN=$$(vault write -field=token auth/approle/login role_id=$$VAULT_ROLEID) && \ /usr/bin/packer init . && \ /usr/bin/packer build . ) # Update build timestamp and date in Consul if on master branch @if [ "$(GIT_BRANCH)" = "master" ]; then \ echo "Current branch is $(GIT_BRANCH), updating consul."; \ CURRENT_TIMESTAMP=$$(date +%s); \ READABLE_DATE=$$(date '+%Y-%m-%d %H:%M:%S %Z'); \ consul kv put infra/packer/$@/timestamp $$CURRENT_TIMESTAMP; \ consul kv put infra/packer/$@/date "$$READABLE_DATE"; \ consul kv put infra/packer/$@/commit "$(GIT_COMMIT)"; \ fi # Clean all symlinks clean: @echo "Cleaning up symlinks..." @find $(IMAGES_PATH) -name 'library_*' -type l -delete @echo "All symlinks removed!"