feat: dynamic make target generation

This commit is contained in:
Lance R. Vick 2024-09-03 12:45:50 -07:00
parent 62bfdf8636
commit 2fdf30531b
No known key found for this signature in database
GPG key ID: 8E47A1EC35A1551D
8 changed files with 131 additions and 4506 deletions

View file

@ -1,76 +1,24 @@
export PLATFORM := linux/amd64
export BUILDER := $(shell which docker)
export REGISTRY_LOCAL := stagex-local
export REGISTRY_REMOTE := stagex
export CHECK ?= 0
export NOCACHE ?= 0
export MIRRORS := \
git.distrust.co \
hub.docker.com
ifeq ($(NOCACHE), 1)
NOCACHE_FLAG=--no-cache
else
NOCACHE_FLAG=
endif
export NOCACHE_FLAG
ifeq ($(CHECK), 1)
CHECK_FLAG=--check
else
CHECK_FLAG=
endif
export CHECK_FLAG
include src/global.mk
clean_logs := $(shell rm *.log 2>&1 >/dev/null || :)
all: $(all_packages)
DEFAULT_GOAL := default
.PHONY: default
default: all
include src/macros.mk
include src/packages.mk
include src/groups.mk
.PHONY: all
all: \
compat \
$(shell find packages/* -type d -exec sh -c 'basename {} | tr "\n" " "' \; )
.PHONY: check
check:
$(MAKE) CHECK=1 all
@$(MAKE) CHECK=1 all
.PHONY: compat
compat:
./src/compat.sh
.PHONY: preseed
preseed:
./src/preseed.sh
.PHONY: verify
verify:
./src/verify.sh
@$(call verify)
.PHONY: digests
digests:
./src/digests.sh
digests.txt: $(shell find out -iname index.json | tr "\n" " ")
./src/digests.sh > digests.txt
.PHONY: sign
sign:
./src/digests.sh | diff digests.txt /dev/stdin
cut -d' ' -f2 digests.txt | xargs -n1 ./src/sign.sh $(REGISTRY_REMOTE)
@$(call sign)
out/graph.svg: Makefile
$(MAKE) -Bnd | make2graph | dot -Tsvg -o graph.svg
digests:
@$(call digests)
.PHONY: gen-make
gen-make: out/sxctl/index.json $(shell find packages/*/Containerfile | tr '\n' ' ')
env -C out/sxctl tar -cf - . | docker load
docker run \
--rm \
--volume .:/src \
--user $(shell id -u):$(shell id -g) \
stagex/sxctl -baseDir=/src gen make
release: all
@$(call digests) > digests.txt
compat:
@./src/compat.sh
preseed:
@./src/preseed.sh

View file

@ -1,7 +0,0 @@
#!/bin/bash
self=${1}
for each in $(find out/*/index.json); do
package=$(basename $(dirname ${each}))
[ "$package" == "$self" ] && continue
printf -- ' --build-context %s=oci-layout://./out/%s' "stagex/${package}" "${package}"
done

View file

@ -1,8 +0,0 @@
#!/bin/sh
for each in $(find out -iname "index.json"| sort); do
printf \
"%s %s\n" \
$(cat $each | jq -r '.manifests[].digest | sub ("sha256:";"")') \
"$(basename $(dirname $each))"
done

40
src/global.mk Normal file
View file

@ -0,0 +1,40 @@
export PLATFORM := linux/amd64
export BUILDER := $(shell which docker)
export REGISTRY_LOCAL := stagex-local
export REGISTRY_REMOTE := stagex
export CHECK ?= 0
export NOCACHE ?= 0
export MIRRORS := \
git.distrust.co \
hub.docker.com
ifeq ($(NOCACHE), 1)
NOCACHE_FLAG=--no-cache
else
NOCACHE_FLAG=
endif
export NOCACHE_FLAG
ifeq ($(CHECK), 1)
CHECK_FLAG=--check
else
CHECK_FLAG=
endif
export CHECK_FLAG
clean_logs := $(shell rm *.log 2>&1 >/dev/null || :)
DEFAULT_GOAL := default
.PHONY: default
default: compat all
.PHONY: all check compat preseed verify sign
include src/macros.mk
out:
mkdir out
all_packages := $(shell $(call folder-list,packages))
$(all_packages): %: out/%/index.json
$(foreach package,$(all_packages),$(eval $(call gen-target,$(package))))

View file

@ -1,2 +0,0 @@
.PHONY: bootstrap
bootstrap: stage0 stage1 stage2 stage3

View file

@ -1,3 +1,76 @@
define target-list
$(eval PACKAGE := $(1))
grep -Ri "AS package" packages/$(PACKAGE)/Containerfile \
| sed -e 's/FROM .* AS package//g' \
| while IFS= read -r; \
do \
printf "$(PACKAGE) "; \
done
endef
define sign
./src/digests.sh | diff digests.txt /dev/stdin
cut -d' ' -f2 digests.txt | xargs -n1 ./src/sign.sh $(REGISTRY_REMOTE)
endef
define verify
cat digests.txt \
| sed 's/\([a-z0-9]\+\) \(.*\)/signatures\/stagex\/\2@sha256=\1/g' \
| while IFS= read -r sigdir; do \
echo $$sigdir; \
find $$sigdir -type f \
| while IFS= read -r sig; do \
cat $$sig | gpg -v 2>&1 > /dev/null | grep "Good signature" || :; \
done; \
done;
endef
define digests
find out -iname "index.json" \
| awk -F/ '{print $$2}' \
| sort \
| while IFS= read -r package; do \
jq \
-jr '.manifests[].digest | sub ("sha256:";"")' \
out/$${package}/index.json; \
printf " %s\n" "$${package}"; \
done
endef
define dep-list
$(eval PACKAGE := $(1))
grep -Ri "^COPY --from=stagex/" packages/$(PACKAGE)/Containerfile \
| sed -e 's/COPY --from=stagex\/\([a-z0-9._-]\+\) .*/\1/g' \
| uniq \
| while IFS= read -r package; \
do \
printf "out/$${package}/index.json "; \
done
endef
define folder-list
$(eval FOLDER := $(1))
ls -1 $(FOLDER) 2>/dev/null | while IFS= read -r f; do printf "$$f "; done
endef
define gen-target
out/$(1)/index.json: $(shell $(call dep-list,$(1))) | out
$(call build,$(1))
endef
define build-context-args
$(eval PACKAGE := $(1))
grep -Ri "^COPY --from=stagex/" packages/$(PACKAGE)/Containerfile \
| sed -e 's/COPY --from=stagex\/\([a-z0-9._-]\+\) .*/\1/g' \
| uniq \
| while IFS= read -r package; do \
if [ "$$package" = "$(PACKAGE)" ]; then
continue; \
fi; \
printf -- ' --build-context %s=oci-layout://./out/%s' "stagex/$${package}" "$${package}"; \
done
endef
# Build package with chosen $(BUILDER)
# Supported BUILDERs: docker
# Usage: $(call build,core/$(NAME),$(VERSION),$(TARGET),$(EXTRA_ARGS))
@ -27,6 +100,7 @@ define build
$(eval EXTRA_ARGS := $(if $(4),$(4),))
$(eval REVISION := $(shell git rev-list HEAD -1 packages/$(NAME)))
$(eval TEMPFILE := out/.$(notdir $(basename $@)).tmp.tar)
$(eval BUILD_CONTEXT := $(shell $(call build-context-args,$(NAME))))
$(eval BUILD_CMD := \
DOCKER_BUILDKIT=1 \
BUILDKIT_MULTI_PLATFORM=1 \
@ -35,15 +109,12 @@ define build
build \
--ulimit nofile=2048:16384 \
--tag $(REGISTRY_REMOTE)/$(NAME):$(VERSION) \
--build-arg CACHE_BUST="$(shell date)" \
--build-arg SOURCE_DATE_EPOCH=1 \
--build-arg CORES=$(shell nproc --all) \
--platform $(PLATFORM) \
--progress=plain \
$(if $(filter latest,$(VERSION)),,--build-arg VERSION=$(VERSION)) \
--output type=oci,rewrite-timestamp=true,force-compression=true,name=$(NAME),annotation.org.opencontainers.image.revision=$(REVISION),annotation.org.opencontainers.image.version=$(VERSION),tar=false,dest=out/$(NAME) \
--target $(TARGET) \
$(shell ./src/context.sh $(NAME)) \
$(BUILD_CONTEXT) \
$(EXTRA_ARGS) \
$(NOCACHE_FLAG) \
$(CHECK_FLAG) \
@ -51,8 +122,7 @@ define build
packages/$(NAME) \
)
$(eval TIMESTAMP := $(shell TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ"))
mkdir -p out/ \
&& echo $(TIMESTAMP) $(BUILD_CMD) start >> out/build.log \
echo $(TIMESTAMP) $(BUILD_CMD) start >> out/build.log \
&& rm -rf out/$(NAME) \
&& $(BUILD_CMD) \
&& echo $(TIMESTAMP) $(BUILD_CMD) end >> out/build.log;

File diff suppressed because it is too large Load diff

View file

@ -1,13 +0,0 @@
#!/bin/sh
set -eu
for each in $( \
cat digests.txt \
| sed 's/\([a-z0-9]\+\) \(.*\)/signatures\/stagex\/\2@sha256=\1/g' \
); do
echo $each;
for sig in $(find $each -type f); do
cat $sig | /usr/bin/gpg -v 2>&1 > /dev/null \
| grep "Good signature" || :
done;
done