From 6cbaa06bec9c59618fe1a8ca5987f503b34783d5 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Mon, 7 Jul 2025 23:50:03 +0200 Subject: [PATCH 01/14] chore(license): Change date and copyright I keep MIT license, just changed date and pseudo --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 76b1ebf..5a01268 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022-2024 Patrice Ferlet +Copyright (c) 2022-2025 Patrice Ferlet (aka metal3d) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 13d231a62cec9bfb56ccd0764edbf7a43f7748e8 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Wed, 9 Jul 2025 14:11:46 +0200 Subject: [PATCH 02/14] feat(package): Add RPM, deb, pacman and tar packages and manpage Build package using fpm. As I don't want ruby/gem in my computer, the build system creates an OCI image with Podman (at this time), and generate dist pacakges. To enhance the packages, a manpage is now generated from the documentation. --- .gitignore | 3 ++ Makefile | 55 ++++++++++++++++++++++++++++++++++++ doc/manpage_requirements.txt | 2 ++ doc/mkdocs.yml | 10 +++++++ doc/preprocess.py | 22 +++++++++++++++ packaging/description | 4 +++ packaging/oci/Containerfile | 15 ++++++++++ 7 files changed, 111 insertions(+) create mode 100644 doc/manpage_requirements.txt create mode 100644 doc/preprocess.py create mode 100644 packaging/description create mode 100644 packaging/oci/Containerfile diff --git a/.gitignore b/.gitignore index 8c1ff8b..6cbef35 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ cover* # nsis nsis/*.dll nsis/*.exe + +doc/share +__pycache__ diff --git a/Makefile b/Makefile index 8c785c7..18f8f97 100644 --- a/Makefile +++ b/Makefile @@ -220,6 +220,19 @@ doc: # generate the labels doc and code doc $(MAKE) __label_doc +manpage: + @echo "=> Generating manpage from documentation" + @cd doc && \ + [ -d venv ] || python -m venv venv; \ + source venv/bin/activate && \ + echo "==> Installing requirements in the virtual env..." && \ + pip install -qq -r requirements.txt && \ + pip install -qq -r manpage_requirements.txt && \ + echo "==> Generating manpage..." && \ + MANPAGE=true mkdocs build && \ + rm -rf site && + echo "==> Manpage generated in doc/share/man/man1/katenary.1" + install-gomarkdoc: go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest @@ -284,3 +297,45 @@ cover: dist-clean: rm -rf dist rm -f katenary + + +#FPM_OPTS=--name katenary \ +# --description "$(shell cat packaging/description)" \ +# --version $(VERSION) \ +# --url https://katenary.org \ +# --vendor "Katenary Project" \ +# --maintainer "Patrice Ferlet " \ +# --license "MIT" \ +# katenary-linux-amd64=/usr/local/bin/katenary +#packages: +# podman build -t packaging:fedora ./packaging/oci +# podman run -it --rm -w /opt -v ./dist:/opt:z --userns keep-id:uid=999,gid=999 packaging:fedora \ +# fpm -s dir -t rpm --rpm-summary="$(shell head -n1 packaging/description)" -f $(FPM_OPTS) +# podman run -it --rm -w /opt -v ./dist:/opt:z --userns keep-id:uid=999,gid=999 packaging:fedora \ +# fpm -s dir -t deb -f $(FPM_OPTS) + +# print packaging/description and replace newlines with explicit \n +DESCRIPTION := $(shell cat packaging/description | sed ':a;N;$$!ba;s/\n/\\n/g') + + +FPM_OCI_OPTS=-w /opt/katenary/dist \ + -v ./:/opt/katenary:z \ + --userns keep-id:uid=999,gid=999 packaging:fedora +FPM_OPTS=--name katenary \ + --version $(VERSION) \ + --url https://katenary.org \ + --vendor "Katenary Project" \ + --maintainer "Patrice Ferlet " \ + --license "MIT" \ + --description="$$(printf "$(DESCRIPTION)" | fold -s)" \ + ./katenary-linux-amd64=/usr/local/bin/katenary \ + ../doc/share/man/man1/katenary.1=/usr/local/share/man/man1/katenary.1 \ + ../LICENSE=/usr/local/share/doc/katenary/LICENSE \ + ../README.md=/usr/local/share/doc/katenary/README.md +packages: manpage + @podman build -t packaging:fedora ./packaging/oci 1>/dev/null + @for target in rpm deb pacman tar; do \ + echo "==> Building $$target package..."; \ + podman run $(FPM_OCI_OPTS) fpm -s dir -t $$target -f $(FPM_OPTS); \ + done + mv dist/katenary.tar dist/katenary-$(VERSION).tar diff --git a/doc/manpage_requirements.txt b/doc/manpage_requirements.txt new file mode 100644 index 0000000..9072507 --- /dev/null +++ b/doc/manpage_requirements.txt @@ -0,0 +1,2 @@ +beautifulsoup4==4.* +mkdocs-manpage[preprocess] diff --git a/doc/mkdocs.yml b/doc/mkdocs.yml index 80925d3..64196d5 100644 --- a/doc/mkdocs.yml +++ b/doc/mkdocs.yml @@ -3,6 +3,16 @@ docs_dir: ./docs plugins: - search - inline-svg + - manpage: + enabled: !ENV [MANPAGE, false] + preprocess: preprocess.py + pages: + - title: Katenary + header: Katenary helm chart generator + output: share/man/man1/katenary.1 + inputs: + - usage.md + - labels.md theme: name: material custom_dir: overrides diff --git a/doc/preprocess.py b/doc/preprocess.py new file mode 100644 index 0000000..d691cc1 --- /dev/null +++ b/doc/preprocess.py @@ -0,0 +1,22 @@ +"""Called by mkdocs to preprocess files and build manpages""" + +from bs4 import BeautifulSoup, Tag + + +def to_remove(tag: Tag) -> bool: + """Removes images, SVGs, links containing images or SVGs, and permalinks from the BeautifulSoup object.""" + if tag.name in {"img", "svg"}: + return True + # remove links containing images or SVGs + if tag.name == "a" and tag.img and to_remove(tag.img): + return True + # remove permalinks + if tag.name == "a" and "headerlink" in tag.get("class", ()): + return True + return False + + +def preprocess(soup: BeautifulSoup, output: str) -> None: + """Preprocess the BeautifulSoup object to remove unwanted elements.""" + for element in soup.find_all(to_remove): + element.decompose() diff --git a/packaging/description b/packaging/description new file mode 100644 index 0000000..63c1b66 --- /dev/null +++ b/packaging/description @@ -0,0 +1,4 @@ +Katenary transforms docker/podman compose files to Helm Charts. +It harnesses the labels from your "compose" file to craft complete Helm Charts effortlessly, saving you time and energy. +- Simple automated CLI: Katenary handles the grunt work, generating everything needed for seamless service binding and Helm Chart creation. +- Effortless Efficiency: You only need to add labels when it's necessary to precise things. Then call katenary convert and let the magic happen diff --git a/packaging/oci/Containerfile b/packaging/oci/Containerfile new file mode 100644 index 0000000..7179620 --- /dev/null +++ b/packaging/oci/Containerfile @@ -0,0 +1,15 @@ +FROM registry.fedoraproject.org/fedora:42 +RUN set -eux; \ + microdnf -y install \ + rubygems rpmbuild bsdtar + +RUN useradd -m -r -d /home/builder -s /bin/bash builder; \ + chown builder:builder /home/builder + +USER builder +ENV PATH="/home/builder/bin:${PATH}" +WORKDIR /home/builder +RUN gem install fpm + + + From 9fadc779798cb93a0edc01c0aa6b206bbebc32a4 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Thu, 10 Jul 2025 08:10:11 +0200 Subject: [PATCH 03/14] chore(package): Add application in registry Allow the application to appear in "Install/Uninstall" Windows parameters. --- nsis/katenary.nsi | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nsis/katenary.nsi b/nsis/katenary.nsi index f098c18..3a7c4cd 100644 --- a/nsis/katenary.nsi +++ b/nsis/katenary.nsi @@ -92,8 +92,13 @@ Section "Install" File "..\dist\katenary.exe" File "..\LICENSE" File "..\README.md" - WriteUninstaller "$INSTDIR\uninstall-katenary.exe" + WriteUninstaller "$INSTDIR\uninstall-katenary.exe" + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Katenary" "DisplayName" "Katenary" + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Katenary" "UninstallString" "$INSTDIR\uninstall-katenary.exe" + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Katenary" "InstallLocation" "$INSTDIR" + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Katenary" "DisplayIcon" "$INSTDIR\katenary.exe" + EnVar::SetHKCU Pop $0 @@ -114,4 +119,6 @@ Section "Uninstall" Delete "$INSTDIR\LICENSE" Delete "$INSTDIR\README.md" RMDir "$INSTDIR" + + DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Katenary" SectionEnd From 0f3528818f297e3080fdc17b4b8b993a34be9bd0 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Thu, 10 Jul 2025 08:11:39 +0200 Subject: [PATCH 04/14] chore(package): Add NSIS to the package image This container image can make Windows installer too. --- packaging/oci/Containerfile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packaging/oci/Containerfile b/packaging/oci/Containerfile index 7179620..6eaede0 100644 --- a/packaging/oci/Containerfile +++ b/packaging/oci/Containerfile @@ -1,15 +1,20 @@ FROM registry.fedoraproject.org/fedora:42 RUN set -eux; \ microdnf -y install \ - rubygems rpmbuild bsdtar + rubygems rpmbuild bsdtar mingw-nsis-base.x86_64 mingw32-nsis.noarch; \ + microdnf clean all; -RUN useradd -m -r -d /home/builder -s /bin/bash builder; \ +# create user with 999 UID/GID +RUN set -eux; \ + groupadd -g 999 builder && \ + useradd -m -r -u 999 -g 999 -d /home/builder -s /bin/bash builder && \ chown builder:builder /home/builder USER builder ENV PATH="/home/builder/bin:${PATH}" WORKDIR /home/builder -RUN gem install fpm +RUN set -eux; \ + gem install fpm From b7186eb8b4be8a234d7671ae01473088bb602fcb Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Thu, 10 Jul 2025 08:13:49 +0200 Subject: [PATCH 05/14] chore(makefile): Refacto Refactor the makefile: - use the "package" container image to build windows installer - cleanup and reorder targets - enhance the way we named packages (add version and architecture to the name) --- Makefile | 231 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 109 deletions(-) diff --git a/Makefile b/Makefile index 18f8f97..bb2886c 100644 --- a/Makefile +++ b/Makefile @@ -1,58 +1,71 @@ -CUR_SHA=$(shell git log -n1 --pretty='%h') -CUR_BRANCH=$(shell git branch --show-current) -VERSION=$(shell git describe --exact-match --tags $(CUR_SHA) 2>/dev/null || echo $(CUR_BRANCH)-$(CUR_SHA)) - -# get the container (podman is preferred, but docker is also supported) -# TODO: prpose nerdctl -CTN:=$(shell which podman 2>&1 1>/dev/null && echo "podman" || echo "docker") -PREFIX=~/.local - -GOVERSION=1.24 -GO=container -OUT=katenary - -MODE=default -RELEASE="" -# if release mode -ifeq ($(MODE),release) - VERSION:=release-$(VERSION) -endif - -BLD_CMD=go build -ldflags="-X 'katenary/generator.Version=$(VERSION)'" -o $(OUT) ./cmd/katenary -GOOS=linux -GOARCH=amd64 -CGO_ENABLED=0 - -# GPG signer -SIGNER=metal3d@gmail.com - -# upx compression -UPX_OPTS = -UPX ?= upx $(UPX_OPTS) - -BUILD_IMAGE=docker.io/golang:$(GOVERSION) -# SHELL=/bin/bash - -# List of source files -SOURCES=$(wildcard ./*.go ./*/*.go ./*/*/*.go) -# List of binaries to build and sign -BINARIES=dist/katenary-linux-amd64 dist/katenary-linux-arm64 dist/katenary.exe dist/katenary-darwin-amd64 dist/katenary-freebsd-amd64 dist/katenary-freebsd-arm64 -BINARIES += dist/katenary-windows-setup.exe -# installer -# List of signatures to build -ASC_BINARIES=$(patsubst %,%.asc,$(BINARIES)) - -# defaults -BROWSER=$(shell command -v epiphany || echo xdg-open) +# Strict mode SHELL := bash -# strict mode .SHELLFLAGS := -eu -o pipefail -c -# One session per target .ONESHELL: .DELETE_ON_ERROR: MAKEFLAGS += --warn-undefined-variables MAKEFLAGS += --no-builtin-rules -.PHONY: help dist-clean build install tests test doc nsis +.PHONY: help dist-clean dist package build install test doc nsis + +# Get a version string from git +CUR_SHA=$(shell git log -n1 --pretty='%h') +CUR_BRANCH=$(shell git branch --show-current) +VERSION=$(shell git describe --exact-match --tags $(CUR_SHA) 2>/dev/null || echo $(CUR_BRANCH)-$(CUR_SHA))# use by golang flags +PKG_VERSION=$(VERSION)# used for package name + +# Go build command and environment variables for target OS and architecture +GOVERSION=1.24 +GO=container # container, local +OUTPUT=katenary +GOOS=linux +GOARCH=amd64 +CGO_ENABLED=0 +PREFIX=~/.local +BLD_CMD=go build -ldflags="-X 'katenary/generator.Version=$(VERSION)'" -o $(OUTPUT) ./cmd/katenary + +# Get the container (podman is preferred, but docker is also supported) +# TODO: prpose nerdctl +CTN:=$(shell which podman 2>&1 1>/dev/null && echo "podman" || echo "docker") + + +# Packaging OCI image, to build rpm, deb, pacman, tar packages +PKG_OCI_IMAGE=packaging:fedora +PKG_OCI_OPTS:=--rm -it \ + -w $$PKG_OCI_WDIR \ + -v ./:/opt/katenary:z \ + --userns keep-id:uid=999,gid=999 \ + $(PKG_OCI_IMAGE) + +# Set the version and package version, following build mode (default, release) +MODE=default +RELEASE="" +# If release mode +ifeq ($(MODE),release) + PKG_VERSION=v$(VERSION) + VERSION:=release-$(VERSION) +endif + + +# UPX compression +UPX_OPTS = +UPX ?= upx $(UPX_OPTS) + +BUILD_IMAGE=docker.io/golang:$(GOVERSION) + +# List of source files +SOURCES=$(shell find -name "*.go" -or -name "*.tpl" -type f | grep -v -P "^./example|^./vendor") +# List of binaries to build and sign +BINARIES=dist/katenary-linux-amd64 dist/katenary-linux-arm64 dist/katenary.exe dist/katenary-darwin-amd64 dist/katenary-freebsd-amd64 dist/katenary-freebsd-arm64 +BINARIES += dist/katenary-windows-setup.exe + +## GPG +# List of signatures to build +ASC_BINARIES=$(patsubst %,%.asc,$(BINARIES)) +# GPG signer +SIGNER=metal3d@gmail.com + +# Browser command to see coverage report after tests +BROWSER=$(shell command -v epiphany || echo xdg-open) all: build @@ -95,6 +108,7 @@ help: ## BUILD +# Simply build the binary for the current OS and architecture build: pull katenary pull: @@ -120,47 +134,50 @@ endif # Make dist, build executables for all platforms, sign them, and compress them with upx if possible. # Also generate the windows installer. -dist: prepare $(BINARIES) upx gpg-sign check-sign +dist: prepare $(BINARIES) upx gpg-sign check-sign packages prepare: pull mkdir -p dist -dist/katenary-linux-amd64: +dist/katenary-linux-amd64: $(SOURCES) Makefile go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for linux-amd64...\033[0m" - $(MAKE) katenary GOOS=linux GOARCH=amd64 OUT=$@ + $(MAKE) katenary GOOS=linux GOARCH=amd64 OUTPUT=$@ strip $@ -dist/katenary-linux-arm64: +dist/katenary-linux-arm64: $(SOURCES) Makefile go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for linux-arm...\033[0m" - $(MAKE) katenary GOOS=linux GOARCH=arm64 OUT=$@ + $(MAKE) katenary GOOS=linux GOARCH=arm64 OUTPUT=$@ -dist/katenary.exe: +dist/katenary.exe: $(SOURCES) Makefile go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for windows...\033[0m" - $(MAKE) katenary GOOS=windows GOARCH=amd64 OUT=$@ + $(MAKE) katenary GOOS=windows GOARCH=amd64 OUTPUT=$@ -dist/katenary-darwin-amd64: +dist/katenary-darwin-amd64: $(SOURCES) Makefile go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for darwin...\033[0m" - $(MAKE) katenary GOOS=darwin GOARCH=amd64 OUT=$@ + $(MAKE) katenary GOOS=darwin GOARCH=amd64 OUTPUT=$@ -dist/katenary-freebsd-amd64: +dist/katenary-freebsd-amd64: $(SOURCES) Makefile go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for freebsd...\033[0m" - $(MAKE) katenary GOOS=freebsd GOARCH=amd64 OUT=$@ + $(MAKE) katenary GOOS=freebsd GOARCH=amd64 OUTPUT=$@ strip $@ -dist/katenary-freebsd-arm64: +dist/katenary-freebsd-arm64: $(SOURCES) Makefile go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for freebsd-arm64...\033[0m" - $(MAKE) katenary GOOS=freebsd GOARCH=arm64 OUT=$@ + $(MAKE) katenary GOOS=freebsd GOARCH=arm64 OUTPUT=$@ -dist/katenary-windows-setup.exe: nsis/EnVar.dll dist/katenary.exe - makensis -DAPP_VERSION=$(VERSION) nsis/katenary.nsi +dist/katenary-windows-setup.exe: nsis/EnVar.dll dist/katenary.exe packager-oci-image $(SOURCES) Makefile go.mod go.sum + PKG_OCI_WDIR=/opt/katenary + podman run $(PKG_OCI_OPTS) \ + makensis -DAPP_VERSION=$(VERSION) nsis/katenary.nsi mv nsis/katenary-windows-setup.exe dist/katenary-windows-setup.exe +# Download the EnVar plugin for NSIS, put it in the nsis directory, and clean up nsis/EnVar.dll: curl https://nsis.sourceforge.io/mediawiki/images/7/7f/EnVar_plugin.zip -o nsis/EnVar_plugin.zip cd nsis @@ -168,12 +185,52 @@ nsis/EnVar.dll: mv Plugins/x86-unicode/EnVar.dll EnVar.dll rm -rf EnVar_plugin.zip Plugins -upx: +upx: dist/katenary-linux-amd64 dist/katenary-linux-arm64 dist/katenary-darwin-amd64 $(UPX) dist/katenary-linux-amd64 $(UPX) dist/katenary-linux-arm64 #$(UPX) dist/katenary.exe $(UPX) dist/katenary-darwin-amd64 --force-macos +## Linux / FreeBSD packages + +DESCRIPTION := $(shell cat packaging/description | sed ':a;N;$$!ba;s/\n/\\n/g') + + +FPM_OPTS=--name katenary \ + --version $(PKG_VERSION) \ + --url https://katenary.org \ + --vendor "Katenary Project" \ + --maintainer "Patrice Ferlet " \ + --license "MIT" \ + --description="$$(printf "$(DESCRIPTION)" | fold -s)" + +FPM_COMMON_FILES=../doc/share/man/man1/katenary.1=/usr/local/share/man/man1/katenary.1 \ + ../LICENSE=/usr/local/share/doc/katenary/LICENSE \ + ../README.md=/usr/local/share/doc/katenary/README.md \ + +packages: manpage packager-oci-image + @PKG_OCI_WDIR=/opt/katenary/dist + for arch in amd64 arm64; do \ + for target in rpm deb pacman tar; do \ + echo "==> Building $$target package for arch $$arch..."; \ + podman run $(PKG_OCI_OPTS) fpm -s dir -t $$target -a $$arch -f $(FPM_OPTS) \ + $(FPM_COMMON_FILES) \ + ./katenary-linux-$$arch=/usr/local/bin/katenary; \ + done + mv dist/katenary.tar dist/katenary-linux-$(PKG_VERSION).$$arch.tar + for target in freebsd tar; do \ + echo "==> Building $$target package for arch $$arch"; \ + podman run $(PKG_OCI_OPTS) fpm -s dir -t $$target -a $$arch -f $(FPM_OPTS) \ + $(FPM_COMMON_FILES) \ + ./katenary-freebsd-$$arch=/usr/local/bin/katenary; + done + mv dist/katenary-$(PKG_VERSION).txz dist/katenary-$(PKG_VERSION).$$arch.txz + mv dist/katenary.tar dist/katenary-freebsd-$(PKG_VERSION).$$arch.tar + done + +packager-oci-image: + @podman build -t packaging:fedora ./packaging/oci 1>/dev/null + ## GPG signing gpg-sign: @@ -275,8 +332,6 @@ sast: --exclude-rule go.lang.security.audit.crypto.use_of_weak_crypto.use-of-sha1 \ --metrics=on \ . - -tests: test test: @echo -e "\033[1;33mTesting katenary $(VERSION)...\033[0m" go test -coverprofile=cover.out ./... @@ -297,45 +352,3 @@ cover: dist-clean: rm -rf dist rm -f katenary - - -#FPM_OPTS=--name katenary \ -# --description "$(shell cat packaging/description)" \ -# --version $(VERSION) \ -# --url https://katenary.org \ -# --vendor "Katenary Project" \ -# --maintainer "Patrice Ferlet " \ -# --license "MIT" \ -# katenary-linux-amd64=/usr/local/bin/katenary -#packages: -# podman build -t packaging:fedora ./packaging/oci -# podman run -it --rm -w /opt -v ./dist:/opt:z --userns keep-id:uid=999,gid=999 packaging:fedora \ -# fpm -s dir -t rpm --rpm-summary="$(shell head -n1 packaging/description)" -f $(FPM_OPTS) -# podman run -it --rm -w /opt -v ./dist:/opt:z --userns keep-id:uid=999,gid=999 packaging:fedora \ -# fpm -s dir -t deb -f $(FPM_OPTS) - -# print packaging/description and replace newlines with explicit \n -DESCRIPTION := $(shell cat packaging/description | sed ':a;N;$$!ba;s/\n/\\n/g') - - -FPM_OCI_OPTS=-w /opt/katenary/dist \ - -v ./:/opt/katenary:z \ - --userns keep-id:uid=999,gid=999 packaging:fedora -FPM_OPTS=--name katenary \ - --version $(VERSION) \ - --url https://katenary.org \ - --vendor "Katenary Project" \ - --maintainer "Patrice Ferlet " \ - --license "MIT" \ - --description="$$(printf "$(DESCRIPTION)" | fold -s)" \ - ./katenary-linux-amd64=/usr/local/bin/katenary \ - ../doc/share/man/man1/katenary.1=/usr/local/share/man/man1/katenary.1 \ - ../LICENSE=/usr/local/share/doc/katenary/LICENSE \ - ../README.md=/usr/local/share/doc/katenary/README.md -packages: manpage - @podman build -t packaging:fedora ./packaging/oci 1>/dev/null - @for target in rpm deb pacman tar; do \ - echo "==> Building $$target package..."; \ - podman run $(FPM_OCI_OPTS) fpm -s dir -t $$target -f $(FPM_OPTS); \ - done - mv dist/katenary.tar dist/katenary-$(VERSION).tar From 8582010d900ef5b5a92d22aa384e839a03cb61e8 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Thu, 10 Jul 2025 15:15:25 +0200 Subject: [PATCH 06/14] fix(versionning): Fix version Version should be x.y.z for releases. It makes things homogenous for debian version (that needs a number as first char) and it is semantically better. At this time, the Makefile is OK. Maybe we don't need `PKG_VERSION` later. --- Makefile | 18 +++++++++++++----- generator/version.go | 12 +++++++++--- generator/version_test.go | 13 +++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index bb2886c..bccfe26 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,6 @@ MAKEFLAGS += --no-builtin-rules CUR_SHA=$(shell git log -n1 --pretty='%h') CUR_BRANCH=$(shell git branch --show-current) VERSION=$(shell git describe --exact-match --tags $(CUR_SHA) 2>/dev/null || echo $(CUR_BRANCH)-$(CUR_SHA))# use by golang flags -PKG_VERSION=$(VERSION)# used for package name # Go build command and environment variables for target OS and architecture GOVERSION=1.24 @@ -21,7 +20,6 @@ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 PREFIX=~/.local -BLD_CMD=go build -ldflags="-X 'katenary/generator.Version=$(VERSION)'" -o $(OUTPUT) ./cmd/katenary # Get the container (podman is preferred, but docker is also supported) # TODO: prpose nerdctl @@ -38,13 +36,16 @@ PKG_OCI_OPTS:=--rm -it \ # Set the version and package version, following build mode (default, release) MODE=default -RELEASE="" # If release mode ifeq ($(MODE),release) - PKG_VERSION=v$(VERSION) - VERSION:=release-$(VERSION) + PKG_VERSION:=$(VERSION) + VERSION:=$(VERSION) +else + PKG_VERSION=$(VERSION)# used for package name endif +BLD_CMD=go build -ldflags="-X 'katenary/generator.Version=$(VERSION)'" -o $(OUTPUT) ./cmd/katenary + # UPX compression UPX_OPTS = @@ -67,6 +68,13 @@ SIGNER=metal3d@gmail.com # Browser command to see coverage report after tests BROWSER=$(shell command -v epiphany || echo xdg-open) +check-version: + @echo "=> Checking version..." + @echo "Mode: $(MODE)" + @echo "Current version: $(VERSION)" + @echo "Package version: $(PKG_VERSION)" + @echo "Build command: $(BLD_CMD)" + all: build help: diff --git a/generator/version.go b/generator/version.go index b528773..310bbf2 100644 --- a/generator/version.go +++ b/generator/version.go @@ -1,8 +1,8 @@ package generator import ( + "regexp" "runtime/debug" - "strings" ) // Version is the version of katenary. It is set at compile time. @@ -12,13 +12,19 @@ var Version = "master" // changed at compile time // the version is set at compile time for the github release. But, it the user get // katneary using `go install`, the version should be different. func GetVersion() string { - if strings.HasPrefix(Version, "release-") { + // try to get the semantic version from the Version variable (theorically set at compile time) + reg := regexp.MustCompile(`^(.?\d+.\d+.\d+.*)|^release-.*`) + if reg.MatchString(Version) { return Version } - // get the version from the build info + + // OK... let's try to get the version from the build info + // get the version from the build info (when installed with go install) v, ok := debug.ReadBuildInfo() if ok { return v.Main.Version + "-" + v.GoVersion } + + // OK... none worked, so we return the default version return Version } diff --git a/generator/version_test.go b/generator/version_test.go index c65c2f3..9b153c7 100644 --- a/generator/version_test.go +++ b/generator/version_test.go @@ -8,11 +8,24 @@ import ( func TestVersion(t *testing.T) { // we build on "devel" branch v := GetVersion() + // by default, the version comes from build info and it's a development version if !strings.Contains(v, "(devel)") { t.Errorf("Expected version to be set, got %s", v) } // now, imagine we are on a release branch + Version = "1.0.0" + v = GetVersion() + if !strings.Contains(v, "1.0.0") { + t.Errorf("Expected version to be set, got %s", v) + } + // now, imagine we are on v1.0.0 + Version = "v1.0.0" + v = GetVersion() + if !strings.Contains(v, "v1.0.0") { + t.Errorf("Expected version to be set, got %s", v) + } + // we can also compile a release branch Version = "release-1.0.0" v = GetVersion() if !strings.Contains(v, "release-1.0.0") { From a26e832fedf16c3241aa93e9ae52a68465a791c5 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Fri, 11 Jul 2025 09:16:43 +0200 Subject: [PATCH 07/14] fix(doc): recompiled documentation --- doc/docs/packages/utils.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/docs/packages/utils.md b/doc/docs/packages/utils.md index 78a6551..3afadd0 100644 --- a/doc/docs/packages/utils.md +++ b/doc/docs/packages/utils.md @@ -149,7 +149,7 @@ TplName returns the name of the kubernetes resource as a template string. It is func TplValue(serviceName, variable string, pipes ...string) string ``` -TplValue returns a container by name and its index in the array. +TplValue returns a string that can be used in a template to access a value from the values file. ## func [Warn]() From 2307ad667e8fe4ca4b5cab846f398fab8c27e482 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Fri, 11 Jul 2025 09:17:33 +0200 Subject: [PATCH 08/14] chore(dev): changed how to test version - force release version check to use "v" (or not) as first character - one line condtion --- generator/version.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/generator/version.go b/generator/version.go index 310bbf2..309c955 100644 --- a/generator/version.go +++ b/generator/version.go @@ -13,15 +13,13 @@ var Version = "master" // changed at compile time // katneary using `go install`, the version should be different. func GetVersion() string { // try to get the semantic version from the Version variable (theorically set at compile time) - reg := regexp.MustCompile(`^(.?\d+.\d+.\d+.*)|^release-.*`) - if reg.MatchString(Version) { + if reg := regexp.MustCompile(`^v?\d+.\d+.\d+.*|^release-.*`); reg.MatchString(Version) { return Version } // OK... let's try to get the version from the build info // get the version from the build info (when installed with go install) - v, ok := debug.ReadBuildInfo() - if ok { + if v, ok := debug.ReadBuildInfo(); ok { return v.Main.Version + "-" + v.GoVersion } From a1c5161ff740403cc7953dec644d603907d0005f Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Sat, 12 Jul 2025 09:08:28 +0200 Subject: [PATCH 09/14] chore(package): Be able to sign RPM --- .gitignore | 3 +++ packaging/oci/Containerfile | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 6cbef35..1fda1d7 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ nsis/*.exe doc/share __pycache__ + +.rpmmacros +*.gpg diff --git a/packaging/oci/Containerfile b/packaging/oci/Containerfile index 6eaede0..3cc865d 100644 --- a/packaging/oci/Containerfile +++ b/packaging/oci/Containerfile @@ -1,13 +1,13 @@ FROM registry.fedoraproject.org/fedora:42 RUN set -eux; \ microdnf -y install \ - rubygems rpmbuild bsdtar mingw-nsis-base.x86_64 mingw32-nsis.noarch; \ + rubygems rpmbuild rpmsign bsdtar mingw-nsis-base.x86_64 mingw32-nsis.noarch gpg2; \ microdnf clean all; # create user with 999 UID/GID RUN set -eux; \ - groupadd -g 999 builder && \ - useradd -m -r -u 999 -g 999 -d /home/builder -s /bin/bash builder && \ + groupadd -g 1001 builder; \ + useradd -m -u 1001 -g 1001 -d /home/builder -s /bin/bash builder; \ chown builder:builder /home/builder USER builder From 39ebf7eb78c8c345d8a61cd87bd6f9a7cd5d002d Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Sat, 12 Jul 2025 09:08:41 +0200 Subject: [PATCH 10/14] chore(package): change description, add a final dot --- packaging/description | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/description b/packaging/description index 63c1b66..f3cbb89 100644 --- a/packaging/description +++ b/packaging/description @@ -1,4 +1,4 @@ Katenary transforms docker/podman compose files to Helm Charts. It harnesses the labels from your "compose" file to craft complete Helm Charts effortlessly, saving you time and energy. - Simple automated CLI: Katenary handles the grunt work, generating everything needed for seamless service binding and Helm Chart creation. -- Effortless Efficiency: You only need to add labels when it's necessary to precise things. Then call katenary convert and let the magic happen +- Effortless Efficiency: You only need to add labels when it's necessary to precise things. Then call katenary convert and let the magic happen. From 796cbb6d3001c448c43601f701e58d4f89a27118 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Sat, 12 Jul 2025 09:12:12 +0200 Subject: [PATCH 11/14] chore(package): Rewrite package targets - rewrite to make packages building more consistent - add rpm signature with GPG - auto test packages in several distributions to ensure the packages are OK Even if loops to build stuffs are sometimes easier to automate, it's simpler to fixup if some rules (targets) are explicitly defined. --- Makefile | 253 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 182 insertions(+), 71 deletions(-) diff --git a/Makefile b/Makefile index bccfe26..41279a5 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,9 @@ SHELL := bash .SHELLFLAGS := -eu -o pipefail -c .ONESHELL: .DELETE_ON_ERROR: +.PHONY: help dist-clean dist package build install test doc nsis MAKEFLAGS += --warn-undefined-variables MAKEFLAGS += --no-builtin-rules -.PHONY: help dist-clean dist package build install test doc nsis # Get a version string from git CUR_SHA=$(shell git log -n1 --pretty='%h') @@ -14,37 +14,48 @@ VERSION=$(shell git describe --exact-match --tags $(CUR_SHA) 2>/dev/null || echo # Go build command and environment variables for target OS and architecture GOVERSION=1.24 -GO=container # container, local +GO=container# container, local OUTPUT=katenary GOOS=linux GOARCH=amd64 CGO_ENABLED=0 PREFIX=~/.local -# Get the container (podman is preferred, but docker is also supported) + +warn-docker: + @echo -e "\033[1;31mWarning: Docker is not recommended, use Podman instead.\033[0m" + sleep 5 + +# Get the container (Podman is preferred, but docker can be used too. It may failed with Docker.) # TODO: prpose nerdctl CTN:=$(shell which podman 2>&1 1>/dev/null && echo "podman" || echo "docker") +ifeq ($(CTN),podman) + CTN_USERMAP=--userns=keep-id +else + $(MAKE) warn-docker + CTN_USERMAP=--user=$(shell id -u):$(shell id -g) -e HOME=/tmp +endif # Packaging OCI image, to build rpm, deb, pacman, tar packages +# We changes the keep-id uid/gid for Podman, so that the user inside the container is the same as the user outside. +# For Docker, as it doesn't support userns, we use common options, but it may fail... PKG_OCI_IMAGE=packaging:fedora -PKG_OCI_OPTS:=--rm -it \ - -w $$PKG_OCI_WDIR \ - -v ./:/opt/katenary:z \ - --userns keep-id:uid=999,gid=999 \ - $(PKG_OCI_IMAGE) - -# Set the version and package version, following build mode (default, release) -MODE=default -# If release mode -ifeq ($(MODE),release) - PKG_VERSION:=$(VERSION) - VERSION:=$(VERSION) +ifeq ($(CTN),podman) + # podman + PKG_OCI_OPTS:=--rm -it \ + -v ./:/opt/katenary:z \ + --userns keep-id:uid=1001,gid=1001 \ + $(PKG_OCI_IMAGE) else - PKG_VERSION=$(VERSION)# used for package name + # docker + PKG_OCI_OPTS:=--rm -it \ + -v ./:/opt/katenary:z \ + -e HOME=/tmp \ + $(CTN_USERMAP) \ + $(PKG_OCI_IMAGE) endif - -BLD_CMD=go build -ldflags="-X 'katenary/generator.Version=$(VERSION)'" -o $(OUTPUT) ./cmd/katenary +GO_BUILD=go build -ldflags="-X 'katenary/generator.Version=$(VERSION)'" -o $(OUTPUT) ./cmd/katenary # UPX compression @@ -56,8 +67,14 @@ BUILD_IMAGE=docker.io/golang:$(GOVERSION) # List of source files SOURCES=$(shell find -name "*.go" -or -name "*.tpl" -type f | grep -v -P "^./example|^./vendor") # List of binaries to build and sign -BINARIES=dist/katenary-linux-amd64 dist/katenary-linux-arm64 dist/katenary.exe dist/katenary-darwin-amd64 dist/katenary-freebsd-amd64 dist/katenary-freebsd-arm64 -BINARIES += dist/katenary-windows-setup.exe +BINARIES=\ + dist/katenary-linux-amd64\ + dist/katenary-linux-arm64\ + dist/katenary-darwin-amd64\ + dist/katenary-freebsd-amd64\ + dist/katenary-freebsd-arm64\ + dist/katenary.exe\ + dist/katenary-windows-setup.exe ## GPG # List of signatures to build @@ -68,13 +85,6 @@ SIGNER=metal3d@gmail.com # Browser command to see coverage report after tests BROWSER=$(shell command -v epiphany || echo xdg-open) -check-version: - @echo "=> Checking version..." - @echo "Mode: $(MODE)" - @echo "Current version: $(VERSION)" - @echo "Package version: $(PKG_VERSION)" - @echo "Build command: $(BLD_CMD)" - all: build help: @@ -125,63 +135,66 @@ ifneq ($(GO),local) @$(CTN) pull $(BUILD_IMAGE) endif -katenary: $(SOURCES) Makefile go.mod go.sum +katenary: $(SOURCES) go.mod go.sum ifeq ($(GO),local) @echo "=> Build on host using go" - $(BLD_CMD) -else ifeq ($(CTN),podman) - @echo "=> Build in container using" $(CTN) - @podman run -e CGO_ENABLED=$(CGO_ENABLED) -e GOOS=$(GOOS) -e GOARCH=$(GOARCH) \ - --rm -v $(PWD):/go/src/katenary:z -w /go/src/katenary --userns keep-id $(BUILD_IMAGE) $(BLD_CMD) + $(GO_BUILD) else @echo "=> Build in container using" $(CTN) - @docker run -e CGO_ENABLED=$(CGO_ENABLED) -e GOOS=$(GOOS) -e GOARCH=$(GOARCH) \ - --rm -v $(PWD):/go/src/katenary:z -w /go/src/katenary --user $(shell id -u):$(shell id -g) -e HOME=/tmp $(BUILD_IMAGE) $(BLD_CMD) + @$(CTN) run \ + -e CGO_ENABLED=$(CGO_ENABLED) \ + -e GOOS=$(GOOS) \ + -e GOARCH=$(GOARCH) \ + --rm -v $(PWD):/go/src/katenary:z \ + -w /go/src/katenary \ + -v ./.cache:/go/pkg/mod:z \ + $(CTN_USERMAP) \ + $(BUILD_IMAGE) $(GO_BUILD) endif # Make dist, build executables for all platforms, sign them, and compress them with upx if possible. # Also generate the windows installer. -dist: prepare $(BINARIES) upx gpg-sign check-sign packages +dist: prepare $(BINARIES) upx packages +dist-full: dist-clean dist gpg-sign check-sign rpm-sign check-dist-all -prepare: pull +prepare: pull packager-oci-image mkdir -p dist -dist/katenary-linux-amd64: $(SOURCES) Makefile go.mod go.sum +dist/katenary-linux-amd64: $(SOURCES) go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for linux-amd64...\033[0m" $(MAKE) katenary GOOS=linux GOARCH=amd64 OUTPUT=$@ strip $@ -dist/katenary-linux-arm64: $(SOURCES) Makefile go.mod go.sum +dist/katenary-linux-arm64: $(SOURCES) go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for linux-arm...\033[0m" $(MAKE) katenary GOOS=linux GOARCH=arm64 OUTPUT=$@ -dist/katenary.exe: $(SOURCES) Makefile go.mod go.sum +dist/katenary.exe: $(SOURCES) go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for windows...\033[0m" $(MAKE) katenary GOOS=windows GOARCH=amd64 OUTPUT=$@ -dist/katenary-darwin-amd64: $(SOURCES) Makefile go.mod go.sum +dist/katenary-darwin-amd64: $(SOURCES) go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for darwin...\033[0m" $(MAKE) katenary GOOS=darwin GOARCH=amd64 OUTPUT=$@ -dist/katenary-freebsd-amd64: $(SOURCES) Makefile go.mod go.sum +dist/katenary-freebsd-amd64: $(SOURCES) go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for freebsd...\033[0m" $(MAKE) katenary GOOS=freebsd GOARCH=amd64 OUTPUT=$@ strip $@ -dist/katenary-freebsd-arm64: $(SOURCES) Makefile go.mod go.sum +dist/katenary-freebsd-arm64: $(SOURCES) go.mod go.sum @echo @echo -e "\033[1;32mBuilding katenary $(VERSION) for freebsd-arm64...\033[0m" $(MAKE) katenary GOOS=freebsd GOARCH=arm64 OUTPUT=$@ -dist/katenary-windows-setup.exe: nsis/EnVar.dll dist/katenary.exe packager-oci-image $(SOURCES) Makefile go.mod go.sum - PKG_OCI_WDIR=/opt/katenary - podman run $(PKG_OCI_OPTS) \ +dist/katenary-windows-setup.exe: nsis/EnVar.dll dist/katenary.exe + @$(CTN) run -w /opt/katenary $(PKG_OCI_OPTS) \ makensis -DAPP_VERSION=$(VERSION) nsis/katenary.nsi mv nsis/katenary-windows-setup.exe dist/katenary-windows-setup.exe @@ -196,48 +209,101 @@ nsis/EnVar.dll: upx: dist/katenary-linux-amd64 dist/katenary-linux-arm64 dist/katenary-darwin-amd64 $(UPX) dist/katenary-linux-amd64 $(UPX) dist/katenary-linux-arm64 - #$(UPX) dist/katenary.exe $(UPX) dist/katenary-darwin-amd64 --force-macos ## Linux / FreeBSD packages DESCRIPTION := $(shell cat packaging/description | sed ':a;N;$$!ba;s/\n/\\n/g') - FPM_OPTS=--name katenary \ - --version $(PKG_VERSION) \ --url https://katenary.org \ --vendor "Katenary Project" \ --maintainer "Patrice Ferlet " \ --license "MIT" \ --description="$$(printf "$(DESCRIPTION)" | fold -s)" -FPM_COMMON_FILES=../doc/share/man/man1/katenary.1=/usr/local/share/man/man1/katenary.1 \ - ../LICENSE=/usr/local/share/doc/katenary/LICENSE \ - ../README.md=/usr/local/share/doc/katenary/README.md \ +# base files (doc...) +FPM_BASES=../LICENSE=/usr/local/share/doc/katenary/LICENSE \ + ../README.md=/usr/local/share/doc/katenary/README.md + +FPM_COMMON_FILES=$(FPM_BASES) ../doc/share/man/man1/katenary.1=/usr/local/share/man/man1/katenary.1 + +# ArchLinux has got inconsistent /usr/local/man directory +FPM_COMMON_FILES_ARCHLINUX=$(FPM_BASES) ../doc/share/man/man1/katenary.1=/usr/local/man/man1/katenary.1 \ + +# Pacman refuses dashes in version, and should start with a number +PACMAN_VERSION=$(shell echo $(VERSION) | sed 's/-/./g; s/^v//') + +define RPM_MACROS +%_signature gpg +%_gpg_path /home/builder/.gnupg +%_gpg_name $(SIGNER) +%_gpgbin /usr/bin/gpg2 +%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --no-secmem-warning -u "%{_gpg_name}" -sbo %{__signature_filename} --digest-algo sha256 %{__plaintext_filename}' +endef + +rpm: dist/katenary-linux-$(GOARCH) + @echo "==> Building RPM packages for $(GOARCH)..." + $(CTN) run -w /opt/katenary/dist $(PKG_OCI_OPTS) \ + fpm -s dir -t rpm -a $(GOARCH) -f $(FPM_OPTS) --version=$(VERSION) \ + $(FPM_COMMON_FILES) \ + ./katenary-linux-$(GOARCH)=/usr/local/bin/katenary +rpm-sign: + [ -f .rpmmacros ] || echo "$(RPM_MACROS)" > .rpmmacros + [ -f .secret.gpg ] || gpg --export-secret-keys -a $(SIGNER) > .secret.gpg + $(CTN) run -w /opt/katenary/dist \ + -v ./.secret.gpg:/home/builder/signer.gpg \ + -v packager-gpg:/home/builder/.gnupg \ + $(PKG_OCI_OPTS) \ + gpg --import /home/builder/signer.gpg + $(CTN) run -w /opt/katenary/dist \ + -v .rpmmacros:/home/builder/.rpmmacros:z \ + -v packager-gpg:/home/builder/.gnupg \ + $(PKG_OCI_OPTS) \ + bash -c 'for rpm in $$(find . -iname "*.rpm"); do echo signing: $$rpm; rpm --addsign $$rpm; done' + +deb: + @echo "==> Building DEB packages for $(GOARCH)..." + $(CTN) run -w /opt/katenary/dist $(PKG_OCI_OPTS) \ + fpm -s dir -t deb -a $(GOARCH) -f $(FPM_OPTS) --version=$(VERSION) \ + $(FPM_COMMON_FILES) \ + ./katenary-linux-$(GOARCH)=/usr/local/bin/katenary + +pacman: + @echo "==> Building Pacman packages for $(GOARCH)..." + $(CTN) run -w /opt/katenary/dist $(PKG_OCI_OPTS) \ + fpm -s dir -t pacman -a $(GOARCH) -f $(FPM_OPTS) --version=$(PACMAN_VERSION) \ + $(FPM_COMMON_FILES_ARCHLINUX) \ + ./katenary-linux-$(GOARCH)=/usr/local/bin/katenary + +freebsd: + @echo "==> Building FreeBSD packages for $(GOARCH)..." + $(CTN) run -w /opt/katenary/dist $(PKG_OCI_OPTS) \ + fpm -s dir -t freebsd -a $(GOARCH) -f $(FPM_OPTS) --version=$(VERSION)\ + $(FPM_COMMON_FILES) \ + ./katenary-freebsd-$(GOARCH)=/usr/local/bin/katenary + mv dist/katenary-$(VERSION).txz dist/katenary-freebsd-$(VERSION).$(GOARCH).txz + +tar: + @echo "==> Building TAR packages for $(GOOS) $(GOARCH)..." + $(CTN) run -w /opt/katenary/dist $(PKG_OCI_OPTS) \ + fpm -s dir -t tar -a $(GOARCH) -f $(FPM_OPTS) \ + $(FPM_COMMON_FILES) \ + ./katenary-$(GOOS)-$(GOARCH)=/usr/local/bin/katenary + mv dist/katenary.tar dist/katenary-$(GOOS)-$(VERSION).$(GOARCH).tar packages: manpage packager-oci-image - @PKG_OCI_WDIR=/opt/katenary/dist for arch in amd64 arm64; do \ - for target in rpm deb pacman tar; do \ - echo "==> Building $$target package for arch $$arch..."; \ - podman run $(PKG_OCI_OPTS) fpm -s dir -t $$target -a $$arch -f $(FPM_OPTS) \ - $(FPM_COMMON_FILES) \ - ./katenary-linux-$$arch=/usr/local/bin/katenary; \ - done - mv dist/katenary.tar dist/katenary-linux-$(PKG_VERSION).$$arch.tar - for target in freebsd tar; do \ - echo "==> Building $$target package for arch $$arch"; \ - podman run $(PKG_OCI_OPTS) fpm -s dir -t $$target -a $$arch -f $(FPM_OPTS) \ - $(FPM_COMMON_FILES) \ - ./katenary-freebsd-$$arch=/usr/local/bin/katenary; - done - mv dist/katenary-$(PKG_VERSION).txz dist/katenary-$(PKG_VERSION).$$arch.txz - mv dist/katenary.tar dist/katenary-freebsd-$(PKG_VERSION).$$arch.tar + $(MAKE) rpm GOARCH=$$arch; \ + $(MAKE) deb GOARCH=$$arch; \ + $(MAKE) pacman GOARCH=$$arch; \ + $(MAKE) freebsd GOARCH=$$arch; \ + $(MAKE) tar GOARCH=$$arch GOOS=linux; \ + $(MAKE) tar GOARCH=$$arch GOOS=freebsd; \ done packager-oci-image: - @podman build -t packaging:fedora ./packaging/oci 1>/dev/null + @$(CTN) build -t packaging:fedora ./packaging/oci 1>/dev/null ## GPG signing @@ -260,6 +326,52 @@ dist/%.asc: dist/% gpg --armor --detach-sign --default-key $(SIGNER) $< &>/dev/null || exit 1 +check-dist-rocky: + @echo "=> Checking Rocky Linux package..." + p=$(wildcard dist/*x86_64.rpm); + $(CTN) run --rm -it -v ./dist:/opt:z quay.io/rockylinux/rockylinux:latest bash -c " + rpm -ivh /opt/$$(basename $$p); + katenary version; + " + +check-dist-fedora: + @echo "=> Checking Fedora package..." + p=$(wildcard dist/*x86_64.rpm); + $(CTN) run --rm -it -v ./dist:/opt:z quay.io/fedora/fedora:latest bash -c " + rpm -ivh /opt/$$(basename $$p); + katenary version; + " + +check-dist-archlinux: + echo "=> Checking ArchLinux package..." + p=$(wildcard dist/*x86_64.pkg.tar.zst); + $(CTN) run --rm -it -v ./dist:/opt:z quay.io/archlinux/archlinux bash -c " + pacman -U /opt/$$(basename $$p) --noconfirm; + katenary version; + " + +check-dist-debian: + @echo "=> Checking Debian package..." + p=$(wildcard dist/*amd64.deb); + $(CTN) run --rm -it -v ./dist:/opt:z debian:latest bash -c " + dpkg -i /opt/$$(basename $$p); + katenary version; + " +check-dist-ubuntu: + @echo "=> Checking Ubuntu package..." + p=$(wildcard dist/*amd64.deb); + $(CTN) run --rm -it -v ./dist:/opt:z ubuntu:latest bash -c " + dpkg -i /opt/$$(basename $$p); + katenary version; + " + +check-dist-all: + $(MAKE) check-dist-fedora + $(MAKE) check-dist-rocky + $(MAKE) check-dist-debian + $(MAKE) check-dist-ubuntu + $(MAKE) check-dist-archlinux + ## installation and uninstallation install: build @@ -268,8 +380,7 @@ install: build uninstall: rm -f $(PREFIX)/bin/katenary - -serve-doc: __label_doc +serve-doc: doc @cd doc && \ [ -d venv ] || python -m venv venv; \ source venv/bin/activate && \ From 5f5cd0268a627e3bd72d5ef140159fe5982a8a32 Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Sun, 13 Jul 2025 00:07:07 +0200 Subject: [PATCH 12/14] fix(deployment): Missed the command from compose file Fixes #133 --- generator/deployment.go | 1 + generator/deployment_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/generator/deployment.go b/generator/deployment.go index 2345882..0e8fafb 100644 --- a/generator/deployment.go +++ b/generator/deployment.go @@ -136,6 +136,7 @@ func (d *Deployment) AddContainer(service types.ServiceConfig) { Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{}, }, + Command: service.Command, } if _, ok := d.chart.Values[service.Name]; !ok { d.chart.Values[service.Name] = NewValue(service, d.isMainApp) diff --git a/generator/deployment_test.go b/generator/deployment_test.go index d9e3f97..6139629 100644 --- a/generator/deployment_test.go +++ b/generator/deployment_test.go @@ -495,3 +495,39 @@ services: t.Errorf("Expected valueFrom to be set") } } + +func TestCheckCommand(t *testing.T) { + composeFile := ` +services: + web-app: + image: nginx:1.29 + command: + - sh + - -c + - |- + echo "Hello, World!" + echo "Done" +` + + // composeFile = fmt.Sprintf(composeFile, labels.Prefix()) + tmpDir := setup(composeFile) + defer teardown(tmpDir) + + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + output := internalCompileTest(t, "-s", "templates/web_app/deployment.yaml") + dt := v1.Deployment{} + if err := yaml.Unmarshal([]byte(output), &dt); err != nil { + t.Errorf(unmarshalError, err) + } + // find the command in the container + command := dt.Spec.Template.Spec.Containers[0].Command + if len(command) != 3 { + t.Errorf("Expected command to have 3 elements, got %d", len(command)) + } + if command[0] != "sh" || command[1] != "-c" { + t.Errorf("Expected command to be 'sh -c', got %s", strings.Join(command, " ")) + } +} From c4e406f855f5e308f40a581b872c1a85fddba26f Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Sun, 13 Jul 2025 00:17:48 +0200 Subject: [PATCH 13/14] chore(moving): Moved repository to organization --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 0af6081..54a12c0 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module katenary // github.com/metal3d/katenary +module katenary // github.com/katenay/katenary go 1.24.0 From a290219c81ea3873c85304580d80b313c4e0573c Mon Sep 17 00:00:00 2001 From: Patrice Ferlet Date: Sun, 13 Jul 2025 00:19:02 +0200 Subject: [PATCH 14/14] chore(licence): I prefer to mention the project --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 5a01268..d15fdf4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022-2025 Patrice Ferlet (aka metal3d) +Copyright (c) 2022-2025 The Katenary authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal