From 576557f9cb708524f7a2cb0a8446cb0dcedcdecd Mon Sep 17 00:00:00 2001 From: Rich Braun Date: Tue, 11 Aug 2026 12:36:53 -0700 Subject: [PATCH 01/10] SYS-696 docker hub readme --- .gitlab-ci.yml | 450 ++++++++++++++++---------------- .image-gitlab-ci.yml | 6 +- lib/build/Makefile.docker_image | 9 +- 3 files changed, 233 insertions(+), 232 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e2b8dbfb..e1470e13 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,31 +3,31 @@ stages: - prepare - git-dump - - blacklist - - data-sync - - ddclient - - dhcpd-dns-pxe - - dovecot - - ez-ipupdate - - git-pull - - haproxy-keepalived - - mariadb-galera - - mysqldump - - mythtv-backend - - nagios - - nagiosql - - nut-upsd - - openldap - - postfix - - postfix-python - - proftpd - - rsyslogd - - samba - - samba-dc - - spamassassin - - udp-nginx-proxy - - vsftpd - - weewx + # - blacklist + # - data-sync + # - ddclient + # - dhcpd-dns-pxe + # - dovecot + # - ez-ipupdate + # - git-pull + # - haproxy-keepalived + # - mariadb-galera + # - mysqldump + # - mythtv-backend + # - nagios + # - nagiosql + # - nut-upsd + # - openldap + # - postfix + # - postfix-python + # - proftpd + # - rsyslogd + # - samba + # - samba-dc + # - spamassassin + # - udp-nginx-proxy + # - vsftpd + # - weewx workflow: rules: - { if: $CI_COMMIT_TAG =~ /^chart-.*/, when: never } @@ -64,227 +64,227 @@ smoketest: # TODO figure out a way to collect all child pipeline results strategy: depend -blacklist: - stage: blacklist - trigger: - include: - - artifact: .child-blacklist.yml - job: prepare - only: - changes: [ images/blacklist/**, lib/**, .image-gitlab-ci.yml ] +# blacklist: +# stage: blacklist +# trigger: +# include: +# - artifact: .child-blacklist.yml +# job: prepare +# only: +# changes: [ images/blacklist/**, lib/**, .image-gitlab-ci.yml ] -data-sync: - stage: data-sync - trigger: - include: - - artifact: .child-data-sync.yml - job: prepare - only: - changes: [ images/data-sync/**, lib/**, .image-gitlab-ci.yml ] +# data-sync: +# stage: data-sync +# trigger: +# include: +# - artifact: .child-data-sync.yml +# job: prepare +# only: +# changes: [ images/data-sync/**, lib/**, .image-gitlab-ci.yml ] -ddclient: - stage: ddclient - trigger: - include: - - artifact: .child-ddclient.yml - job: prepare - only: - changes: [ images/ddclient/**, lib/**, .image-gitlab-ci.yml ] +# ddclient: +# stage: ddclient +# trigger: +# include: +# - artifact: .child-ddclient.yml +# job: prepare +# only: +# changes: [ images/ddclient/**, lib/**, .image-gitlab-ci.yml ] -dhcpd-dns-pxe: - stage: dhcpd-dns-pxe - trigger: - include: - - artifact: .child-dhcpd-dns-pxe.yml - job: prepare - only: - changes: [ images/dhcpd-dns-pxe/**, lib/**, .image-gitlab-ci.yml ] +# dhcpd-dns-pxe: +# stage: dhcpd-dns-pxe +# trigger: +# include: +# - artifact: .child-dhcpd-dns-pxe.yml +# job: prepare +# only: +# changes: [ images/dhcpd-dns-pxe/**, lib/**, .image-gitlab-ci.yml ] -dovecot: - stage: dovecot - trigger: - include: - - artifact: .child-dovecot.yml - job: prepare - only: - changes: [ images/dovecot/**, lib/**, .image-gitlab-ci.yml ] +# dovecot: +# stage: dovecot +# trigger: +# include: +# - artifact: .child-dovecot.yml +# job: prepare +# only: +# changes: [ images/dovecot/**, lib/**, .image-gitlab-ci.yml ] -ez-ipupdate: - stage: ez-ipupdate - trigger: - include: - - artifact: .child-ez-ipupdate.yml - job: prepare - only: - changes: [ images/ez-ipupdate/**, lib/**, .image-gitlab-ci.yml ] +# ez-ipupdate: +# stage: ez-ipupdate +# trigger: +# include: +# - artifact: .child-ez-ipupdate.yml +# job: prepare +# only: +# changes: [ images/ez-ipupdate/**, lib/**, .image-gitlab-ci.yml ] -git-pull: - stage: git-pull - trigger: - include: - - artifact: .child-git-pull.yml - job: prepare - only: - changes: [ images/git-pull/**, lib/**, .image-gitlab-ci.yml ] +# git-pull: +# stage: git-pull +# trigger: +# include: +# - artifact: .child-git-pull.yml +# job: prepare +# only: +# changes: [ images/git-pull/**, lib/**, .image-gitlab-ci.yml ] -haproxy-keepalived: - stage: haproxy-keepalived - trigger: - include: - - artifact: .child-haproxy-keepalived.yml - job: prepare - only: - changes: [ images/haproxy-keepalived/**, lib/**, .image-gitlab-ci.yml ] +# haproxy-keepalived: +# stage: haproxy-keepalived +# trigger: +# include: +# - artifact: .child-haproxy-keepalived.yml +# job: prepare +# only: +# changes: [ images/haproxy-keepalived/**, lib/**, .image-gitlab-ci.yml ] -mariadb-galera: - stage: mariadb-galera - trigger: - include: - - artifact: .child-mariadb-galera.yml - job: prepare - only: - changes: [ images/mariadb-galera/**, lib/**, .image-gitlab-ci.yml ] +# mariadb-galera: +# stage: mariadb-galera +# trigger: +# include: +# - artifact: .child-mariadb-galera.yml +# job: prepare +# only: +# changes: [ images/mariadb-galera/**, lib/**, .image-gitlab-ci.yml ] -mysqldump: - stage: mysqldump - trigger: - include: - - artifact: .child-mysqldump.yml - job: prepare - only: - changes: [ images/mysqldump/**, lib/**, .image-gitlab-ci.yml ] +# mysqldump: +# stage: mysqldump +# trigger: +# include: +# - artifact: .child-mysqldump.yml +# job: prepare +# only: +# changes: [ images/mysqldump/**, lib/**, .image-gitlab-ci.yml ] -mythtv-backend: - stage: mythtv-backend - trigger: - include: - - artifact: .child-mythtv-backend.yml - job: prepare - only: - changes: [ images/mythtv-backend/**, lib/**, .image-gitlab-ci.yml ] +# mythtv-backend: +# stage: mythtv-backend +# trigger: +# include: +# - artifact: .child-mythtv-backend.yml +# job: prepare +# only: +# changes: [ images/mythtv-backend/**, lib/**, .image-gitlab-ci.yml ] -nagios: - stage: nagios - trigger: - include: - - artifact: .child-nagios.yml - job: prepare - only: - changes: [ images/nagios/**, lib/**, .image-gitlab-ci.yml ] +# nagios: +# stage: nagios +# trigger: +# include: +# - artifact: .child-nagios.yml +# job: prepare +# only: +# changes: [ images/nagios/**, lib/**, .image-gitlab-ci.yml ] -nagiosql: - stage: nagiosql - trigger: - include: - - artifact: .child-nagiosql.yml - job: prepare - only: - changes: [ images/nagiosql/**, lib/**, .image-gitlab-ci.yml ] +# nagiosql: +# stage: nagiosql +# trigger: +# include: +# - artifact: .child-nagiosql.yml +# job: prepare +# only: +# changes: [ images/nagiosql/**, lib/**, .image-gitlab-ci.yml ] -nut-upsd: - stage: nut-upsd - trigger: - include: - - artifact: .child-nut-upsd.yml - job: prepare - only: - changes: [ images/nut-upsd/**, lib/**, .image-gitlab-ci.yml ] +# nut-upsd: +# stage: nut-upsd +# trigger: +# include: +# - artifact: .child-nut-upsd.yml +# job: prepare +# only: +# changes: [ images/nut-upsd/**, lib/**, .image-gitlab-ci.yml ] -postfix: - stage: postfix - trigger: - include: - - artifact: .child-postfix.yml - job: prepare - only: - changes: [ images/postfix/**, lib/**, .image-gitlab-ci.yml ] +# postfix: +# stage: postfix +# trigger: +# include: +# - artifact: .child-postfix.yml +# job: prepare +# only: +# changes: [ images/postfix/**, lib/**, .image-gitlab-ci.yml ] -openldap: - stage: openldap - trigger: - include: - - artifact: .child-openldap.yml - job: prepare - only: - changes: [ images/openldap/**, lib/**, .image-gitlab-ci.yml ] +# openldap: +# stage: openldap +# trigger: +# include: +# - artifact: .child-openldap.yml +# job: prepare +# only: +# changes: [ images/openldap/**, lib/**, .image-gitlab-ci.yml ] -postfix-python: - stage: postfix-python - trigger: - include: - - artifact: .child-postfix-python.yml - job: prepare - only: - changes: [ images/postfix-python/**, lib/**, .image-gitlab-ci.yml ] +# postfix-python: +# stage: postfix-python +# trigger: +# include: +# - artifact: .child-postfix-python.yml +# job: prepare +# only: +# changes: [ images/postfix-python/**, lib/**, .image-gitlab-ci.yml ] -proftpd: - stage: proftpd - trigger: - include: - - artifact: .child-proftpd.yml - job: prepare - only: - changes: [ images/proftpd/**, lib/**, .image-gitlab-ci.yml ] +# proftpd: +# stage: proftpd +# trigger: +# include: +# - artifact: .child-proftpd.yml +# job: prepare +# only: +# changes: [ images/proftpd/**, lib/**, .image-gitlab-ci.yml ] -rsyslogd: - stage: rsyslogd - trigger: - include: - - artifact: .child-rsyslogd.yml - job: prepare - only: - changes: [ images/rsyslogd/**, lib/**, .image-gitlab-ci.yml ] +# rsyslogd: +# stage: rsyslogd +# trigger: +# include: +# - artifact: .child-rsyslogd.yml +# job: prepare +# only: +# changes: [ images/rsyslogd/**, lib/**, .image-gitlab-ci.yml ] -samba: - stage: samba - trigger: - include: - - artifact: .child-samba.yml - job: prepare - only: - changes: [ images/samba/**, lib/**, .image-gitlab-ci.yml ] +# samba: +# stage: samba +# trigger: +# include: +# - artifact: .child-samba.yml +# job: prepare +# only: +# changes: [ images/samba/**, lib/**, .image-gitlab-ci.yml ] -samba-dc: - stage: samba-dc - trigger: - include: - - artifact: .child-samba-dc.yml - job: prepare - only: - changes: [ images/samba-dc/**, lib/**, .image-gitlab-ci.yml ] +# samba-dc: +# stage: samba-dc +# trigger: +# include: +# - artifact: .child-samba-dc.yml +# job: prepare +# only: +# changes: [ images/samba-dc/**, lib/**, .image-gitlab-ci.yml ] -spamassassin: - stage: spamassassin - trigger: - include: - - artifact: .child-spamassassin.yml - job: prepare - only: - changes: [ images/spamassassin/**, lib/**, .image-gitlab-ci.yml ] +# spamassassin: +# stage: spamassassin +# trigger: +# include: +# - artifact: .child-spamassassin.yml +# job: prepare +# only: +# changes: [ images/spamassassin/**, lib/**, .image-gitlab-ci.yml ] -udp-nginx-proxy: - stage: udp-nginx-proxy - trigger: - include: - - artifact: .child-udp-nginx-proxy.yml - job: prepare - only: - changes: [ images/udp-nginx-proxy/**, lib/**, .image-gitlab-ci.yml ] +# udp-nginx-proxy: +# stage: udp-nginx-proxy +# trigger: +# include: +# - artifact: .child-udp-nginx-proxy.yml +# job: prepare +# only: +# changes: [ images/udp-nginx-proxy/**, lib/**, .image-gitlab-ci.yml ] -vsftpd: - stage: vsftpd - trigger: - include: - - artifact: .child-vsftpd.yml - job: prepare - only: - changes: [ images/vsftpd/**, lib/**, .image-gitlab-ci.yml ] +# vsftpd: +# stage: vsftpd +# trigger: +# include: +# - artifact: .child-vsftpd.yml +# job: prepare +# only: +# changes: [ images/vsftpd/**, lib/**, .image-gitlab-ci.yml ] -weewx: - stage: weewx - trigger: - include: - - artifact: .child-weewx.yml - job: prepare - only: - changes: [ images/weewx/**, lib/**, .image-gitlab-ci.yml ] +# weewx: +# stage: weewx +# trigger: +# include: +# - artifact: .child-weewx.yml +# job: prepare +# only: +# changes: [ images/weewx/**, lib/**, .image-gitlab-ci.yml ] diff --git a/.image-gitlab-ci.yml b/.image-gitlab-ci.yml index 0c2e2939..fc8eb78b 100644 --- a/.image-gitlab-ci.yml +++ b/.image-gitlab-ci.yml @@ -87,6 +87,6 @@ promote_image: <<: *registry_login script: apk add curl jq make && cd images/$IMAGE && make promote_image interruptible: true - only: - refs: [ main, tags ] - variables: [ $REGISTRY_URI == "registry.gitlab.com" ] + # only: + # refs: [ main, tags ] + # variables: [ $REGISTRY_URI == "registry.gitlab.com" ] diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 67c522eb..2327a45a 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -73,14 +73,15 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx --build-arg=BUILD_DATE=$(shell date +%Y-%m-%dT%H:%M:%SZ) # update dockerhub README + ls -l /usr/bin/jq [ -s /usr/bin/jq ] || apk add jq - @JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ - '{username: $user, password: $pwd}') - @JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ + JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ + '{username: $$user, password: $$pwd}') + JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ -d "$$JSON" https://hub.docker.com/v2/users/login/ |jq -r .token) # Build JSON payload securely and send PATCH request # jq --arg escapes special characters / newlines in markdown text - RESP=$$(jq -n --arg desc "$( Date: Tue, 11 Aug 2026 13:00:58 -0700 Subject: [PATCH 02/10] SYS-696 wip --- lib/build/Makefile.docker_image | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 2327a45a..a366712a 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -73,19 +73,18 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx --build-arg=BUILD_DATE=$(shell date +%Y-%m-%dT%H:%M:%SZ) # update dockerhub README - ls -l /usr/bin/jq - [ -s /usr/bin/jq ] || apk add jq - JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ + @JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ '{username: $$user, password: $$pwd}') - JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ + @JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ -d "$$JSON" https://hub.docker.com/v2/users/login/ |jq -r .token) + echo $$JWT # Build JSON payload securely and send PATCH request # jq --arg escapes special characters / newlines in markdown text - RESP=$$(jq -n --arg desc "$( Date: Tue, 11 Aug 2026 13:08:51 -0700 Subject: [PATCH 03/10] SYS-696 wip --- lib/build/Makefile.docker_image | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index a366712a..62abd55d 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -73,10 +73,12 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx --build-arg=BUILD_DATE=$(shell date +%Y-%m-%dT%H:%M:%SZ) # update dockerhub README - @JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ + echo Commencing hub readme task + JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ '{username: $$user, password: $$pwd}') - @JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ - -d "$$JSON" https://hub.docker.com/v2/users/login/ |jq -r .token) + echo $$JSON + JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ + -d "$$JSON" https://hub.docker.com/v2/users/login/ | jq -r .token) echo $$JWT # Build JSON payload securely and send PATCH request # jq --arg escapes special characters / newlines in markdown text From 19eb3df99c190a48cf2e09d753d8650bb6194a7e Mon Sep 17 00:00:00 2001 From: Rich Braun Date: Tue, 11 Aug 2026 13:26:21 -0700 Subject: [PATCH 04/10] SYS-696 wip --- .image-gitlab-ci.yml | 104 ++++++++++++++++---------------- lib/build/Makefile.docker_image | 7 +-- 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/.image-gitlab-ci.yml b/.image-gitlab-ci.yml index fc8eb78b..1d72e731 100644 --- a/.image-gitlab-ci.yml +++ b/.image-gitlab-ci.yml @@ -8,9 +8,9 @@ variables: stages: - Static Code Analysis - - Create Image + # - Create Image - Functional Tests - - Security Scan + # - Security Scan - Promote Image image: docker:29.7.2 @@ -26,61 +26,61 @@ analysis: image: instantlinux/python-builder:latest script: cd images/$IMAGE && make analysis -create_image: - <<: *registry_login - stage: Create Image - script: apk add make && cd images/$IMAGE && make create_image - services: [ { name: "docker:dind", command: ["--experimental"] } ] +# create_image: +# <<: *registry_login +# stage: Create Image +# script: apk add make && cd images/$IMAGE && make create_image +# services: [ { name: "docker:dind", command: ["--experimental"] } ] test: stage: Functional Tests script: apk add make && cd images/$IMAGE && make test_functional -security_scan_trivy: - services: [ "docker:dind" ] - image: - name: aquasec/trivy:$TRIVY_VERSION - entrypoint: [""] - stage: Security Scan - variables: - GIT_STRATEGY: none - TRIVY_CACHE_DIR: .trivycache/ - TRIVY_DEBUG: "true" - TRIVY_EXIT_CODE: 1 - TRIVY_FORMAT: json - TRIVY_IGNORE: >- - CVE-2023-52425,CVE-2024-8176, - CVE-2025-9900, - # CVE-2025-9900 is for mythtv-backend - TRIVY_OUTPUT: gl-container-scanning-report.json - TRIVY_SEVERITY: HIGH,CRITICAL - TRIVY_PKG_TYPES: os,library - script: - - export TAG=bld_$CI_PIPELINE_IID_${CI_COMMIT_SHORT_SHA} - # Trivy alerts on unfixed vulnerabilities in debian images - - > - if [ $IMAGE = blacklist ] || [ $IMAGE = spamassassin ]; then - IGN_FLAG=--ignore-unfixed ; - fi - - trivy clean --all - - trivy image --download-db-only --no-progress - - trivy image "${REGISTRY}/${IMAGE}:${TAG}" --severity LOW,MEDIUM - --exit-code 0 --format table --output medium-vulns.txt - - cat medium-vulns.txt - - echo $TRIVY_IGNORE | tr , "\n" | tee .trivyignore - - trivy image $IGN_FLAG "${REGISTRY}/${IMAGE}:${TAG}" - cache: - paths: [ .trivycache ] - interruptible: true - retry: - max: 2 - when: [ runner_system_failure, stuck_or_timeout_failure ] - timeout: 5m - artifacts: - reports: - container_scanning: gl-container-scanning-report.json - expire_in: 30 days - paths: [ medium-vulns.txt ] +# security_scan_trivy: +# services: [ "docker:dind" ] +# image: +# name: aquasec/trivy:$TRIVY_VERSION +# entrypoint: [""] +# stage: Security Scan +# variables: +# GIT_STRATEGY: none +# TRIVY_CACHE_DIR: .trivycache/ +# TRIVY_DEBUG: "true" +# TRIVY_EXIT_CODE: 1 +# TRIVY_FORMAT: json +# TRIVY_IGNORE: >- +# CVE-2023-52425,CVE-2024-8176, +# CVE-2025-9900, +# # CVE-2025-9900 is for mythtv-backend +# TRIVY_OUTPUT: gl-container-scanning-report.json +# TRIVY_SEVERITY: HIGH,CRITICAL +# TRIVY_PKG_TYPES: os,library +# script: +# - export TAG=bld_$CI_PIPELINE_IID_${CI_COMMIT_SHORT_SHA} +# # Trivy alerts on unfixed vulnerabilities in debian images +# - > +# if [ $IMAGE = blacklist ] || [ $IMAGE = spamassassin ]; then +# IGN_FLAG=--ignore-unfixed ; +# fi +# - trivy clean --all +# - trivy image --download-db-only --no-progress +# - trivy image "${REGISTRY}/${IMAGE}:${TAG}" --severity LOW,MEDIUM +# --exit-code 0 --format table --output medium-vulns.txt +# - cat medium-vulns.txt +# - echo $TRIVY_IGNORE | tr , "\n" | tee .trivyignore +# - trivy image $IGN_FLAG "${REGISTRY}/${IMAGE}:${TAG}" +# cache: +# paths: [ .trivycache ] +# interruptible: true +# retry: +# max: 2 +# when: [ runner_system_failure, stuck_or_timeout_failure ] +# timeout: 5m +# artifacts: +# reports: +# container_scanning: gl-container-scanning-report.json +# expire_in: 30 days +# paths: [ medium-vulns.txt ] promote_image: stage: Promote Image diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 62abd55d..2052f9df 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -75,11 +75,10 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx # update dockerhub README echo Commencing hub readme task JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ - '{username: $$user, password: $$pwd}') - echo $$JSON + '{username: $$user, password: $$pwd}') && \ JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ - -d "$$JSON" https://hub.docker.com/v2/users/login/ | jq -r .token) - echo $$JWT + -d "$$JSON" https://hub.docker.com/v2/users/login/ | jq -r .token) && \ + echo "$$JWT" # Build JSON payload securely and send PATCH request # jq --arg escapes special characters / newlines in markdown text RESP=$$(jq -n --arg desc "$$( Date: Tue, 11 Aug 2026 13:30:46 -0700 Subject: [PATCH 05/10] SYS-696 wip --- lib/build/Makefile.docker_image | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 2052f9df..275a8e9d 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -73,19 +73,17 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx --build-arg=BUILD_DATE=$(shell date +%Y-%m-%dT%H:%M:%SZ) # update dockerhub README - echo Commencing hub readme task + # jq --arg escapes special characters / newlines JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ '{username: $$user, password: $$pwd}') && \ JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ -d "$$JSON" https://hub.docker.com/v2/users/login/ | jq -r .token) && \ - echo "$$JWT" - # Build JSON payload securely and send PATCH request - # jq --arg escapes special characters / newlines in markdown text + # Build JSON payload, send PATCH request RESP=$$(jq -n --arg desc "$$( Date: Tue, 11 Aug 2026 14:07:20 -0700 Subject: [PATCH 06/10] SYS-696 wip --- lib/build/Makefile.docker_image | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 275a8e9d..34a933a6 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -79,11 +79,13 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ -d "$$JSON" https://hub.docker.com/v2/users/login/ | jq -r .token) && \ # Build JSON payload, send PATCH request + echo "$$JWT" && \ RESP=$$(jq -n --arg desc "$$( Date: Tue, 11 Aug 2026 14:14:45 -0700 Subject: [PATCH 07/10] SYS-696 wip --- lib/build/Makefile.docker_image | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 34a933a6..5e6e65e0 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -79,13 +79,11 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ -d "$$JSON" https://hub.docker.com/v2/users/login/ | jq -r .token) && \ # Build JSON payload, send PATCH request - echo "$$JWT" && \ - RESP=$$(jq -n --arg desc "$$( Date: Tue, 11 Aug 2026 14:25:07 -0700 Subject: [PATCH 08/10] SYS-696 wip --- lib/build/Makefile.docker_image | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 5e6e65e0..2c65a8ba 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -74,17 +74,19 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx # update dockerhub README # jq --arg escapes special characters / newlines + pwd && ls -l README.md JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ '{username: $$user, password: $$pwd}') && \ JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ -d "$$JSON" https://hub.docker.com/v2/users/login/ | jq -r .token) && \ - # Build JSON payload, send PATCH request + echo "$$JWT" RESP=$$(jq -n --rawfile desc README.md '{"full_description": $$desc}' | \ curl -s -o /dev/null -w "%{http_code}" -X PATCH \ -H "Content-Type: application/json" \ - -H "Authorization: JWT $$JWT" \ + -H "Authorization: JWT xxx" \ -d @- https://hub.docker.com/v2/repositories/$(IMAGE_REPO)/) && \ [ "$$RESP" -eq 200 ] || exit 1 + # Build JSON payload, send PATCH request flake8: test_requirements @echo "Running flake8 code analysis" From e35fd92c22d97d3c1080fffc45f381d5b14ecd45 Mon Sep 17 00:00:00 2001 From: Rich Braun Date: Tue, 11 Aug 2026 14:32:28 -0700 Subject: [PATCH 09/10] SYS-696 wip --- lib/build/Makefile.docker_image | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 2c65a8ba..5515cd33 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -79,11 +79,10 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx '{username: $$user, password: $$pwd}') && \ JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ -d "$$JSON" https://hub.docker.com/v2/users/login/ | jq -r .token) && \ - echo "$$JWT" RESP=$$(jq -n --rawfile desc README.md '{"full_description": $$desc}' | \ curl -s -o /dev/null -w "%{http_code}" -X PATCH \ -H "Content-Type: application/json" \ - -H "Authorization: JWT xxx" \ + -H "Authorization: Bearer $$JWT" \ -d @- https://hub.docker.com/v2/repositories/$(IMAGE_REPO)/) && \ [ "$$RESP" -eq 200 ] || exit 1 # Build JSON payload, send PATCH request From 28de488f4d2f765a11d30a1a0db29539b67b1732 Mon Sep 17 00:00:00 2001 From: Rich Braun Date: Tue, 11 Aug 2026 14:42:08 -0700 Subject: [PATCH 10/10] SYS-696 wip --- .gitlab-ci.yml | 450 ++++++++++++++++---------------- .image-gitlab-ci.yml | 110 ++++---- lib/build/Makefile.docker_image | 4 +- 3 files changed, 281 insertions(+), 283 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e1470e13..e2b8dbfb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,31 +3,31 @@ stages: - prepare - git-dump - # - blacklist - # - data-sync - # - ddclient - # - dhcpd-dns-pxe - # - dovecot - # - ez-ipupdate - # - git-pull - # - haproxy-keepalived - # - mariadb-galera - # - mysqldump - # - mythtv-backend - # - nagios - # - nagiosql - # - nut-upsd - # - openldap - # - postfix - # - postfix-python - # - proftpd - # - rsyslogd - # - samba - # - samba-dc - # - spamassassin - # - udp-nginx-proxy - # - vsftpd - # - weewx + - blacklist + - data-sync + - ddclient + - dhcpd-dns-pxe + - dovecot + - ez-ipupdate + - git-pull + - haproxy-keepalived + - mariadb-galera + - mysqldump + - mythtv-backend + - nagios + - nagiosql + - nut-upsd + - openldap + - postfix + - postfix-python + - proftpd + - rsyslogd + - samba + - samba-dc + - spamassassin + - udp-nginx-proxy + - vsftpd + - weewx workflow: rules: - { if: $CI_COMMIT_TAG =~ /^chart-.*/, when: never } @@ -64,227 +64,227 @@ smoketest: # TODO figure out a way to collect all child pipeline results strategy: depend -# blacklist: -# stage: blacklist -# trigger: -# include: -# - artifact: .child-blacklist.yml -# job: prepare -# only: -# changes: [ images/blacklist/**, lib/**, .image-gitlab-ci.yml ] +blacklist: + stage: blacklist + trigger: + include: + - artifact: .child-blacklist.yml + job: prepare + only: + changes: [ images/blacklist/**, lib/**, .image-gitlab-ci.yml ] -# data-sync: -# stage: data-sync -# trigger: -# include: -# - artifact: .child-data-sync.yml -# job: prepare -# only: -# changes: [ images/data-sync/**, lib/**, .image-gitlab-ci.yml ] +data-sync: + stage: data-sync + trigger: + include: + - artifact: .child-data-sync.yml + job: prepare + only: + changes: [ images/data-sync/**, lib/**, .image-gitlab-ci.yml ] -# ddclient: -# stage: ddclient -# trigger: -# include: -# - artifact: .child-ddclient.yml -# job: prepare -# only: -# changes: [ images/ddclient/**, lib/**, .image-gitlab-ci.yml ] +ddclient: + stage: ddclient + trigger: + include: + - artifact: .child-ddclient.yml + job: prepare + only: + changes: [ images/ddclient/**, lib/**, .image-gitlab-ci.yml ] -# dhcpd-dns-pxe: -# stage: dhcpd-dns-pxe -# trigger: -# include: -# - artifact: .child-dhcpd-dns-pxe.yml -# job: prepare -# only: -# changes: [ images/dhcpd-dns-pxe/**, lib/**, .image-gitlab-ci.yml ] +dhcpd-dns-pxe: + stage: dhcpd-dns-pxe + trigger: + include: + - artifact: .child-dhcpd-dns-pxe.yml + job: prepare + only: + changes: [ images/dhcpd-dns-pxe/**, lib/**, .image-gitlab-ci.yml ] -# dovecot: -# stage: dovecot -# trigger: -# include: -# - artifact: .child-dovecot.yml -# job: prepare -# only: -# changes: [ images/dovecot/**, lib/**, .image-gitlab-ci.yml ] +dovecot: + stage: dovecot + trigger: + include: + - artifact: .child-dovecot.yml + job: prepare + only: + changes: [ images/dovecot/**, lib/**, .image-gitlab-ci.yml ] -# ez-ipupdate: -# stage: ez-ipupdate -# trigger: -# include: -# - artifact: .child-ez-ipupdate.yml -# job: prepare -# only: -# changes: [ images/ez-ipupdate/**, lib/**, .image-gitlab-ci.yml ] +ez-ipupdate: + stage: ez-ipupdate + trigger: + include: + - artifact: .child-ez-ipupdate.yml + job: prepare + only: + changes: [ images/ez-ipupdate/**, lib/**, .image-gitlab-ci.yml ] -# git-pull: -# stage: git-pull -# trigger: -# include: -# - artifact: .child-git-pull.yml -# job: prepare -# only: -# changes: [ images/git-pull/**, lib/**, .image-gitlab-ci.yml ] +git-pull: + stage: git-pull + trigger: + include: + - artifact: .child-git-pull.yml + job: prepare + only: + changes: [ images/git-pull/**, lib/**, .image-gitlab-ci.yml ] -# haproxy-keepalived: -# stage: haproxy-keepalived -# trigger: -# include: -# - artifact: .child-haproxy-keepalived.yml -# job: prepare -# only: -# changes: [ images/haproxy-keepalived/**, lib/**, .image-gitlab-ci.yml ] +haproxy-keepalived: + stage: haproxy-keepalived + trigger: + include: + - artifact: .child-haproxy-keepalived.yml + job: prepare + only: + changes: [ images/haproxy-keepalived/**, lib/**, .image-gitlab-ci.yml ] -# mariadb-galera: -# stage: mariadb-galera -# trigger: -# include: -# - artifact: .child-mariadb-galera.yml -# job: prepare -# only: -# changes: [ images/mariadb-galera/**, lib/**, .image-gitlab-ci.yml ] +mariadb-galera: + stage: mariadb-galera + trigger: + include: + - artifact: .child-mariadb-galera.yml + job: prepare + only: + changes: [ images/mariadb-galera/**, lib/**, .image-gitlab-ci.yml ] -# mysqldump: -# stage: mysqldump -# trigger: -# include: -# - artifact: .child-mysqldump.yml -# job: prepare -# only: -# changes: [ images/mysqldump/**, lib/**, .image-gitlab-ci.yml ] +mysqldump: + stage: mysqldump + trigger: + include: + - artifact: .child-mysqldump.yml + job: prepare + only: + changes: [ images/mysqldump/**, lib/**, .image-gitlab-ci.yml ] -# mythtv-backend: -# stage: mythtv-backend -# trigger: -# include: -# - artifact: .child-mythtv-backend.yml -# job: prepare -# only: -# changes: [ images/mythtv-backend/**, lib/**, .image-gitlab-ci.yml ] +mythtv-backend: + stage: mythtv-backend + trigger: + include: + - artifact: .child-mythtv-backend.yml + job: prepare + only: + changes: [ images/mythtv-backend/**, lib/**, .image-gitlab-ci.yml ] -# nagios: -# stage: nagios -# trigger: -# include: -# - artifact: .child-nagios.yml -# job: prepare -# only: -# changes: [ images/nagios/**, lib/**, .image-gitlab-ci.yml ] +nagios: + stage: nagios + trigger: + include: + - artifact: .child-nagios.yml + job: prepare + only: + changes: [ images/nagios/**, lib/**, .image-gitlab-ci.yml ] -# nagiosql: -# stage: nagiosql -# trigger: -# include: -# - artifact: .child-nagiosql.yml -# job: prepare -# only: -# changes: [ images/nagiosql/**, lib/**, .image-gitlab-ci.yml ] +nagiosql: + stage: nagiosql + trigger: + include: + - artifact: .child-nagiosql.yml + job: prepare + only: + changes: [ images/nagiosql/**, lib/**, .image-gitlab-ci.yml ] -# nut-upsd: -# stage: nut-upsd -# trigger: -# include: -# - artifact: .child-nut-upsd.yml -# job: prepare -# only: -# changes: [ images/nut-upsd/**, lib/**, .image-gitlab-ci.yml ] +nut-upsd: + stage: nut-upsd + trigger: + include: + - artifact: .child-nut-upsd.yml + job: prepare + only: + changes: [ images/nut-upsd/**, lib/**, .image-gitlab-ci.yml ] -# postfix: -# stage: postfix -# trigger: -# include: -# - artifact: .child-postfix.yml -# job: prepare -# only: -# changes: [ images/postfix/**, lib/**, .image-gitlab-ci.yml ] +postfix: + stage: postfix + trigger: + include: + - artifact: .child-postfix.yml + job: prepare + only: + changes: [ images/postfix/**, lib/**, .image-gitlab-ci.yml ] -# openldap: -# stage: openldap -# trigger: -# include: -# - artifact: .child-openldap.yml -# job: prepare -# only: -# changes: [ images/openldap/**, lib/**, .image-gitlab-ci.yml ] +openldap: + stage: openldap + trigger: + include: + - artifact: .child-openldap.yml + job: prepare + only: + changes: [ images/openldap/**, lib/**, .image-gitlab-ci.yml ] -# postfix-python: -# stage: postfix-python -# trigger: -# include: -# - artifact: .child-postfix-python.yml -# job: prepare -# only: -# changes: [ images/postfix-python/**, lib/**, .image-gitlab-ci.yml ] +postfix-python: + stage: postfix-python + trigger: + include: + - artifact: .child-postfix-python.yml + job: prepare + only: + changes: [ images/postfix-python/**, lib/**, .image-gitlab-ci.yml ] -# proftpd: -# stage: proftpd -# trigger: -# include: -# - artifact: .child-proftpd.yml -# job: prepare -# only: -# changes: [ images/proftpd/**, lib/**, .image-gitlab-ci.yml ] +proftpd: + stage: proftpd + trigger: + include: + - artifact: .child-proftpd.yml + job: prepare + only: + changes: [ images/proftpd/**, lib/**, .image-gitlab-ci.yml ] -# rsyslogd: -# stage: rsyslogd -# trigger: -# include: -# - artifact: .child-rsyslogd.yml -# job: prepare -# only: -# changes: [ images/rsyslogd/**, lib/**, .image-gitlab-ci.yml ] +rsyslogd: + stage: rsyslogd + trigger: + include: + - artifact: .child-rsyslogd.yml + job: prepare + only: + changes: [ images/rsyslogd/**, lib/**, .image-gitlab-ci.yml ] -# samba: -# stage: samba -# trigger: -# include: -# - artifact: .child-samba.yml -# job: prepare -# only: -# changes: [ images/samba/**, lib/**, .image-gitlab-ci.yml ] +samba: + stage: samba + trigger: + include: + - artifact: .child-samba.yml + job: prepare + only: + changes: [ images/samba/**, lib/**, .image-gitlab-ci.yml ] -# samba-dc: -# stage: samba-dc -# trigger: -# include: -# - artifact: .child-samba-dc.yml -# job: prepare -# only: -# changes: [ images/samba-dc/**, lib/**, .image-gitlab-ci.yml ] +samba-dc: + stage: samba-dc + trigger: + include: + - artifact: .child-samba-dc.yml + job: prepare + only: + changes: [ images/samba-dc/**, lib/**, .image-gitlab-ci.yml ] -# spamassassin: -# stage: spamassassin -# trigger: -# include: -# - artifact: .child-spamassassin.yml -# job: prepare -# only: -# changes: [ images/spamassassin/**, lib/**, .image-gitlab-ci.yml ] +spamassassin: + stage: spamassassin + trigger: + include: + - artifact: .child-spamassassin.yml + job: prepare + only: + changes: [ images/spamassassin/**, lib/**, .image-gitlab-ci.yml ] -# udp-nginx-proxy: -# stage: udp-nginx-proxy -# trigger: -# include: -# - artifact: .child-udp-nginx-proxy.yml -# job: prepare -# only: -# changes: [ images/udp-nginx-proxy/**, lib/**, .image-gitlab-ci.yml ] +udp-nginx-proxy: + stage: udp-nginx-proxy + trigger: + include: + - artifact: .child-udp-nginx-proxy.yml + job: prepare + only: + changes: [ images/udp-nginx-proxy/**, lib/**, .image-gitlab-ci.yml ] -# vsftpd: -# stage: vsftpd -# trigger: -# include: -# - artifact: .child-vsftpd.yml -# job: prepare -# only: -# changes: [ images/vsftpd/**, lib/**, .image-gitlab-ci.yml ] +vsftpd: + stage: vsftpd + trigger: + include: + - artifact: .child-vsftpd.yml + job: prepare + only: + changes: [ images/vsftpd/**, lib/**, .image-gitlab-ci.yml ] -# weewx: -# stage: weewx -# trigger: -# include: -# - artifact: .child-weewx.yml -# job: prepare -# only: -# changes: [ images/weewx/**, lib/**, .image-gitlab-ci.yml ] +weewx: + stage: weewx + trigger: + include: + - artifact: .child-weewx.yml + job: prepare + only: + changes: [ images/weewx/**, lib/**, .image-gitlab-ci.yml ] diff --git a/.image-gitlab-ci.yml b/.image-gitlab-ci.yml index 1d72e731..0c2e2939 100644 --- a/.image-gitlab-ci.yml +++ b/.image-gitlab-ci.yml @@ -8,9 +8,9 @@ variables: stages: - Static Code Analysis - # - Create Image + - Create Image - Functional Tests - # - Security Scan + - Security Scan - Promote Image image: docker:29.7.2 @@ -26,67 +26,67 @@ analysis: image: instantlinux/python-builder:latest script: cd images/$IMAGE && make analysis -# create_image: -# <<: *registry_login -# stage: Create Image -# script: apk add make && cd images/$IMAGE && make create_image -# services: [ { name: "docker:dind", command: ["--experimental"] } ] +create_image: + <<: *registry_login + stage: Create Image + script: apk add make && cd images/$IMAGE && make create_image + services: [ { name: "docker:dind", command: ["--experimental"] } ] test: stage: Functional Tests script: apk add make && cd images/$IMAGE && make test_functional -# security_scan_trivy: -# services: [ "docker:dind" ] -# image: -# name: aquasec/trivy:$TRIVY_VERSION -# entrypoint: [""] -# stage: Security Scan -# variables: -# GIT_STRATEGY: none -# TRIVY_CACHE_DIR: .trivycache/ -# TRIVY_DEBUG: "true" -# TRIVY_EXIT_CODE: 1 -# TRIVY_FORMAT: json -# TRIVY_IGNORE: >- -# CVE-2023-52425,CVE-2024-8176, -# CVE-2025-9900, -# # CVE-2025-9900 is for mythtv-backend -# TRIVY_OUTPUT: gl-container-scanning-report.json -# TRIVY_SEVERITY: HIGH,CRITICAL -# TRIVY_PKG_TYPES: os,library -# script: -# - export TAG=bld_$CI_PIPELINE_IID_${CI_COMMIT_SHORT_SHA} -# # Trivy alerts on unfixed vulnerabilities in debian images -# - > -# if [ $IMAGE = blacklist ] || [ $IMAGE = spamassassin ]; then -# IGN_FLAG=--ignore-unfixed ; -# fi -# - trivy clean --all -# - trivy image --download-db-only --no-progress -# - trivy image "${REGISTRY}/${IMAGE}:${TAG}" --severity LOW,MEDIUM -# --exit-code 0 --format table --output medium-vulns.txt -# - cat medium-vulns.txt -# - echo $TRIVY_IGNORE | tr , "\n" | tee .trivyignore -# - trivy image $IGN_FLAG "${REGISTRY}/${IMAGE}:${TAG}" -# cache: -# paths: [ .trivycache ] -# interruptible: true -# retry: -# max: 2 -# when: [ runner_system_failure, stuck_or_timeout_failure ] -# timeout: 5m -# artifacts: -# reports: -# container_scanning: gl-container-scanning-report.json -# expire_in: 30 days -# paths: [ medium-vulns.txt ] +security_scan_trivy: + services: [ "docker:dind" ] + image: + name: aquasec/trivy:$TRIVY_VERSION + entrypoint: [""] + stage: Security Scan + variables: + GIT_STRATEGY: none + TRIVY_CACHE_DIR: .trivycache/ + TRIVY_DEBUG: "true" + TRIVY_EXIT_CODE: 1 + TRIVY_FORMAT: json + TRIVY_IGNORE: >- + CVE-2023-52425,CVE-2024-8176, + CVE-2025-9900, + # CVE-2025-9900 is for mythtv-backend + TRIVY_OUTPUT: gl-container-scanning-report.json + TRIVY_SEVERITY: HIGH,CRITICAL + TRIVY_PKG_TYPES: os,library + script: + - export TAG=bld_$CI_PIPELINE_IID_${CI_COMMIT_SHORT_SHA} + # Trivy alerts on unfixed vulnerabilities in debian images + - > + if [ $IMAGE = blacklist ] || [ $IMAGE = spamassassin ]; then + IGN_FLAG=--ignore-unfixed ; + fi + - trivy clean --all + - trivy image --download-db-only --no-progress + - trivy image "${REGISTRY}/${IMAGE}:${TAG}" --severity LOW,MEDIUM + --exit-code 0 --format table --output medium-vulns.txt + - cat medium-vulns.txt + - echo $TRIVY_IGNORE | tr , "\n" | tee .trivyignore + - trivy image $IGN_FLAG "${REGISTRY}/${IMAGE}:${TAG}" + cache: + paths: [ .trivycache ] + interruptible: true + retry: + max: 2 + when: [ runner_system_failure, stuck_or_timeout_failure ] + timeout: 5m + artifacts: + reports: + container_scanning: gl-container-scanning-report.json + expire_in: 30 days + paths: [ medium-vulns.txt ] promote_image: stage: Promote Image <<: *registry_login script: apk add curl jq make && cd images/$IMAGE && make promote_image interruptible: true - # only: - # refs: [ main, tags ] - # variables: [ $REGISTRY_URI == "registry.gitlab.com" ] + only: + refs: [ main, tags ] + variables: [ $REGISTRY_URI == "registry.gitlab.com" ] diff --git a/lib/build/Makefile.docker_image b/lib/build/Makefile.docker_image index 5515cd33..9fb3c17f 100644 --- a/lib/build/Makefile.docker_image +++ b/lib/build/Makefile.docker_image @@ -73,8 +73,7 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx --build-arg=BUILD_DATE=$(shell date +%Y-%m-%dT%H:%M:%SZ) # update dockerhub README - # jq --arg escapes special characters / newlines - pwd && ls -l README.md + # jq --arg or --rawfile escapes special characters / newlines JSON=$$(jq -n --arg pwd "$(DOCKER_TOKEN)" --arg user "$(USER_LOGIN)" \ '{username: $$user, password: $$pwd}') && \ JWT=$$(curl -s -H "Content-Type: application/json" -X POST \ @@ -85,7 +84,6 @@ promote_image: $(HOME)/.docker/cli-plugins/docker-buildx -H "Authorization: Bearer $$JWT" \ -d @- https://hub.docker.com/v2/repositories/$(IMAGE_REPO)/) && \ [ "$$RESP" -eq 200 ] || exit 1 - # Build JSON payload, send PATCH request flake8: test_requirements @echo "Running flake8 code analysis"