From d44930de7e46ff8cfd48fa5323887d465fad7da6 Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Sun, 23 Aug 2026 18:26:20 +0200 Subject: [PATCH 1/4] Ref: Aktualisiere Anweisungen in der README.md --- README.md | 60 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 0aca80d..a06fbff 100644 --- a/README.md +++ b/README.md @@ -76,38 +76,54 @@ sudo apt install docker-update --- -### 2. Fedora / RHEL / CentOS (`dnf` / `yum`) +### 2. RedHat / Fedora / SUSE #### Stable (Produktiv) -Erstelle die Repository-Datei `/etc/yum.repos.d/docker-update.repo`: +Repository einrichten: +```bash +# auf RedHat-basierten Distributionen +dnf config-manager --add-repo https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/rpm/stable.repo + +# Fedora 41+ (DNF5) +dnf config-manager addrepo --from-repofile=https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/rpm/stable.repo + +# auf SUSE-basierten Distributionen +zypper addrepo https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/rpm/stable.repo +``` + +Paket installieren: ```bash -sudo tee /etc/yum.repos.d/docker-update-stable.repo << 'EOF' -[docker-update-stable] -name=DockerUpdate Stable -baseurl=https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/rpm/stable -enabled=1 -gpgcheck=0 -EOF +# auf RedHat-basierten Distributionen +dnf install docker-update -# Installation via DNF -sudo dnf install docker-update +# auf SUSE-basierten Distributionen +zypper install docker-update ``` #### Testing (Vorschau / Testing) +Repository einrichten: ```bash -sudo tee /etc/yum.repos.d/docker-update-testing.repo << 'EOF' -[docker-update-testing] -name=DockerUpdate Testing -baseurl=https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/rpm/testing -enabled=1 -gpgcheck=0 -EOF +# auf RedHat-basierten Distributionen +dnf config-manager --add-repo https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/rpm/testing.repo -# Installation via DNF -sudo dnf install docker-update +# Fedora 41+ (DNF5) +dnf config-manager addrepo --from-repofile=https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/rpm/testing.repo + +# auf SUSE-basierten Distributionen +zypper addrepo https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/rpm/testing.repo +``` + +Paket installieren: + +```bash +# auf RedHat-basierten Distributionen +dnf install docker-update + +# auf SUSE-basierten Distributionen +zypper install docker-update ``` --- @@ -121,7 +137,7 @@ Füge das Repository in `/etc/pacman.conf` ein: ```ini [docker-update-stable] SigLevel = Optional TrustAll -Server = https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/arch/stable/$arch +Server = https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/arch/stable/x86_64 ``` Installiere das Paket anschließend: @@ -137,7 +153,7 @@ Füge das Testing-Repository in `/etc/pacman.conf` ein: ```ini [docker-update-testing] SigLevel = Optional TrustAll -Server = https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/arch/testing/$arch +Server = https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/arch/testing/x86_64 ``` Installiere das Paket: From 24955f75b5c913cf3a83ef8a1d58d6327f2bcbbf Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Sun, 23 Aug 2026 18:46:33 +0200 Subject: [PATCH 2/4] Ref: Packaging-Definitionen in Cargo.toml verschieben und alte Dateien entfernen --- .gitea/workflows/main.yaml | 64 ++++++++++++++++- .gitea/workflows/testing.yaml | 64 ++++++++++++++++- AGENTS.md | 23 ++----- Cargo.toml | 6 ++ README.md | 102 +++++++++++++++++++++------- packaging/arch/PKGBUILD | 40 ----------- packaging/arch/build-package.sh | 54 --------------- packaging/fedora/docker-update.spec | 42 ------------ 8 files changed, 212 insertions(+), 183 deletions(-) delete mode 100644 packaging/arch/PKGBUILD delete mode 100755 packaging/arch/build-package.sh delete mode 100644 packaging/fedora/docker-update.spec diff --git a/.gitea/workflows/main.yaml b/.gitea/workflows/main.yaml index 9e0e5c0..1802998 100644 --- a/.gitea/workflows/main.yaml +++ b/.gitea/workflows/main.yaml @@ -44,8 +44,68 @@ jobs: - name: Build Arch Linux Package (.pkg.tar.zst) run: | - chmod +x packaging/arch/build-package.sh - ./packaging/arch/build-package.sh + python3 - <<'EOF' + import json, os, subprocess, tempfile, time + + metadata = json.loads(subprocess.check_output(["cargo", "metadata", "--format-version", "1", "--no-deps"])) + pkg = metadata["packages"][0] + name = pkg["name"] + version = pkg["version"] + description = pkg.get("description", "") + license = pkg.get("license", "") + repository = pkg.get("repository", "") + authors = pkg.get("authors", []) + author = authors[0] if authors else "Unknown" + + arch_meta = pkg.get("metadata", {}).get("arch", {}) + pkgrel = arch_meta.get("pkgrel", "1") + arch = arch_meta.get("arch", "x86_64") + depends = arch_meta.get("depends", ["gcc-libs", "glibc", "sudo", "docker"]) + optdepends = arch_meta.get("optdepends", ["docker-compose: Unterstützung für Docker Compose v1"]) + + with tempfile.TemporaryDirectory() as build_dir: + bin_dir = os.path.join(build_dir, "usr/bin") + doc_dir = os.path.join(build_dir, f"usr/share/doc/{name}") + lic_dir = os.path.join(build_dir, f"usr/share/licenses/{name}") + os.makedirs(bin_dir, exist_ok=True) + os.makedirs(doc_dir, exist_ok=True) + os.makedirs(lic_dir, exist_ok=True) + + subprocess.run(["install", "-m", "755", f"target/release/{name}", f"{bin_dir}/{name}"], check=True) + if os.path.exists("LICENSE"): + subprocess.run(["install", "-m", "644", "LICENSE", f"{lic_dir}/LICENSE"], check=True) + if os.path.exists("README.md"): + subprocess.run(["install", "-m", "644", "README.md", f"{doc_dir}/README.md"], check=True) + + installed_size = subprocess.check_output(["du", "-sb", build_dir]).decode().split()[0] + builddate = str(int(time.time())) + + pkginfo_lines = [ + f"pkgname = {name}", + f"pkgbase = {name}", + f"pkgver = {version}-{pkgrel}", + f"pkgdesc = {description}", + f"url = {repository}", + f"builddate = {builddate}", + f"packager = {author}", + f"size = {installed_size}", + f"arch = {arch}", + f"license = {license}", + ] + for dep in depends: + pkginfo_lines.append(f"depend = {dep}") + for optdep in optdepends: + pkginfo_lines.append(f"optdepend = {optdep}") + pkginfo_lines.append("makepkgopt = strip\n") + + with open(os.path.join(build_dir, ".PKGINFO"), "w") as f: + f.write("\n".join(pkginfo_lines)) + + os.makedirs("target/arch", exist_ok=True) + output_file = os.path.abspath(f"target/arch/{name}-{version}-{pkgrel}-{arch}.pkg.tar.zst") + subprocess.run(["tar", "--zstd", "-cf", output_file, ".PKGINFO", "usr"], cwd=build_dir, check=True) + print(f"Arch-Paket erfolgreich erstellt: {output_file}") + EOF - name: Publish Packages to Gitea Package Registry env: diff --git a/.gitea/workflows/testing.yaml b/.gitea/workflows/testing.yaml index 6a8cef6..19d94dc 100644 --- a/.gitea/workflows/testing.yaml +++ b/.gitea/workflows/testing.yaml @@ -44,8 +44,68 @@ jobs: - name: Build Arch Linux Package (.pkg.tar.zst) run: | - chmod +x packaging/arch/build-package.sh - ./packaging/arch/build-package.sh + python3 - <<'EOF' + import json, os, subprocess, tempfile, time + + metadata = json.loads(subprocess.check_output(["cargo", "metadata", "--format-version", "1", "--no-deps"])) + pkg = metadata["packages"][0] + name = pkg["name"] + version = pkg["version"] + description = pkg.get("description", "") + license = pkg.get("license", "") + repository = pkg.get("repository", "") + authors = pkg.get("authors", []) + author = authors[0] if authors else "Unknown" + + arch_meta = pkg.get("metadata", {}).get("arch", {}) + pkgrel = arch_meta.get("pkgrel", "1") + arch = arch_meta.get("arch", "x86_64") + depends = arch_meta.get("depends", ["gcc-libs", "glibc", "sudo", "docker"]) + optdepends = arch_meta.get("optdepends", ["docker-compose: Unterstützung für Docker Compose v1"]) + + with tempfile.TemporaryDirectory() as build_dir: + bin_dir = os.path.join(build_dir, "usr/bin") + doc_dir = os.path.join(build_dir, f"usr/share/doc/{name}") + lic_dir = os.path.join(build_dir, f"usr/share/licenses/{name}") + os.makedirs(bin_dir, exist_ok=True) + os.makedirs(doc_dir, exist_ok=True) + os.makedirs(lic_dir, exist_ok=True) + + subprocess.run(["install", "-m", "755", f"target/release/{name}", f"{bin_dir}/{name}"], check=True) + if os.path.exists("LICENSE"): + subprocess.run(["install", "-m", "644", "LICENSE", f"{lic_dir}/LICENSE"], check=True) + if os.path.exists("README.md"): + subprocess.run(["install", "-m", "644", "README.md", f"{doc_dir}/README.md"], check=True) + + installed_size = subprocess.check_output(["du", "-sb", build_dir]).decode().split()[0] + builddate = str(int(time.time())) + + pkginfo_lines = [ + f"pkgname = {name}", + f"pkgbase = {name}", + f"pkgver = {version}-{pkgrel}", + f"pkgdesc = {description}", + f"url = {repository}", + f"builddate = {builddate}", + f"packager = {author}", + f"size = {installed_size}", + f"arch = {arch}", + f"license = {license}", + ] + for dep in depends: + pkginfo_lines.append(f"depend = {dep}") + for optdep in optdepends: + pkginfo_lines.append(f"optdepend = {optdep}") + pkginfo_lines.append("makepkgopt = strip\n") + + with open(os.path.join(build_dir, ".PKGINFO"), "w") as f: + f.write("\n".join(pkginfo_lines)) + + os.makedirs("target/arch", exist_ok=True) + output_file = os.path.abspath(f"target/arch/{name}-{version}-{pkgrel}-{arch}.pkg.tar.zst") + subprocess.run(["tar", "--zstd", "-cf", output_file, ".PKGINFO", "usr"], cwd=build_dir, check=True) + print(f"Arch-Paket erfolgreich erstellt: {output_file}") + EOF - name: Publish Packages to Gitea Package Registry env: diff --git a/AGENTS.md b/AGENTS.md index 95bd7d9..b78793a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,17 +31,11 @@ DockerUpdate/ │ └── workflows/ │ ├── testing.yaml # CI/CD für testing-Branch (Tests, Testing-Packages & Preview-Release) │ └── main.yaml # CI/CD für main-Branch (Tests, Stable-Packages & Release) -├── Cargo.toml # Rust-Manifest, Abhängigkeiten und Metadaten für cargo-deb / generate-rpm +├── Cargo.toml # Rust-Manifest, Abhängigkeiten und Metadaten für deb / generate-rpm / arch ├── Cargo.lock ├── LICENSE # GPL-3.0 Lizenztext ├── README.md # Projektdokumentation für Endanwender und Administratoren ├── AGENTS.md # Richtlinien und Dokumentation für Agenten -├── packaging/ -│ ├── arch/ -│ │ ├── PKGBUILD # Arch Linux PKGBUILD -│ │ └── build-package.sh # Hilfsskript zur Erstellung des .pkg.tar.zst-Pakets -│ └── fedora/ -│ └── docker-update.spec # RPM-Spec für Fedora / RHEL / CentOS └── src/ ├── main.rs # Einstiegspunkt, Root-Prüfung, Ausführung ├── program.rs # Hilfsfunktion zur Programmnamensermittlung @@ -83,10 +77,6 @@ DockerUpdate/ - `main.yaml`: Führt bei Push auf `main` Tests und Builds durch, veröffentlicht Pakete in der Gitea Package Registry (`distribution: stable`, `component: main` bzw. Gruppe/Repo `stable`) und erstellt ein Gitea Release mit den Paketen als Assets. -- **`packaging/`**: - - `arch/PKGBUILD`: Quellpaketdefinition für Arch Linux (AUR / Makepkg). - - `arch/build-package.sh`: Hilfsskript zum Bauen des standardkonformen `.pkg.tar.zst`-Pakets aus dem Cargo-Build. - - `fedora/docker-update.spec`: RPM-Spec-Datei für Fedora, RHEL und CentOS. --- @@ -113,9 +103,6 @@ cargo deb # Fedora / RPM-Paket (.rpm) erstellen (benötigt cargo-generate-rpm) cargo generate-rpm - -# Arch Linux-Paket (.pkg.tar.zst) erstellen -./packaging/arch/build-package.sh ``` --- @@ -124,10 +111,10 @@ cargo generate-rpm 1. **Abwärtskompatibilität & Pfade**: Der Standard-Apps-Pfad `/var/apps` und die Konfigurationspfade dürfen nicht ohne triftigen Grund geändert werden. -2. **Paketierungsdefinitionen synchron halten**: - Werden Abhängigkeiten, Metadaten oder Assets geändert, müssen `Cargo.toml` (`[package.metadata.deb]`, - `[package.metadata.generate-rpm]`), `packaging/arch/PKGBUILD`, `packaging/arch/build-package.sh` und - `packaging/fedora/docker-update.spec` entsprechend aktualisiert werden. +2. **Paketierungsdefinitionen in Cargo.toml pflegen**: + Alle Paketierungsdefinitionen für Debian, RPM und Arch Linux werden zentral in `Cargo.toml` verwaltet + (`[package.metadata.deb]`, `[package.metadata.generate-rpm]`, `[package.metadata.arch]`). Es wird kein separater + `packaging/`-Ordner benötigt. 3. **Automatisierung**: Die empfohlene Automatisierungsmethode ist **Cron** (`/etc/cron.d/docker-update` oder `crontab -e`). 4. **Keine Mocking-Bypässe**: diff --git a/Cargo.toml b/Cargo.toml index 2bb358d..a536004 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,3 +43,9 @@ assets = [ { source = "LICENSE", dest = "/usr/share/licenses/docker-update/LICENSE", mode = "644", license = true }, ] requires = { "sudo" = "*", "docker" = "*" } + +[package.metadata.arch] +pkgrel = "1" +arch = "x86_64" +depends = ["gcc-libs", "glibc", "sudo", "docker"] +optdepends = ["docker-compose: Unterstützung für Docker Compose v1"] diff --git a/README.md b/README.md index a06fbff..092e0e7 100644 --- a/README.md +++ b/README.md @@ -234,7 +234,7 @@ cargo install cargo-deb cargo deb # Installation des erstellten Pakets -sudo dpkg -i target/debian/docker-update_0.1.0-1_amd64.deb +sudo dpkg -i target/debian/docker-update_*.deb ``` Die Paketkonfiguration und Abhängigkeiten (`sudo`, `docker.io | docker-ce`) sind in `Cargo.toml` unter @@ -242,29 +242,93 @@ Die Paketkonfiguration und Abhängigkeiten (`sudo`, `docker.io | docker-ce`) sin --- -### 2. Arch Linux (`PKGBUILD`) +### 2. Arch Linux (`.pkg.tar.zst`) -Für Arch Linux liegt ein `PKGBUILD` im Verzeichnis `packaging/arch/` bereit: +Die Paketmetadaten und Abhängigkeiten für Arch Linux sind direkt in `Cargo.toml` unter `[package.metadata.arch]` +hinterlegt. Das Paket kann nach dem Kompilieren des Release-Builds über das folgende Skript (analog zu CI/CD) erzeugt +werden: ```bash -cd packaging/arch +# Release kompilieren +cargo build --release -# Paket bauen und installieren -makepkg -si +# Arch Linux-Paket (.pkg.tar.zst) erstellen +python3 - <<'EOF' +import json, os, subprocess, tempfile, time + +metadata = json.loads(subprocess.check_output(["cargo", "metadata", "--format-version", "1", "--no-deps"])) +pkg = metadata["packages"][0] +name = pkg["name"] +version = pkg["version"] +description = pkg.get("description", "") +license = pkg.get("license", "") +repository = pkg.get("repository", "") +authors = pkg.get("authors", []) +author = authors[0] if authors else "Unknown" + +arch_meta = pkg.get("metadata", {}).get("arch", {}) +pkgrel = arch_meta.get("pkgrel", "1") +arch = arch_meta.get("arch", "x86_64") +depends = arch_meta.get("depends", ["gcc-libs", "glibc", "sudo", "docker"]) +optdepends = arch_meta.get("optdepends", ["docker-compose: Unterstützung für Docker Compose v1"]) + +with tempfile.TemporaryDirectory() as build_dir: + bin_dir = os.path.join(build_dir, "usr/bin") + doc_dir = os.path.join(build_dir, f"usr/share/doc/{name}") + lic_dir = os.path.join(build_dir, f"usr/share/licenses/{name}") + os.makedirs(bin_dir, exist_ok=True) + os.makedirs(doc_dir, exist_ok=True) + os.makedirs(lic_dir, exist_ok=True) + + subprocess.run(["install", "-m", "755", f"target/release/{name}", f"{bin_dir}/{name}"], check=True) + if os.path.exists("LICENSE"): + subprocess.run(["install", "-m", "644", "LICENSE", f"{lic_dir}/LICENSE"], check=True) + if os.path.exists("README.md"): + subprocess.run(["install", "-m", "644", "README.md", f"{doc_dir}/README.md"], check=True) + + installed_size = subprocess.check_output(["du", "-sb", build_dir]).decode().split()[0] + builddate = str(int(time.time())) + + pkginfo_lines = [ + f"pkgname = {name}", + f"pkgbase = {name}", + f"pkgver = {version}-{pkgrel}", + f"pkgdesc = {description}", + f"url = {repository}", + f"builddate = {builddate}", + f"packager = {author}", + f"size = {installed_size}", + f"arch = {arch}", + f"license = {license}", + ] + for dep in depends: + pkginfo_lines.append(f"depend = {dep}") + for optdep in optdepends: + pkginfo_lines.append(f"optdepend = {optdep}") + pkginfo_lines.append("makepkgopt = strip\n") + + with open(os.path.join(build_dir, ".PKGINFO"), "w") as f: + f.write("\n".join(pkginfo_lines)) + + os.makedirs("target/arch", exist_ok=True) + output_file = os.path.abspath(f"target/arch/{name}-{version}-{pkgrel}-{arch}.pkg.tar.zst") + subprocess.run(["tar", "--zstd", "-cf", output_file, ".PKGINFO", "usr"], cwd=build_dir, check=True) + print(f"Arch-Paket erfolgreich erstellt: {output_file}") +EOF + +# Installation des erstellten Pakets +sudo pacman -U target/arch/docker-update-*.pkg.tar.zst ``` -Alternativ kann das Binary auch manuell mit `pacman -U .pkg.tar.zst` installiert werden. - --- ### 3. Fedora / RHEL / CentOS (`.rpm`) -Für RPM-basierte Distributionen gibt es zwei Möglichkeiten: - -#### Option A: Mit `cargo-generate-rpm` +Das RPM-Paket wird mithilfe von [`cargo-generate-rpm`](https://github.com/cat-in-136/cargo-generate-rpm) direkt aus den +Metadaten in `Cargo.toml` (`[package.metadata.generate-rpm]`) erstellt: ```bash -# cargo-generate-rpm installieren +# cargo-generate-rpm installieren (falls noch nicht vorhanden) cargo install cargo-generate-rpm # Release bauen und RPM erzeugen @@ -272,19 +336,7 @@ cargo build --release cargo generate-rpm # Installation des erstellten RPM-Pakets -sudo dnf install target/generate-rpm/docker-update-0.1.0-1.*.rpm -``` - -#### Option B: Mit `rpmbuild` und Spec-Datei - -Die RPM-Spec-Datei befindet sich in `packaging/fedora/docker-update.spec`: - -```bash -# Erforderliche Build-Werkzeuge installieren -sudo dnf install rpm-build - -# Paket über rpmbuild erstellen -rpmbuild -ba packaging/fedora/docker-update.spec +sudo dnf install target/generate-rpm/docker-update-*.rpm ``` --- diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD deleted file mode 100644 index 084ca28..0000000 --- a/packaging/arch/PKGBUILD +++ /dev/null @@ -1,40 +0,0 @@ -# Maintainer: DragonSlayer_14 - -pkgname=docker-update -pkgver=0.1.0 -pkgrel=1 -pkgdesc="Automatisches Aktualisieren von Docker-Compose-Anwendungen in /var/apps mit :latest-Images" -arch=('x86_64' 'aarch64') -url="https://gitea.creative-dragonslayer.de/Linuxapps/DockerUpdate" -license=('GPL-3.0-or-later') -depends=('gcc-libs' 'glibc' 'sudo' 'docker') -optdepends=('docker-compose: Unterstützung für Docker Compose v1') -makedepends=('cargo') -source=("$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz") -sha256sums=('SKIP') - -prepare() { - cd "$srcdir/$pkgname-$pkgver" 2>/dev/null || cd "$srcdir/$pkgname" 2>/dev/null || cd "$srcdir" - export RUSTUP_TOOLCHAIN=stable - cargo fetch --locked --target "$(rustc -vV | sed -n 's/host: //p')" 2>/dev/null || cargo fetch || true -} - -build() { - cd "$srcdir/$pkgname-$pkgver" 2>/dev/null || cd "$srcdir/$pkgname" 2>/dev/null || cd "$srcdir" - export RUSTUP_TOOLCHAIN=stable - export CARGO_TARGET_DIR=target - cargo build --frozen --release --all-targets 2>/dev/null || cargo build --release -} - -check() { - cd "$srcdir/$pkgname-$pkgver" 2>/dev/null || cd "$srcdir/$pkgname" 2>/dev/null || cd "$srcdir" - export RUSTUP_TOOLCHAIN=stable - cargo test --frozen 2>/dev/null || cargo test -} - -package() { - cd "$srcdir/$pkgname-$pkgver" 2>/dev/null || cd "$srcdir/$pkgname" 2>/dev/null || cd "$srcdir" - install -Dm755 "target/release/$pkgname" "$pkgdir/usr/bin/$pkgname" - install -Dm644 "LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE" - install -Dm644 "README.md" "$pkgdir/usr/share/doc/$pkgname/README.md" -} diff --git a/packaging/arch/build-package.sh b/packaging/arch/build-package.sh deleted file mode 100755 index 8c22a03..0000000 --- a/packaging/arch/build-package.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" - -cd "$PROJECT_ROOT" - -if [ ! -f "target/release/docker-update" ]; then - cargo build --release -fi - -VERSION="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)" -PKGVER="${VERSION}" -PKGREL="1" -ARCH="x86_64" - -BUILD_DIR="$(mktemp -d)" -trap 'rm -rf "$BUILD_DIR"' EXIT - -mkdir -p "$BUILD_DIR/usr/bin" -mkdir -p "$BUILD_DIR/usr/share/licenses/docker-update" -mkdir -p "$BUILD_DIR/usr/share/doc/docker-update" - -install -m 755 "target/release/docker-update" "$BUILD_DIR/usr/bin/docker-update" -install -m 644 "LICENSE" "$BUILD_DIR/usr/share/licenses/docker-update/LICENSE" -install -m 644 "README.md" "$BUILD_DIR/usr/share/doc/docker-update/README.md" - -INSTALLED_SIZE="$(du -sb "$BUILD_DIR" | awk '{print $1}')" - -cat < "$BUILD_DIR/.PKGINFO" -pkgname = docker-update -pkgbase = docker-update -pkgver = ${PKGVER}-${PKGREL} -pkgdesc = Automatisches Aktualisieren von Docker-Compose-Anwendungen in /var/apps mit :latest-Images -url = https://gitea.creative-dragonslayer.de/Linuxapps/DockerUpdate -builddate = $(date +%s) -packager = DragonSlayer_14 -size = ${INSTALLED_SIZE} -arch = ${ARCH} -license = GPL-3.0-or-later -depend = gcc-libs -depend = glibc -depend = sudo -depend = docker -optdepend = docker-compose: Unterstützung für Docker Compose v1 -makepkgopt = strip -EOF - -mkdir -p "target/arch" -OUTPUT_FILE="$PROJECT_ROOT/target/arch/docker-update-${PKGVER}-${PKGREL}-${ARCH}.pkg.tar.zst" -(cd "$BUILD_DIR" && tar --zstd -cf "$OUTPUT_FILE" .PKGINFO usr) - -echo "Arch-Paket erfolgreich erstellt: $OUTPUT_FILE" diff --git a/packaging/fedora/docker-update.spec b/packaging/fedora/docker-update.spec deleted file mode 100644 index 7db52ce..0000000 --- a/packaging/fedora/docker-update.spec +++ /dev/null @@ -1,42 +0,0 @@ -Name: docker-update -Version: 0.1.0 -Release: 1%{?dist} -Summary: Automatisches Aktualisieren von Docker-Compose-Anwendungen in /var/apps mit :latest-Images - -License: GPL-3.0-or-later -URL: https://gitea.creative-dragonslayer.de/Linuxapps/DockerUpdate -Source0: %{name}-%{version}.tar.gz - -BuildRequires: cargo -BuildRequires: rust -Requires: sudo -Requires: (docker or moby-engine or docker-ce) -Suggests: (docker-compose or docker-compose-plugin) - -%description -DockerUpdate durchsucht Verzeichnisse (standardmäßig in /var/apps) nach -Docker-Compose-Dateien mit ':latest'-Images, prüft auf neuere Images, -lädt diese herunter und startet die betroffenen Container automatisch neu. - -%prep -%autosetup - -%build -cargo build --release - -%check -cargo test - -%install -install -D -p -m 0755 target/release/%{name} %{buildroot}%{_bindir}/%{name} -install -D -p -m 0644 README.md %{buildroot}%{_docdir}/%{name}/README.md -install -D -p -m 0644 LICENSE %{buildroot}%{_licensedir}/%{name}/LICENSE - -%files -%license LICENSE -%doc README.md -%{_bindir}/%{name} - -%changelog -* Sun Aug 23 2026 DragonSlayer_14 - 0.1.0-1 -- Erstveröffentlichung von docker-update From 8ef3ad28a08792e3da3ca25d9f88db5ba113d93d Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Sun, 23 Aug 2026 18:52:38 +0200 Subject: [PATCH 3/4] Ref: Arch-Paketierung in separates Skript auslagern und Workflows aktualisieren --- .gitea/workflows/main.yaml | 63 +------------------------------ .gitea/workflows/testing.yaml | 63 +------------------------------ AGENTS.md | 5 +++ README.md | 66 ++------------------------------ scripts/package-arch.py | 71 +++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 187 deletions(-) create mode 100755 scripts/package-arch.py diff --git a/.gitea/workflows/main.yaml b/.gitea/workflows/main.yaml index 1802998..3ed19b5 100644 --- a/.gitea/workflows/main.yaml +++ b/.gitea/workflows/main.yaml @@ -44,68 +44,7 @@ jobs: - name: Build Arch Linux Package (.pkg.tar.zst) run: | - python3 - <<'EOF' - import json, os, subprocess, tempfile, time - - metadata = json.loads(subprocess.check_output(["cargo", "metadata", "--format-version", "1", "--no-deps"])) - pkg = metadata["packages"][0] - name = pkg["name"] - version = pkg["version"] - description = pkg.get("description", "") - license = pkg.get("license", "") - repository = pkg.get("repository", "") - authors = pkg.get("authors", []) - author = authors[0] if authors else "Unknown" - - arch_meta = pkg.get("metadata", {}).get("arch", {}) - pkgrel = arch_meta.get("pkgrel", "1") - arch = arch_meta.get("arch", "x86_64") - depends = arch_meta.get("depends", ["gcc-libs", "glibc", "sudo", "docker"]) - optdepends = arch_meta.get("optdepends", ["docker-compose: Unterstützung für Docker Compose v1"]) - - with tempfile.TemporaryDirectory() as build_dir: - bin_dir = os.path.join(build_dir, "usr/bin") - doc_dir = os.path.join(build_dir, f"usr/share/doc/{name}") - lic_dir = os.path.join(build_dir, f"usr/share/licenses/{name}") - os.makedirs(bin_dir, exist_ok=True) - os.makedirs(doc_dir, exist_ok=True) - os.makedirs(lic_dir, exist_ok=True) - - subprocess.run(["install", "-m", "755", f"target/release/{name}", f"{bin_dir}/{name}"], check=True) - if os.path.exists("LICENSE"): - subprocess.run(["install", "-m", "644", "LICENSE", f"{lic_dir}/LICENSE"], check=True) - if os.path.exists("README.md"): - subprocess.run(["install", "-m", "644", "README.md", f"{doc_dir}/README.md"], check=True) - - installed_size = subprocess.check_output(["du", "-sb", build_dir]).decode().split()[0] - builddate = str(int(time.time())) - - pkginfo_lines = [ - f"pkgname = {name}", - f"pkgbase = {name}", - f"pkgver = {version}-{pkgrel}", - f"pkgdesc = {description}", - f"url = {repository}", - f"builddate = {builddate}", - f"packager = {author}", - f"size = {installed_size}", - f"arch = {arch}", - f"license = {license}", - ] - for dep in depends: - pkginfo_lines.append(f"depend = {dep}") - for optdep in optdepends: - pkginfo_lines.append(f"optdepend = {optdep}") - pkginfo_lines.append("makepkgopt = strip\n") - - with open(os.path.join(build_dir, ".PKGINFO"), "w") as f: - f.write("\n".join(pkginfo_lines)) - - os.makedirs("target/arch", exist_ok=True) - output_file = os.path.abspath(f"target/arch/{name}-{version}-{pkgrel}-{arch}.pkg.tar.zst") - subprocess.run(["tar", "--zstd", "-cf", output_file, ".PKGINFO", "usr"], cwd=build_dir, check=True) - print(f"Arch-Paket erfolgreich erstellt: {output_file}") - EOF + python3 scripts/package-arch.py - name: Publish Packages to Gitea Package Registry env: diff --git a/.gitea/workflows/testing.yaml b/.gitea/workflows/testing.yaml index 19d94dc..c5b65d4 100644 --- a/.gitea/workflows/testing.yaml +++ b/.gitea/workflows/testing.yaml @@ -44,68 +44,7 @@ jobs: - name: Build Arch Linux Package (.pkg.tar.zst) run: | - python3 - <<'EOF' - import json, os, subprocess, tempfile, time - - metadata = json.loads(subprocess.check_output(["cargo", "metadata", "--format-version", "1", "--no-deps"])) - pkg = metadata["packages"][0] - name = pkg["name"] - version = pkg["version"] - description = pkg.get("description", "") - license = pkg.get("license", "") - repository = pkg.get("repository", "") - authors = pkg.get("authors", []) - author = authors[0] if authors else "Unknown" - - arch_meta = pkg.get("metadata", {}).get("arch", {}) - pkgrel = arch_meta.get("pkgrel", "1") - arch = arch_meta.get("arch", "x86_64") - depends = arch_meta.get("depends", ["gcc-libs", "glibc", "sudo", "docker"]) - optdepends = arch_meta.get("optdepends", ["docker-compose: Unterstützung für Docker Compose v1"]) - - with tempfile.TemporaryDirectory() as build_dir: - bin_dir = os.path.join(build_dir, "usr/bin") - doc_dir = os.path.join(build_dir, f"usr/share/doc/{name}") - lic_dir = os.path.join(build_dir, f"usr/share/licenses/{name}") - os.makedirs(bin_dir, exist_ok=True) - os.makedirs(doc_dir, exist_ok=True) - os.makedirs(lic_dir, exist_ok=True) - - subprocess.run(["install", "-m", "755", f"target/release/{name}", f"{bin_dir}/{name}"], check=True) - if os.path.exists("LICENSE"): - subprocess.run(["install", "-m", "644", "LICENSE", f"{lic_dir}/LICENSE"], check=True) - if os.path.exists("README.md"): - subprocess.run(["install", "-m", "644", "README.md", f"{doc_dir}/README.md"], check=True) - - installed_size = subprocess.check_output(["du", "-sb", build_dir]).decode().split()[0] - builddate = str(int(time.time())) - - pkginfo_lines = [ - f"pkgname = {name}", - f"pkgbase = {name}", - f"pkgver = {version}-{pkgrel}", - f"pkgdesc = {description}", - f"url = {repository}", - f"builddate = {builddate}", - f"packager = {author}", - f"size = {installed_size}", - f"arch = {arch}", - f"license = {license}", - ] - for dep in depends: - pkginfo_lines.append(f"depend = {dep}") - for optdep in optdepends: - pkginfo_lines.append(f"optdepend = {optdep}") - pkginfo_lines.append("makepkgopt = strip\n") - - with open(os.path.join(build_dir, ".PKGINFO"), "w") as f: - f.write("\n".join(pkginfo_lines)) - - os.makedirs("target/arch", exist_ok=True) - output_file = os.path.abspath(f"target/arch/{name}-{version}-{pkgrel}-{arch}.pkg.tar.zst") - subprocess.run(["tar", "--zstd", "-cf", output_file, ".PKGINFO", "usr"], cwd=build_dir, check=True) - print(f"Arch-Paket erfolgreich erstellt: {output_file}") - EOF + python3 scripts/package-arch.py - name: Publish Packages to Gitea Package Registry env: diff --git a/AGENTS.md b/AGENTS.md index b78793a..3be3543 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,6 +31,8 @@ DockerUpdate/ │ └── workflows/ │ ├── testing.yaml # CI/CD für testing-Branch (Tests, Testing-Packages & Preview-Release) │ └── main.yaml # CI/CD für main-Branch (Tests, Stable-Packages & Release) +├── scripts/ +│ └── package-arch.py # Hilfsskript zur Arch-Linux-Paketerstellung (.pkg.tar.zst) ├── Cargo.toml # Rust-Manifest, Abhängigkeiten und Metadaten für deb / generate-rpm / arch ├── Cargo.lock ├── LICENSE # GPL-3.0 Lizenztext @@ -103,6 +105,9 @@ cargo deb # Fedora / RPM-Paket (.rpm) erstellen (benötigt cargo-generate-rpm) cargo generate-rpm + +# Arch Linux-Paket (.pkg.tar.zst) erstellen +python3 scripts/package-arch.py ``` --- diff --git a/README.md b/README.md index 092e0e7..d89426d 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,8 @@ Die Paketkonfiguration und Abhängigkeiten (`sudo`, `docker.io | docker-ce`) sin ### 2. Arch Linux (`.pkg.tar.zst`) Die Paketmetadaten und Abhängigkeiten für Arch Linux sind direkt in `Cargo.toml` unter `[package.metadata.arch]` -hinterlegt. Das Paket kann nach dem Kompilieren des Release-Builds über das folgende Skript (analog zu CI/CD) erzeugt +hinterlegt. Das Paket kann nach dem Kompilieren des Release-Builds über das Skript `scripts/package-arch.py` (analog zu +CI/CD) erzeugt werden: ```bash @@ -253,68 +254,7 @@ werden: cargo build --release # Arch Linux-Paket (.pkg.tar.zst) erstellen -python3 - <<'EOF' -import json, os, subprocess, tempfile, time - -metadata = json.loads(subprocess.check_output(["cargo", "metadata", "--format-version", "1", "--no-deps"])) -pkg = metadata["packages"][0] -name = pkg["name"] -version = pkg["version"] -description = pkg.get("description", "") -license = pkg.get("license", "") -repository = pkg.get("repository", "") -authors = pkg.get("authors", []) -author = authors[0] if authors else "Unknown" - -arch_meta = pkg.get("metadata", {}).get("arch", {}) -pkgrel = arch_meta.get("pkgrel", "1") -arch = arch_meta.get("arch", "x86_64") -depends = arch_meta.get("depends", ["gcc-libs", "glibc", "sudo", "docker"]) -optdepends = arch_meta.get("optdepends", ["docker-compose: Unterstützung für Docker Compose v1"]) - -with tempfile.TemporaryDirectory() as build_dir: - bin_dir = os.path.join(build_dir, "usr/bin") - doc_dir = os.path.join(build_dir, f"usr/share/doc/{name}") - lic_dir = os.path.join(build_dir, f"usr/share/licenses/{name}") - os.makedirs(bin_dir, exist_ok=True) - os.makedirs(doc_dir, exist_ok=True) - os.makedirs(lic_dir, exist_ok=True) - - subprocess.run(["install", "-m", "755", f"target/release/{name}", f"{bin_dir}/{name}"], check=True) - if os.path.exists("LICENSE"): - subprocess.run(["install", "-m", "644", "LICENSE", f"{lic_dir}/LICENSE"], check=True) - if os.path.exists("README.md"): - subprocess.run(["install", "-m", "644", "README.md", f"{doc_dir}/README.md"], check=True) - - installed_size = subprocess.check_output(["du", "-sb", build_dir]).decode().split()[0] - builddate = str(int(time.time())) - - pkginfo_lines = [ - f"pkgname = {name}", - f"pkgbase = {name}", - f"pkgver = {version}-{pkgrel}", - f"pkgdesc = {description}", - f"url = {repository}", - f"builddate = {builddate}", - f"packager = {author}", - f"size = {installed_size}", - f"arch = {arch}", - f"license = {license}", - ] - for dep in depends: - pkginfo_lines.append(f"depend = {dep}") - for optdep in optdepends: - pkginfo_lines.append(f"optdepend = {optdep}") - pkginfo_lines.append("makepkgopt = strip\n") - - with open(os.path.join(build_dir, ".PKGINFO"), "w") as f: - f.write("\n".join(pkginfo_lines)) - - os.makedirs("target/arch", exist_ok=True) - output_file = os.path.abspath(f"target/arch/{name}-{version}-{pkgrel}-{arch}.pkg.tar.zst") - subprocess.run(["tar", "--zstd", "-cf", output_file, ".PKGINFO", "usr"], cwd=build_dir, check=True) - print(f"Arch-Paket erfolgreich erstellt: {output_file}") -EOF +python3 scripts/package-arch.py # Installation des erstellten Pakets sudo pacman -U target/arch/docker-update-*.pkg.tar.zst diff --git a/scripts/package-arch.py b/scripts/package-arch.py new file mode 100755 index 0000000..5c78312 --- /dev/null +++ b/scripts/package-arch.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +import json +import os +import subprocess +import tempfile +import time + + +def main(): + metadata = json.loads(subprocess.check_output(["cargo", "metadata", "--format-version", "1", "--no-deps"])) + pkg = metadata["packages"][0] + name = pkg["name"] + version = pkg["version"] + description = pkg.get("description", "") + license_name = pkg.get("license", "") + repository = pkg.get("repository", "") + authors = pkg.get("authors", []) + author = authors[0] if authors else "Unknown" + + arch_meta = pkg.get("metadata", {}).get("arch", {}) + pkgrel = arch_meta.get("pkgrel", "1") + arch = arch_meta.get("arch", "x86_64") + depends = arch_meta.get("depends", ["gcc-libs", "glibc", "sudo", "docker"]) + optdepends = arch_meta.get("optdepends", ["docker-compose: Unterstützung für Docker Compose v1"]) + + with tempfile.TemporaryDirectory() as build_dir: + bin_dir = os.path.join(build_dir, "usr/bin") + doc_dir = os.path.join(build_dir, f"usr/share/doc/{name}") + lic_dir = os.path.join(build_dir, f"usr/share/licenses/{name}") + os.makedirs(bin_dir, exist_ok=True) + os.makedirs(doc_dir, exist_ok=True) + os.makedirs(lic_dir, exist_ok=True) + + subprocess.run(["install", "-m", "755", f"target/release/{name}", f"{bin_dir}/{name}"], check=True) + if os.path.exists("LICENSE"): + subprocess.run(["install", "-m", "644", "LICENSE", f"{lic_dir}/LICENSE"], check=True) + if os.path.exists("README.md"): + subprocess.run(["install", "-m", "644", "README.md", f"{doc_dir}/README.md"], check=True) + + installed_size = subprocess.check_output(["du", "-sb", build_dir]).decode().split()[0] + builddate = str(int(time.time())) + + pkginfo_lines = [ + f"pkgname = {name}", + f"pkgbase = {name}", + f"pkgver = {version}-{pkgrel}", + f"pkgdesc = {description}", + f"url = {repository}", + f"builddate = {builddate}", + f"packager = {author}", + f"size = {installed_size}", + f"arch = {arch}", + f"license = {license_name}", + ] + for dep in depends: + pkginfo_lines.append(f"depend = {dep}") + for optdep in optdepends: + pkginfo_lines.append(f"optdepend = {optdep}") + pkginfo_lines.append("makepkgopt = strip\n") + + with open(os.path.join(build_dir, ".PKGINFO"), "w") as f: + f.write("\n".join(pkginfo_lines)) + + os.makedirs("target/arch", exist_ok=True) + output_file = os.path.abspath(f"target/arch/{name}-{version}-{pkgrel}-{arch}.pkg.tar.zst") + subprocess.run(["tar", "--zstd", "-cf", output_file, ".PKGINFO", "usr"], cwd=build_dir, check=True) + print(f"Arch-Paket erfolgreich erstellt: {output_file}") + + +if __name__ == "__main__": + main() From 451abe83c091961e0d48800bb5b23f8efa19e083 Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Sun, 23 Aug 2026 18:54:22 +0200 Subject: [PATCH 4/4] Ref: Version auf 0.1.1 aktualisiert --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31c80f6..9caa770 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" [[package]] name = "docker-update" -version = "0.1.0" +version = "0.1.1" dependencies = [ "confy", "libc 1.0.0-alpha.4", diff --git a/Cargo.toml b/Cargo.toml index a536004..130ad7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "docker-update" -version = "0.1.0" +version = "0.1.1" edition = "2024" authors = ['DragonSlayer_14'] readme = "README.md"