suse
This commit is contained in:
1 parent
1f0daa0679
commit
f86a62b8b1
19 files changed
+388
-72
No files matched your search
@@ -1,11 +1,12 @@
|
||||
# RustProxy unified package builder
|
||||
|
||||
Wydanie wdrożeniowe (odchudzone): zawiera panel, konfigurację Nginx oraz wszystkie skrypty budowania Linux, OPNsense i FreeBSD. Nie zawiera pustych szkieletów projektów ani testów developerskich. Istniejące katalogi `data/`, `gpg/` i plik `.env` pozostają nienaruszone podczas rozpakowywania.
|
||||
Wydanie wdrożeniowe (odchudzone): zawiera panel, konfigurację Nginx oraz wszystkie skrypty budowania Linux, OPNsense i FreeBSD. Nie zawiera pustych szkieletów projektów; dołączono lekkie testy offline dla pakowania SUSE. Istniejące katalogi `data/`, `gpg/` i plik `.env` pozostają nienaruszone podczas rozpakowywania.
|
||||
|
||||
Jeden kontener buildera buduje z jednego commita RustProxy:
|
||||
|
||||
- Linux x86_64: DEB + podpisane repo APT (`rustproxy` **oraz osobny** `rustproxy-docker-agent`),
|
||||
- Linux x86_64: RPM + podpisane repo DNF/YUM (`rustproxy` **oraz osobny** `rustproxy-docker-agent`),
|
||||
- **SUSE / openSUSE / openSUSE Leap x86_64**: oddzielne paczki RPM dostosowane do `zypper`, podpisane repo `suse/x86_64` (`rustproxy` i `rustproxy-docker-agent`),
|
||||
- FreeBSD x86_64: cross-build bez VM FreeBSD,
|
||||
- OPNsense: `os-rustproxy-<version>_<revision>.pkg` + statyczne repo `pkg`,
|
||||
- **natywne FreeBSD** (domyślnie włączone): `rustproxy-<version>_<revision>.pkg` + osobny katalog repo `pkg` pod `/freebsd/` (bez zależności OPNsense).
|
||||
@@ -14,21 +15,22 @@ Jeden kontener buildera buduje z jednego commita RustProxy:
|
||||
|
||||
## Panel repozytorium (RustProxy Package Registry)
|
||||
|
||||
The dashboard interface defaults to **English (`en-GB`)**, including its dates, navigation, notifications, and installation instructions. The **Docker discovery agent** installation card is shown only for **Linux (DEB/RPM)**, never for OPNsense or native FreeBSD. Package listings/API also omit any stray agent PKG files for the FreeBSD channels.
|
||||
The dashboard interface defaults to **English (`en-GB`)**, including its dates, navigation, notifications, and installation instructions. The **Docker discovery agent** installation card is shown only for **Linux (DEB/RPM, including SUSE/Zypper)**, never for OPNsense or native FreeBSD. Package listings/API also omit any stray agent PKG files for the FreeBSD channels.
|
||||
|
||||
Strony startowe wszystkich trzech repozytoriów działają teraz jako **lekka aplikacja Python** (`dashboard/`) za istniejącym Nginx. Wygląd nawiązuje do panelu RustProxy 0.34.6 (ciemny, jasny i kremowy motyw). **APT, RPM i pkg są nadal obsługiwane bezpośrednio przez Nginx**, więc mechanizm aktualizacji paczek, ścieżki plików, podpisy GPG i atomowe przełączanie `current` nie zmieniają się.
|
||||
Strony startowe repozytoriów (Linux DNF/APT, SUSE, OPNsense, FreeBSD) działają jako **lekka aplikacja Python** (`dashboard/`) za istniejącym Nginx. Wygląd nawiązuje do panelu RustProxy 0.34.6 (ciemny, jasny i kremowy motyw). **APT, RPM i pkg są nadal obsługiwane bezpośrednio przez Nginx**, więc mechanizm aktualizacji paczek, ścieżki plików, podpisy GPG i atomowe przełączanie `current` nie zmieniają się.
|
||||
|
||||
Panel udostępnia:
|
||||
|
||||
- **Przegląd**: najnowsza wersja, czas buildu, commit, stan Linux / OPNsense / FreeBSD, statystyki i ostatnie paczki.
|
||||
- **Przegląd**: najnowsza wersja, czas buildu, commit, stan Linux / SUSE / OPNsense / FreeBSD, statystyki i ostatnie paczki.
|
||||
- **Paczki i wersje**: pełny katalog z nazwą, wersją, architekturą, datą, rozmiarem i linkiem pobrania; wyszukiwanie, sortowanie oraz filtry formatów/kanałów.
|
||||
- **Instalacja**: aktualne polecenia dla APT, DNF, OPNsense i natywnego FreeBSD oraz przyciski kopiowania.
|
||||
- **Instalacja**: aktualne polecenia dla APT, DNF, Zypper, OPNsense i natywnego FreeBSD oraz przyciski kopiowania.
|
||||
- **Repozytoria**: linki do metadanych, katalogów i klucza GPG. Automatyczne odświeżanie co **60 sekund** oraz ręczne odświeżenie.
|
||||
|
||||
Adresy paneli (bez zmian domen i portów):
|
||||
|
||||
```text
|
||||
REPOSITORY_URL/ Linux DEB + RPM
|
||||
REPOSITORY_URL/ Linux DEB + RPM (DNF) + SUSE RPM (Zypper)
|
||||
REPOSITORY_URL/suse/x86_64/ podpisane RPM i metadane dla SUSE/openSUSE
|
||||
OPNSENSE_REPOSITORY_URL/ OPNsense pkg
|
||||
OPNSENSE_REPOSITORY_URL/freebsd/ Native FreeBSD pkg
|
||||
```
|
||||
@@ -74,7 +76,7 @@ Dla `http://` bez portu `start.sh` dopisze domyślny port. Dla `https://` zakła
|
||||
Domyślne lokalne porty:
|
||||
|
||||
```text
|
||||
APT/RPM: 18765 -> nginx :8080
|
||||
APT/RPM/Zypper: 18765 -> nginx :8080
|
||||
OPNsense: 18766 -> nginx :8081
|
||||
```
|
||||
|
||||
@@ -97,8 +99,8 @@ opn-rustproxy.linuxiarz.pl -> http://builder:18766
|
||||
cargo test |
|
||||
cargo build +---+---+
|
||||
go test/build agent | |
|
||||
2x DEB + 2x RPM | |
|
||||
APT + DNF OPNsense FreeBSD native*
|
||||
2x DEB + 2x RPM + 2x SUSE RPM | |
|
||||
APT + DNF + Zypper OPNsense FreeBSD native*
|
||||
| | |
|
||||
v v v
|
||||
publikacja Linux os-rustproxy rustproxy.pkg
|
||||
@@ -107,7 +109,7 @@ opn-rustproxy.linuxiarz.pl -> http://builder:18766
|
||||
* FreeBSD native: enabled by default; FREEBSD_NATIVE_ENABLED=0 disables it
|
||||
```
|
||||
|
||||
`cargo test` i `go test ./...` (agenta) należą tylko do gałęzi Linux. Jeśli testy nie przejdą, DEB/RPM nie są publikowane, ale builder nadal uruchamia cross-build FreeBSD i może opublikować repo OPNsense. Stan jest śledzony osobno w `last_linux_commit`, `last_opnsense_commit` i (jeśli włączone) `last_freebsd_commit`; kolejny cykl ponawia tylko brakującą gałąź.
|
||||
`cargo test` i `go test ./...` (agenta) należą tylko do gałęzi Linux. Jeśli testy nie przejdą, DEB/RPM/SUSE nie są publikowane, ale builder nadal uruchamia cross-build FreeBSD i może opublikować repo OPNsense. Stan jest śledzony osobno w `last_linux_commit`, `last_opnsense_commit` i (jeśli włączone) `last_freebsd_commit`; kolejny cykl ponawia tylko brakującą gałąź.
|
||||
|
||||
## Docker Agent: osobne pakiety Linux
|
||||
|
||||
@@ -120,9 +122,11 @@ data/packages/deb/rustproxy_<version>-<release>_amd64.deb
|
||||
data/packages/deb/rustproxy-docker-agent_<version>-<release>_amd64.deb
|
||||
data/packages/rpm/x86_64/rustproxy-<version>-<release>.x86_64.rpm
|
||||
data/packages/rpm/x86_64/rustproxy-docker-agent-<version>-<release>.x86_64.rpm
|
||||
data/packages/suse/x86_64/rustproxy-<version>-<release>.x86_64.rpm
|
||||
data/packages/suse/x86_64/rustproxy-docker-agent-<version>-<release>.x86_64.rpm
|
||||
```
|
||||
|
||||
Obie paczki są podpisane istniejącym kluczem GPG repozytorium, a repo APT/DNF automatycznie zawiera oba produkty. Zmiana rewizji pakowania Linux (`PACKAGING_REVISION=5`) wymusza przebudowę także dla niezmienionego commita.
|
||||
Wszystkie pakiety (DEB, DNF RPM i SUSE RPM) są podpisane istniejącym kluczem GPG repozytorium; metadane obu repozytoriów RPM również są podpisane. Każde repo zawiera `rustproxy` i `rustproxy-docker-agent`. Zmiana rewizji pakowania Linux (`PACKAGING_REVISION=6`) wymusza przebudowę także dla niezmienionego commita.
|
||||
|
||||
Instalacja na hoście Docker (uruchom Docker Engine wcześniej):
|
||||
|
||||
@@ -147,6 +151,25 @@ Konfiguracja i klucze pozostają po aktualizacji: `/etc/rustproxy/docker-agent.e
|
||||
|
||||
W przypadku przechodzenia z instalacji ręcznej na paczkę: jednostka w `/etc/systemd/system/rustproxy-docker-agent.service` ma pierwszeństwo przed jednostką paczkowaną w `/usr/lib/systemd/system`. Należy zachować token/certyfikat, zatrzymać usługę, przenieść ręczną jednostkę poza katalog systemd i wykonać `systemctl daemon-reload` przed zainstalowaniem paczki. Głównego `rustproxy` i jego konfiguracji to nie dotyczy.
|
||||
|
||||
## SUSE / openSUSE / openSUSE Leap — RPM / Zypper
|
||||
|
||||
Gałąź Linux buduje dodatkowo **dwie natywne paczki RPM dla SUSE** z tego samego commita: `rustproxy` i `rustproxy-docker-agent`. Mają inne zależności niż paczki dla RHEL (m.in. `shadow` zamiast `shadow-utils`) i oddzielne, podpisane repozytorium `suse/x86_64` z metadanymi `repomd.xml.asc` oraz informacją `SUSE-BUILD-INFO.txt`. DNF/YUM nie jest zmieniany. Paczki SUSE mają kompresję gzip dla zgodności ze starszymi klientami RPM.
|
||||
|
||||
Dla systemów SUSE z Pythonem systemowym starszym niż 3.10 paczka serwera dopuszcza doinstalowanie wersjonowanego Pythona (z `pip`), np. `python311` i `python311-pip`. Lokalny wrapper `/usr/libexec/rustproxy/python3` jest dodawany wyłącznie do ścieżki `PATH` usługi RustProxy przez drop-in systemd. **Nie podmienia** systemowego `/usr/bin/python3`. Zalecane środowiska: **SLES 15 SP6/SP7 i nowsze**, **SLES 16**, **openSUSE Leap 15.6 i 16.x**, **openSUSE Tumbleweed** z architekturą x86_64 i `glibc >= 2.34`. Dla starszych wydań z glibc 2.31 (np. SLES 15 SP5) paczka nie jest kompatybilna bez osobnego builda na starszym toolchainie. Zależności dla konkretnej wersji sprawdź przez `zypper` przed wdrożeniem.
|
||||
|
||||
Instalacja po pierwszej publikacji (zamień `REPOSITORY_URL` na adres serwera pakietów):
|
||||
|
||||
```sh
|
||||
sudo rpm --import REPOSITORY_URL/repo-key.gpg
|
||||
sudo zypper addrepo --refresh --gpgcheck REPOSITORY_URL/suse/x86_64/ rustproxy-suse
|
||||
sudo zypper refresh rustproxy-suse
|
||||
sudo zypper install rustproxy
|
||||
# Opcjonalnie, na hoście z Docker Engine:
|
||||
sudo zypper install rustproxy-docker-agent
|
||||
```
|
||||
|
||||
Aktualizacja: `sudo zypper update rustproxy rustproxy-docker-agent` (agent tylko gdy zainstalowany). Pakiety i repozytorium są publikowane atomowo wraz z APT/DNF jako część gałęzi Linux. Jeśli builder miał już wydanie z tą samą wersją, `PACKAGING_REVISION=6` wymusi jednorazową przebudowę; gałęzie OPNsense/FreeBSD zachowują dotychczasowy stan. **Paczki RPM nie znajdują się w samym archiwum projektu** — powstają po uruchomieniu buildera na źródłach RustProxy.
|
||||
|
||||
## OPNsense repo
|
||||
|
||||
Publiczny root `OPNSENSE_REPOSITORY_URL` zawiera m.in.:
|
||||
@@ -206,7 +229,7 @@ FREEBSD_RUST_TOOLCHAIN=1.88.0
|
||||
APPLY_FREEBSD_PATCHES=1
|
||||
```
|
||||
|
||||
`RUN_LINUX_TESTS=1` jest domyślne. Testy są bramką tylko dla DEB/RPM i nie wpływają na gałąź OPNsense. Ustaw `0`, jeśli chcesz całkowicie pominąć testy Linux.
|
||||
`RUN_LINUX_TESTS=1` jest domyślne. Testy są bramką tylko dla DEB/RPM/SUSE i nie wpływają na gałąź OPNsense. Ustaw `0`, jeśli chcesz całkowicie pominąć testy Linux.
|
||||
|
||||
`OPNSENSE_RETENTION=10` zachowuje ostatnie 10 wersji pakietu dla danej serii/architektury OPNsense. `0` wyłącza usuwanie starych wersji.
|
||||
|
||||
@@ -292,7 +315,7 @@ configctl rustproxy start
|
||||
```
|
||||
|
||||
Obsługa miękkiego przeładowania zwiększa `OPNSENSE_PACKAGING_REVISION` do `4`.
|
||||
Pakowanie Linux ma `PACKAGING_REVISION=5`, a natywne FreeBSD `FREEBSD_NATIVE_PACKAGING_REVISION=2`. Każdy kanał otrzymuje osobną aktualizację przy zmianie swojej rewizji.
|
||||
Pakowanie Linux ma `PACKAGING_REVISION=6`, a natywne FreeBSD `FREEBSD_NATIVE_PACKAGING_REVISION=2`. Każdy kanał otrzymuje osobną aktualizację przy zmianie swojej rewizji.
|
||||
|
||||
## DEB/RPM: dostęp do plików strony i zewnętrznych certyfikatów
|
||||
|
||||
@@ -323,7 +346,7 @@ Test pakowania jest dostępny w pełnym repozytorium developerskim (nie jest do
|
||||
|
||||
**Uwaga FreeBSD:** `newsyslog` działa przez zmianę nazwy pliku, nie ma `copytruncate`. Pliki JSONL i inne logi otwarte bezpośrednio przez aplikację muszą być przez nią ponownie otwierane po rotacji. W przeciwnym razie proces może pisać do poprzedniego (przeniesionego) pliku; zachowanie nie jest identyczne z Linux. Reguły są instalowane, ale na działającym OPNsense należy zweryfikować sposób otwierania plików przez RustProxy.
|
||||
|
||||
Bieżąca rewizja pakowania Linux wynosi `PACKAGING_REVISION=5` i `OPNSENSE_PACKAGING_REVISION=4`; nowy kanał używa `FREEBSD_NATIVE_PACKAGING_REVISION=2`. `check-and-build.sh` sprawdza osobno rewizje pakowania Linux, OPNsense i FreeBSD native; nowa wersja samej wtyczki przebudowuje **tylko OPNsense**, nawet przy niezmienionym SHA aplikacji. Rewizja pakietu PKG zwiększy się automatycznie. W przypadku zmiany rewizji Linux analogicznie odświeżane są DEB/RPM. Konfiguracja w `/etc/logrotate.d/rustproxy` jest oznaczona jako `noreplace`, więc lokalna wersja zmodyfikowana przez administratora może zostać zachowana (zależnie od menedżera pakietów).
|
||||
Bieżąca rewizja pakowania Linux wynosi `PACKAGING_REVISION=6` i `OPNSENSE_PACKAGING_REVISION=4`; nowy kanał używa `FREEBSD_NATIVE_PACKAGING_REVISION=2`. `check-and-build.sh` sprawdza osobno rewizje pakowania Linux, OPNsense i FreeBSD native; nowa wersja samej wtyczki przebudowuje **tylko OPNsense**, nawet przy niezmienionym SHA aplikacji. Rewizja pakietu PKG zwiększy się automatycznie. W przypadku zmiany rewizji Linux analogicznie odświeżane są DEB/RPM. Konfiguracja w `/etc/logrotate.d/rustproxy` jest oznaczona jako `noreplace`, więc lokalna wersja zmodyfikowana przez administratora może zostać zachowana (zależnie od menedżera pakietów).
|
||||
|
||||
Kontrola po zainstalowaniu:
|
||||
|
||||
|
||||
+19
-17
@@ -1,13 +1,13 @@
|
||||
c92255b37b57e5356a10e88a8be14c856e9ef4372379c48423d69db7a1365625 .env.example
|
||||
2bfb200c5ddfa603746de1d5cb70ad43ca9c041bbc5ed361a9ec244c764bd4cf .env.example
|
||||
17298e7669ed82b4c98abfce803e1a3f0a265b0abdc2567bf1316aa15e98aad3 Dockerfile
|
||||
16821f51ece84db491da19b64f1129710fb46288e9807abe31e1000fe33f72df README.md
|
||||
bf55ac0d7435b5152c0f5af491d12977c795924a4fb0094569c66e49f7f961d3 README.md
|
||||
862263fa1f46c20f0d1e4dac5ffcc75abd55c08211b2c3864c5f8764b9d87793 dashboard/.dockerignore
|
||||
ced0339cb93478c2faf7b7b74215fe03375086e11ca957bd8892b52802fbbd3a dashboard/Dockerfile
|
||||
bd2ba3a11ee715ba41a94f3301bec4ce83d7177489190a755e165112df50f112 dashboard/app.py
|
||||
6447c64295ac62dd88d03fc796344f8702d6af54586720bb3e1240eb4f16db42 dashboard/web/app.js
|
||||
bc13583e4dc80d4914c7a82a06c1390b5118d4821c7d081f99d68a38e1156bac dashboard/app.py
|
||||
3b03fe39336fdfb9cd4abc2fa9a47c335afd72fcc4a868375b6fd93ab4e98a71 dashboard/web/app.js
|
||||
f1ac0fb5c4da97db09ff328cb86f4bc763fbdd84d7310d6e8e713be1c8707bb9 dashboard/web/favicon.svg
|
||||
df2483e63e8559f41da83712e94b5f216faff38f4786fd2c804eac4576645c23 dashboard/web/index.html
|
||||
2b5a34085be972372401abc9af16e2c14cc4e682fac448afb7c6f364d61b8649 dashboard/web/style.css
|
||||
05821c98841c783014496d88192639609408e7907c3ac15687e6aafd966c5687 dashboard/web/index.html
|
||||
94010e2be028d8153d1ffe9142e0a5aeb6d484c1edf5cb7318d70c5e32b5c985 dashboard/web/style.css
|
||||
ebb5e6eefe375ca1357d96f6a7344424c43df0bc51bc01ee66a459e54ef4b3c7 docker-compose.yml
|
||||
7da761300aef6cf22ce28c1c7a55414b692814023e4d540a3f3ec4111c62926c http/nginx.conf
|
||||
77e898aebb54f8acf39d3eb1fb348e7f41532da1b0a9e1820a717fdcde406f71 opnsense/patches/0.20.0/0001-opnsense-build.patch
|
||||
@@ -40,24 +40,26 @@ d4fc4b261c8252afbc6f403f828656cb7a49174de8cd239a233f5475d4cfeacd opnsense/plugi
|
||||
c8dde46217c008bfc31420c19ecbd31e3db6d71ee48f99be856ad40ca3c7f490 packaging/freebsd/rustproxy.rc
|
||||
79122afbd5964a87c0d933abe8b34745d4189e2a586d5918a82efbb9b2f50864 packaging/rustproxy-filesystem-access.md
|
||||
0f7970888117b4bc810ad3f6abc6796f189d34e4863875b2501785e689471be6 packaging/rustproxy.logrotate
|
||||
b5845f5510adcc3a63ccc710d8e893b33336051651917fa533e8b70df2e2991d packaging/suse-python3
|
||||
eee3cb8959cb90cd1b5b320ec4674892e5d1a987049d1028dae39c3bdc9f3dc7 scripts/apply-freebsd-patches.sh
|
||||
a869ece6aef358abd5901474c5c2201e74bfc56d24bfe9931ad5cc3837aea215 scripts/build-freebsd-release.sh
|
||||
d197c25fd346a2cd2a516434a8d9fab304ae6fbf3b215e4f9ea35e6efbc4f417 scripts/build-linux-release.sh
|
||||
01aaa5ecd63e15f3a5436ca394d26308f7616117233dcac8a74a6db73ab68142 scripts/build-opnsense-release.sh
|
||||
d1f2ac24d6742afed8d46fe827373cd4b3febebfcccf15f7265bed0cf8ec4c9c scripts/build-freebsd-release.sh
|
||||
345377ae905dd33e96ee1c7d92728fdd28bd7fab4b9ef448fbe2d105ec89771f scripts/build-linux-release.sh
|
||||
43a51a2734b5f2629598c3d84ca656480a46c2d09bc5b0b858e92aa6c89151ed scripts/build-opnsense-release.sh
|
||||
16bafbba1eb2000b42c754bae92fee43301e57e0859e2cef17be2550006ab111 scripts/build-opnsense.sh
|
||||
ed581639a606323d4e91e632bc40a9be7037570f91cdef4264e4db0ca130ee8e scripts/build-release.sh
|
||||
62fc5506b3786a1c943299a3d8107224dadb1b5bdee068acbbd4f649e7edc13b scripts/check-and-build.sh
|
||||
f5e2be2a0128e0d768c3ed4b151b21dfd39d35a688a4c3f6fc35877c3e2ee434 scripts/check-and-build.sh
|
||||
cba164bde8967045bfb76de7eff46d4407dfb7ed2bc861fbc600782551d1629e scripts/ensure-rust-toolchain.sh
|
||||
6cc8f506dd72189af34ed22334467e9af022690860edcc902e80b2ae976384ea scripts/entrypoint.sh
|
||||
a26a5ade31962030a63bad36479c153116a5a6c87e518fbe4cfad1746eb5f9cd scripts/entrypoint.sh
|
||||
c8402314cbcf87c30eb521a273a13628eccb78112acb85e0e85c9a7679550cca scripts/generate-freebsd-index.sh
|
||||
4220710396d0670d5c9ebcc31c6c4d59073d2b1c192f08268a3ea49164d1dcbd scripts/generate-index.sh
|
||||
d3193e4bbfe3d853db003610318815fdfc295fa501affffd3e18db4c7074a5a2 scripts/generate-index.sh
|
||||
80f49932346268f2cd63cbfe4814c666cd665661e82c25f2e99883929ecae0c0 scripts/generate-opnsense-index.sh
|
||||
094c603f30f6a41bddeedfefa9e2c260dc97f849f0a690475ebe128ce4b49475 scripts/generate-opnsense-repo.py
|
||||
40186599540f6886188abda5dac72bc85d15b9b71ce20788061131bfcd519cb7 scripts/init-storage.sh
|
||||
4fdb7f98e83a262e9ad22f08fd5dd776993009f7b22623dfa9b04f554e48ac3c scripts/lib.sh
|
||||
5aae7f35cc09576c07f8c57ce59cb6153840be15f187e0cf538d6987780f670a scripts/init-storage.sh
|
||||
13d66803d2125156ff64cb548cc5982210cd17161375eaebf5d0716a58a8ffcd scripts/lib.sh
|
||||
de4fbbb973d9cddb170ef1e9f4f6f7896018ed5e6184594c9636c0215adf5233 scripts/normalize-systemd-unit.py
|
||||
0eca8ef60f15dce0c5651fc8a55de10e0d9a11f3816f04153608abcbe2e2e1d8 scripts/package-freebsd.sh
|
||||
b098fa629f9fcc1a54baab3d46b28721eb582c314e084b3210259bf157c124a6 scripts/package-opnsense.sh
|
||||
4ad289bc2c0e400b39a8d1bcf86395d7576c88e71b678ba8b893ccb72ac35465 scripts/prepare-agent-package.sh
|
||||
46908bfac309688340be72edded60efaecd765aa151f520a2491952619f53a43 scripts/prepare-package.sh
|
||||
2b6d2dc393be6dd5ba5184e6ccd068a8faf193bcd280f349a4b1da890187a79f start.sh
|
||||
37233bdc0e14cdf32a18095fffc5fb219795ec7e838a112eb38fa29195a5d25c scripts/prepare-agent-package.sh
|
||||
fc8c6ae8e35fb68f4851344ddf014759b7bac4f2d07b6b8bb383b3289e3ca23b scripts/prepare-package.sh
|
||||
4bd555061e9a50faa05e2f8c095da2a6581e19b8d4c7fe01d791e59f5dd2f597 start.sh
|
||||
bc54e4b93202454c298d1e67aa68f126e25b8c2b20e62db46a89932fdacd2ba9 tests/test_suse.py
|
||||
+5
-2
@@ -26,9 +26,10 @@ PORT = int(os.environ.get("DASHBOARD_PORT", "8000"))
|
||||
CACHE_SECONDS = max(1, int(os.environ.get("DASHBOARD_CACHE_SECONDS", "15")))
|
||||
MAX_PACKAGES = 5000
|
||||
|
||||
SITES = ("linux", "opnsense", "freebsd")
|
||||
SITES = ("linux", "suse", "opnsense", "freebsd")
|
||||
META_PATHS = {
|
||||
"linux": Path("LINUX-BUILD-INFO.txt"),
|
||||
"suse": Path("SUSE-BUILD-INFO.txt"),
|
||||
"opnsense": Path("opnsense/BUILD-INFO.txt"),
|
||||
"freebsd": Path("freebsd/BUILD-INFO.txt"),
|
||||
}
|
||||
@@ -37,6 +38,7 @@ REPO_URLS = {
|
||||
"opnsense": os.environ.get("OPNSENSE_REPOSITORY_URL", "http://localhost:18766").rstrip("/"),
|
||||
}
|
||||
REPO_URLS["freebsd"] = REPO_URLS["opnsense"] + "/freebsd"
|
||||
REPO_URLS["suse"] = REPO_URLS["linux"] + "/suse"
|
||||
|
||||
DEB_FILENAME = re.compile(r"^(?P<name>.+?)_(?P<version>[^_]+)_(?P<arch>[^_]+)\.deb$")
|
||||
RPM_FILENAME = re.compile(
|
||||
@@ -98,7 +100,7 @@ def publication_info(current: Path, channel: str) -> dict[str, object]:
|
||||
"built_at": None,
|
||||
"date_source": "unknown",
|
||||
}
|
||||
if channel == "linux" and info["app_version"]:
|
||||
if channel in ("linux", "suse") and info["app_version"]:
|
||||
info["package_version"] = f"{info['app_version']}-{info['package_release']}" if info["package_release"] else info["app_version"]
|
||||
|
||||
stamp = raw.get("built_at", "")
|
||||
@@ -189,6 +191,7 @@ def generate_catalog(repository: Path = REPOSITORY) -> dict[str, object]:
|
||||
folders = (
|
||||
("linux", "deb", "linux", current / "apt" / "pool", "*.deb"),
|
||||
("linux", "rpm", "linux", current / "rpm" / "x86_64", "*.rpm"),
|
||||
("suse", "rpm", "suse", current / "suse" / "x86_64", "*.rpm"),
|
||||
("opnsense", "pkg", "opnsense", current / "opnsense", "*.pkg"),
|
||||
("freebsd", "pkg", "freebsd", current / "freebsd", "*.pkg"),
|
||||
)
|
||||
|
||||
+32
-9
@@ -3,8 +3,8 @@
|
||||
'use strict';
|
||||
|
||||
const el = (id) => document.getElementById(id);
|
||||
const CHANNEL_LABELS = {linux:'Linux',opnsense:'OPNsense',freebsd:'FreeBSD'};
|
||||
const INSTALL_NAMES = {deb:'Debian / Ubuntu',rpm:'RHEL / Rocky / Alma / Fedora',opnsense:'OPNsense',freebsd:'FreeBSD native'};
|
||||
const CHANNEL_LABELS = {linux:'Linux',suse:'SUSE / openSUSE',opnsense:'OPNsense',freebsd:'FreeBSD'};
|
||||
const INSTALL_NAMES = {deb:'Debian / Ubuntu',rpm:'RHEL / Rocky / Alma / Fedora',suse:'SUSE / openSUSE / Leap',opnsense:'OPNsense',freebsd:'FreeBSD native'};
|
||||
const SECTION_LABELS = {overview:'Overview',packages:'Packages & versions',install:'Installation',repository:'Repositories'};
|
||||
const esc = (value) => String(value ?? '').replace(/[&<>"']/g, (char) => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[char]));
|
||||
const collator = new Intl.Collator('en', {numeric:true,sensitivity:'base'});
|
||||
@@ -78,11 +78,12 @@
|
||||
function buildCard(build, channel) {
|
||||
const live = !!build?.published;
|
||||
const commit = build?.source_commit ? build.source_commit.slice(0,9) : '—';
|
||||
const subtitle = channel === 'linux' ? 'APT / DNF · amd64 + x86_64' : channel === 'opnsense'
|
||||
const subtitle = channel === 'linux' ? 'APT / DNF · amd64 + x86_64' : channel === 'suse'
|
||||
? 'RPM / Zypper · x86_64' : channel === 'opnsense'
|
||||
? `PKG · ${build?.opnsense_series || 'FreeBSD'}` : `PKG · ${build?.freebsd_abi || 'Native'}`;
|
||||
const version = build?.package_version || (live ? build?.app_version : '') || '—';
|
||||
return `<article class="build-card${live ? '' : ' off'}">
|
||||
<div class="build-card-top"><span>${esc(CHANNEL_LABELS[channel].toUpperCase())} / ${channel === 'linux' ? 'SIGNED' : 'PKG'}</span><span class="pill ${live ? 'live' : 'missing'}">${live ? 'PUBLISHED' : 'NOT BUILT'}</span></div>
|
||||
<div class="build-card-top"><span>${esc(CHANNEL_LABELS[channel].toUpperCase())} / ${['linux','suse'].includes(channel) ? 'SIGNED' : 'PKG'}</span><span class="pill ${live ? 'live' : 'missing'}">${live ? 'PUBLISHED' : 'NOT BUILT'}</span></div>
|
||||
<div class="build-card-version">${esc(version)}</div><div class="build-card-sub">${esc(subtitle)}</div>
|
||||
<div class="build-card-details"><div><small>BUILD DATE</small><strong title="${esc(dateLabel(build?.date_source))}">${esc(formatDate(build?.built_at))}</strong></div><div><small>COMMIT</small><strong class="commit">${esc(commit)}</strong></div></div>
|
||||
</article>`;
|
||||
@@ -109,7 +110,7 @@
|
||||
setText('hero-commit', main?.source_commit ? main.source_commit.slice(0,12) : '—');
|
||||
el('hero-date').title = dateLabel(main?.date_source);
|
||||
setText('stat-packages', formatNumber.format(data.summary?.packages_count || 0));
|
||||
setText('stat-channels', `${data.summary?.channels_published || 0} / 3`);
|
||||
setText('stat-channels', `${data.summary?.channels_published || 0} / 4`);
|
||||
setText('stat-date', formatShortDate(data.summary?.latest_build_at));
|
||||
setText('stat-version', heroVersion);
|
||||
setText('stat-release', main?.package_version ? `Package: ${main.package_version}` : 'No release published yet');
|
||||
@@ -121,8 +122,8 @@
|
||||
el('sidebar-status').classList.toggle('waiting', !ready);
|
||||
el('sidebar-status').querySelector('span').textContent = ready ? 'REPOSITORY ONLINE' : 'WAITING FOR DATA';
|
||||
const side = el('side-channels');
|
||||
side.innerHTML = ['linux','opnsense','freebsd'].map((channel) => `<span class="side-channel${data.builds[channel]?.published ? '' : ' disabled'}"><i class="tiny-dot"></i>${esc(CHANNEL_LABELS[channel])}<small>${channel === 'linux' ? 'APT / DNF' : 'PKG'}</small></span>`).join('');
|
||||
el('build-grid').innerHTML = ['linux','opnsense','freebsd'].map((channel) => buildCard(data.builds[channel],channel)).join('');
|
||||
side.innerHTML = ['linux','suse','opnsense','freebsd'].map((channel) => `<span class="side-channel${data.builds[channel]?.published ? '' : ' disabled'}"><i class="tiny-dot"></i>${esc(CHANNEL_LABELS[channel])}<small>${channel === 'linux' ? 'APT / DNF' : channel === 'suse' ? 'RPM / Zypper' : 'PKG'}</small></span>`).join('');
|
||||
el('build-grid').innerHTML = ['linux','suse','opnsense','freebsd'].map((channel) => buildCard(data.builds[channel],channel)).join('');
|
||||
const recent = data.packages.filter((pkg) => state.site === 'linux' || pkg.channel === state.site).slice(0,6);
|
||||
el('recent-rows').innerHTML = recent.length ? recent.map((pkg) => tableRow(pkg,true)).join('') : '<tr><td colspan="5" class="empty-table">No packages published yet. The catalog will populate after the first build.</td></tr>';
|
||||
}
|
||||
@@ -157,6 +158,7 @@
|
||||
function instructions(kind, data) {
|
||||
const urls = data.repository_urls || {};
|
||||
const linux = origin(urls.linux);
|
||||
const suse = origin(urls.suse || `${linux}/suse`);
|
||||
const opnsense = origin(urls.opnsense);
|
||||
const freebsd = origin(urls.freebsd);
|
||||
const distribution = data.apt_distribution || 'stable';
|
||||
@@ -204,6 +206,21 @@
|
||||
].join('\n'),
|
||||
};
|
||||
}
|
||||
if (kind === 'suse') {
|
||||
return {
|
||||
description:'Add the signed RPM repository with Zypper on SUSE Linux Enterprise, openSUSE Leap or Tumbleweed.',
|
||||
signature:'GPG SIGNED',
|
||||
note:'x86_64. Minimum glibc: 2.34; intended for SLES 15 SP6+, SLES 16+, Leap 15.6+, and Tumbleweed. Check Python >= 3.10 dependencies.',
|
||||
reference:`${suse}/x86_64/repodata/repomd.xml`,
|
||||
agent:'sudo zypper install rustproxy-docker-agent',
|
||||
code:[
|
||||
`sudo rpm --import ${linux}/repo-key.gpg`,
|
||||
`sudo zypper addrepo --refresh --gpgcheck ${suse}/x86_64/ rustproxy-suse`,
|
||||
'sudo zypper refresh rustproxy-suse',
|
||||
'sudo zypper install rustproxy',
|
||||
].join('\n'),
|
||||
};
|
||||
}
|
||||
if (kind === 'opnsense') {
|
||||
return {
|
||||
description:'Fetch the pkg repository configuration and install the os-rustproxy plugin.',
|
||||
@@ -252,7 +269,7 @@
|
||||
setText('install-command', instructionsData.code);
|
||||
setText('install-note', instructionsData.note);
|
||||
// Docker discovery agent is only built for Linux DEB/RPM.
|
||||
const hasDockerAgent = (kind === 'deb' || kind === 'rpm') && !!instructionsData.agent;
|
||||
const hasDockerAgent = (kind === 'deb' || kind === 'rpm' || kind === 'suse') && !!instructionsData.agent;
|
||||
el('agent-card').hidden = !hasDockerAgent;
|
||||
el('install-extra-grid').classList.toggle('single-card', !hasDockerAgent);
|
||||
setText('trust-index', hasDockerAgent ? '02' : '01');
|
||||
@@ -279,6 +296,12 @@
|
||||
{name:'RPM repomd.xml',url:`${url.linux}/rpm/x86_64/repodata/repomd.xml`},
|
||||
{name:'Build info',url:`${url.linux}/LINUX-BUILD-INFO.txt`},
|
||||
],true),
|
||||
endpointsCard('SUSE / openSUSE','GPG SIGNED',url.suse,[
|
||||
{name:'GPG public key',url:`${url.linux}/repo-key.gpg`},
|
||||
{name:'RPM repomd.xml',url:`${url.suse}/x86_64/repodata/repomd.xml`},
|
||||
{name:'Metadata signature',url:`${url.suse}/x86_64/repodata/repomd.xml.asc`},
|
||||
{name:'Build info',url:`${url.linux}/SUSE-BUILD-INFO.txt`},
|
||||
],true),
|
||||
endpointsCard('OPNsense','UNSIGNED PKG',url.opnsense,[
|
||||
{name:'RustProxy.conf',url:`${url.opnsense}/RustProxy.conf`},
|
||||
{name:'meta.conf',url:`${url.opnsense}/meta.conf`},
|
||||
@@ -292,7 +315,7 @@
|
||||
{name:'Build info',url:`${url.freebsd}/BUILD-INFO.txt`},
|
||||
],false),
|
||||
].join('');
|
||||
el('metadata-table').innerHTML = ['linux','opnsense','freebsd'].map((channel) => {
|
||||
el('metadata-table').innerHTML = ['linux','suse','opnsense','freebsd'].map((channel) => {
|
||||
const b = data.builds[channel] || {};
|
||||
const rows = [
|
||||
['APPLICATION VERSION',b.app_version || '—','latest-value'],
|
||||
|
||||
@@ -27,12 +27,13 @@
|
||||
<div class="sidebar-label sidebar-label--second">AVAILABLE CHANNELS</div>
|
||||
<div class="side-channels" id="side-channels">
|
||||
<span class="side-channel"><i class="tiny-dot"></i> Linux <small>APT / DNF</small></span>
|
||||
<span class="side-channel"><i class="tiny-dot"></i> SUSE / openSUSE <small>RPM / Zypper</small></span>
|
||||
<span class="side-channel"><i class="tiny-dot"></i> OPNsense <small>PKG</small></span>
|
||||
<span class="side-channel"><i class="tiny-dot"></i> FreeBSD <small>PKG</small></span>
|
||||
</div>
|
||||
<div class="sidebar-bottom">
|
||||
<div class="small-label">REPOSITORY ENGINE</div>
|
||||
<p>Python / HTTP API<br>Nginx / Signed APT + RPM<br>FreeBSD pkg catalog</p>
|
||||
<p>Python / HTTP API<br>Nginx / Signed APT + RPM + SUSE<br>FreeBSD pkg catalog</p>
|
||||
<div class="local-tag" id="sidebar-status"><i></i><span>WAITING FOR DATA</span></div>
|
||||
<div class="copyright">© RustProxy <span id="year"></span></div>
|
||||
</div>
|
||||
@@ -79,7 +80,7 @@
|
||||
<div class="pipeline-connector"></div>
|
||||
<div class="pipeline-step"><span class="step-index">02</span><span class="step-info"><b>Build / package</b><small>Rust + Go + FreeBSD</small></span><span class="step-right">CI <span>↗</span></span></div>
|
||||
<div class="pipeline-connector"></div>
|
||||
<div class="pipeline-step"><span class="step-index">03</span><span class="step-info"><b>Repository publish</b><small>APT / RPM / PKG</small></span><span class="step-right step-success">LIVE <span>●</span></span></div>
|
||||
<div class="pipeline-step"><span class="step-index">03</span><span class="step-info"><b>Repository publish</b><small>APT / RPM / Zypper / PKG</small></span><span class="step-right step-success">LIVE <span>●</span></span></div>
|
||||
</div>
|
||||
<div class="pipeline-footer">Last sync <span id="pipeline-updated">—</span></div>
|
||||
</div>
|
||||
@@ -87,7 +88,7 @@
|
||||
|
||||
<div class="stats-grid" aria-label="Repository statistics">
|
||||
<div class="stat"><span>01 / CATALOG PACKAGES</span><strong id="stat-packages">—</strong><small>All published artifacts</small></div>
|
||||
<div class="stat"><span>02 / ACTIVE CHANNELS</span><strong id="stat-channels">—</strong><small>Linux · OPNsense · FreeBSD</small></div>
|
||||
<div class="stat"><span>02 / ACTIVE CHANNELS</span><strong id="stat-channels">—</strong><small>Linux · SUSE · OPNsense · FreeBSD</small></div>
|
||||
<div class="stat"><span>03 / LATEST BUILD</span><strong class="stat-date" id="stat-date">—</strong><small id="stat-date-sub">Latest publication time</small></div>
|
||||
<div class="stat"><span>04 / CURRENT VERSION</span><strong id="stat-version">—</strong><small id="stat-release">Application version</small></div>
|
||||
</div>
|
||||
@@ -103,16 +104,16 @@
|
||||
|
||||
<section class="view" id="view-packages" aria-labelledby="packages-title" hidden>
|
||||
<div class="page-head compact-head"><div><div class="eyebrow"><span class="eyebrow-line"></span> ARTIFACT EXPLORER <span class="eyebrow-separator">/</span> VERSIONS</div><h1 id="packages-title">Package <em>catalog.</em></h1><p class="lead">Search, filter, sort, and download published files. All details are read directly from the current repository.</p></div><div class="count-pill" id="packages-total">0 packages</div></div>
|
||||
<div class="filter-panel"><div class="search-field"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m16.5 16.5 4 4"/></svg><input id="search-input" type="search" placeholder="Search by name, version, architecture..." aria-label="Search packages" autocomplete="off"></div><label class="filter-input">CHANNEL<select id="filter-channel"><option value="all">All</option><option value="linux">Linux</option><option value="opnsense">OPNsense</option><option value="freebsd">FreeBSD</option></select></label><label class="filter-input">FORMAT<select id="filter-format"><option value="all">All</option><option value="DEB">DEB</option><option value="RPM">RPM</option><option value="PKG">PKG</option></select></label><label class="filter-input">SORT BY<select id="filter-sort"><option value="date">Newest first</option><option value="version">Version ↓</option><option value="name">Name A–Z</option><option value="size">Size ↓</option></select></label></div>
|
||||
<div class="filter-panel"><div class="search-field"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m16.5 16.5 4 4"/></svg><input id="search-input" type="search" placeholder="Search by name, version, architecture..." aria-label="Search packages" autocomplete="off"></div><label class="filter-input">CHANNEL<select id="filter-channel"><option value="all">All</option><option value="linux">Linux</option><option value="suse">SUSE / openSUSE</option><option value="opnsense">OPNsense</option><option value="freebsd">FreeBSD</option></select></label><label class="filter-input">FORMAT<select id="filter-format"><option value="all">All</option><option value="DEB">DEB</option><option value="RPM">RPM</option><option value="PKG">PKG</option></select></label><label class="filter-input">SORT BY<select id="filter-sort"><option value="date">Newest first</option><option value="version">Version ↓</option><option value="name">Name A–Z</option><option value="size">Size ↓</option></select></label></div>
|
||||
<div class="result-topline"><span id="filter-count">Loading…</span><span>Versions and dates are read from packages and build metadata</span></div>
|
||||
<div class="card catalog-card"><div class="table-scroller"><table class="data-table data-table--catalog"><thead><tr><th>PACKAGE</th><th>CHANNEL</th><th>VERSION</th><th>BUILD DATE</th><th>SIZE</th><th>DOWNLOAD</th></tr></thead><tbody id="catalog-rows"><tr><td colspan="6" class="empty-table">Loading data…</td></tr></tbody></table></div><div class="catalog-bottom"><span id="result-range">—</span><button class="quiet show-more" id="show-more" hidden>Load 25 more ↓</button></div></div>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-install" aria-labelledby="install-title" hidden>
|
||||
<div class="page-head compact-head"><div><div class="eyebrow"><span class="eyebrow-line"></span> GET STARTED <span class="eyebrow-separator">/</span> INSTALLATION</div><h1 id="install-title">Install <em>RustProxy.</em></h1><p class="lead">Ready-to-run commands to add the repository and install RustProxy. Select a platform and copy the commands to your terminal.</p></div></div>
|
||||
<div class="install-tabs" role="tablist" aria-label="Choose operating system"><button role="tab" aria-selected="true" data-install="deb" class="install-tab active">Debian / Ubuntu <small>APT · amd64</small></button><button role="tab" aria-selected="false" data-install="rpm" class="install-tab">RHEL / Rocky <small>DNF · x86_64</small></button><button role="tab" aria-selected="false" data-install="opnsense" class="install-tab">OPNsense <small>FreeBSD pkg</small></button><button role="tab" aria-selected="false" data-install="freebsd" class="install-tab">FreeBSD <small>Native pkg</small></button></div>
|
||||
<div class="install-tabs" role="tablist" aria-label="Choose operating system"><button role="tab" aria-selected="true" data-install="deb" class="install-tab active">Debian / Ubuntu <small>APT · amd64</small></button><button role="tab" aria-selected="false" data-install="rpm" class="install-tab">RHEL / Rocky <small>DNF · x86_64</small></button><button role="tab" aria-selected="false" data-install="suse" class="install-tab">SUSE / openSUSE <small>Zypper · x86_64</small></button><button role="tab" aria-selected="false" data-install="opnsense" class="install-tab">OPNsense <small>FreeBSD pkg</small></button><button role="tab" aria-selected="false" data-install="freebsd" class="install-tab">FreeBSD <small>Native pkg</small></button></div>
|
||||
<div class="install-card card"><div class="install-card-head"><div><span class="section-index">TERMINAL / INSTALL</span><h2 id="install-tab-title">Debian / Ubuntu</h2><p id="install-description">Add the signed APT repository and install the server.</p></div><span class="pill" id="install-signature">GPG SIGNED</span></div><div class="code-window"><div class="code-topbar"><span><i class="tiny-dot"></i><i class="tiny-dot"></i><i class="tiny-dot"></i> <b>install.sh</b></span><button class="copy-code" id="copy-install" data-copy-target="install-command">Copy <span>↗</span></button></div><pre><code id="install-command">Preparing commands…</code></pre></div><div class="install-foot"><span id="install-note">Requires sudo privileges.</span><a id="install-reference" class="text-link" href="#">Repository files ↗</a></div></div>
|
||||
<div class="install-extra-grid single-card" id="install-extra-grid"><div class="card hint-card" id="agent-card" hidden><span class="hint-icon">01</span><h3>Docker discovery agent</h3><p>Linux also provides a separate <code>rustproxy-docker-agent</code> package. Install it separately from the main server.</p><div class="inline-command"><code id="agent-command">sudo apt install rustproxy-docker-agent</code><button data-copy-target="agent-command" class="quiet">Copy</button></div></div><div class="card hint-card"><span class="hint-icon" id="trust-index">01</span><h3>Signatures and trust</h3><p>APT and DNF repositories are GPG-signed. OPNsense and native FreeBSD currently use <code>signature_type: none</code> catalogs; use a trusted HTTPS source.</p></div></div>
|
||||
<div class="install-extra-grid single-card" id="install-extra-grid"><div class="card hint-card" id="agent-card" hidden><span class="hint-icon">01</span><h3>Docker discovery agent</h3><p>Linux also provides a separate <code>rustproxy-docker-agent</code> package. Install it separately from the main server.</p><div class="inline-command"><code id="agent-command">sudo apt install rustproxy-docker-agent</code><button data-copy-target="agent-command" class="quiet">Copy</button></div></div><div class="card hint-card"><span class="hint-icon" id="trust-index">01</span><h3>Signatures and trust</h3><p>APT, DNF and SUSE/Zypper repositories are GPG-signed. OPNsense and native FreeBSD currently use <code>signature_type: none</code> catalogs; use a trusted HTTPS source.</p></div></div>
|
||||
</section>
|
||||
|
||||
<section class="view" id="view-repository" aria-labelledby="repository-title" hidden>
|
||||
|
||||
@@ -168,7 +168,7 @@ h3{font-size:16px;font-weight:575;letter-spacing:-.3px}
|
||||
.text-link{background:none;border:0;color:var(--accent);font:11px var(--mono);padding:4px 0;white-space:nowrap}
|
||||
.text-link:hover{text-decoration:underline}
|
||||
.text-link span{margin-left:5px}
|
||||
.build-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
|
||||
.build-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}
|
||||
.build-card,.skeleton-card{background:var(--panel);border:1px solid var(--line);padding:19px 22px 20px;min-width:0;position:relative}
|
||||
.build-card:before{content:"";position:absolute;inset:0 auto 0 0;width:2px;background:var(--green);opacity:.75}
|
||||
.build-card.off:before{background:var(--separator)}
|
||||
@@ -224,7 +224,7 @@ h3{font-size:16px;font-weight:575;letter-spacing:-.3px}
|
||||
.result-topline span:first-child{color:var(--green)}
|
||||
.catalog-bottom{display:flex;gap:15px;align-items:center;justify-content:space-between;padding:14px 19px;border-top:1px solid var(--line);color:var(--text-subtle);font:10px var(--mono)}
|
||||
.show-more{font-size:11px;padding:8px 13px}
|
||||
.install-tabs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-bottom:16px}
|
||||
.install-tabs{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:10px;margin-bottom:16px}
|
||||
.install-tab{display:flex;flex-direction:column;align-items:flex-start;gap:6px;padding:16px 18px;border:1px solid var(--line);border-bottom:2px solid var(--line);background:var(--panel);color:var(--muted);font-size:13px;font-weight:600;text-align:left;transition:border-color .14s,color .14s}
|
||||
.install-tab small{font:10px var(--mono);font-weight:400;color:var(--text-subtle)}
|
||||
.install-tab:hover{border-color:var(--border-hover);color:var(--text)}
|
||||
@@ -255,7 +255,7 @@ h3{font-size:16px;font-weight:575;letter-spacing:-.3px}
|
||||
.inline-command{display:flex;align-items:center;justify-content:space-between;gap:8px;border:1px solid var(--line);background:var(--code-bg);padding:9px 12px;margin-top:15px}
|
||||
.inline-command code{font-size:10px;overflow:auto;white-space:nowrap}
|
||||
.inline-command button{font-size:10px;padding:5px 8px}
|
||||
.endpoints-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
|
||||
.endpoints-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}
|
||||
.endpoint-card{border:1px solid var(--line);background:var(--panel);padding:23px 22px}
|
||||
.endpoint-card-top{display:flex;align-items:center;justify-content:space-between;gap:9px;margin-bottom:19px}
|
||||
.endpoint-card h2{font-size:20px;letter-spacing:-.4px;margin:0}
|
||||
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
# SUSE 15 can keep an old /usr/bin/python3 alongside versioned Python >= 3.10.
|
||||
# Restrict this wrapper to RustProxy's service PATH; never replace system Python.
|
||||
for executable in /usr/bin/python3.14 /usr/bin/python3.13 /usr/bin/python3.12 /usr/bin/python3.11 /usr/bin/python3.10 /usr/bin/python3; do
|
||||
if [ -x "$executable" ] && "$executable" -c 'import sys; sys.exit(sys.version_info < (3, 10))' >/dev/null 2>&1; then
|
||||
exec "$executable" "$@"
|
||||
fi
|
||||
done
|
||||
echo 'RustProxy requires Python 3.10 or newer; install a supported python3XX package.' >&2
|
||||
exit 127
|
||||
@@ -47,7 +47,7 @@ FREEBSD_PACKAGE_FILE="$OUT/rustproxy-${FREEBSD_PACKAGE_VERSION}.pkg"
|
||||
"$BUILDER_ROOT/scripts/package-freebsd.sh" \
|
||||
"$SRC" "$FREEBSD_BINARY" "$FREEBSD_PACKAGE_FILE" "$FREEBSD_PACKAGE_VERSION"
|
||||
|
||||
mkdir -p "$RELEASE_DIR/apt" "$RELEASE_DIR/rpm/x86_64" "$RELEASE_DIR/opnsense" "$RELEASE_DIR/freebsd"
|
||||
mkdir -p "$RELEASE_DIR/apt" "$RELEASE_DIR/rpm/x86_64" "$RELEASE_DIR/suse/x86_64" "$RELEASE_DIR/opnsense" "$RELEASE_DIR/freebsd"
|
||||
CURRENT_TARGET=""
|
||||
if [[ -L "$REPOSITORY/current" ]]; then
|
||||
CURRENT_LINK=$(readlink "$REPOSITORY/current")
|
||||
@@ -56,12 +56,12 @@ fi
|
||||
|
||||
log 'staging native FreeBSD repository snapshot'
|
||||
if [[ -n "$CURRENT_TARGET" ]]; then
|
||||
for component in apt rpm opnsense freebsd; do
|
||||
for component in apt rpm suse opnsense freebsd; do
|
||||
if [[ -d "$CURRENT_TARGET/$component" ]]; then
|
||||
rsync -a --delete --link-dest="$CURRENT_TARGET/$component"/ "$CURRENT_TARGET/$component"/ "$RELEASE_DIR/$component"/
|
||||
fi
|
||||
done
|
||||
for copied in repo-key.gpg index.html LINUX-BUILD-INFO.txt; do
|
||||
for copied in repo-key.gpg index.html LINUX-BUILD-INFO.txt SUSE-BUILD-INFO.txt; do
|
||||
if [[ -f "$CURRENT_TARGET/$copied" ]]; then
|
||||
cp -a "$CURRENT_TARGET/$copied" "$RELEASE_DIR/$copied"
|
||||
fi
|
||||
|
||||
@@ -124,6 +124,9 @@ DEB_FILE="$OUT/${PACKAGE_NAME}_${VERSION}-${PACKAGE_RELEASE}_amd64.deb"
|
||||
RPM_FILE="$OUT/${PACKAGE_NAME}-${VERSION}-${PACKAGE_RELEASE}.x86_64.rpm"
|
||||
AGENT_DEB_FILE="$OUT/rustproxy-docker-agent_${VERSION}-${PACKAGE_RELEASE}_amd64.deb"
|
||||
AGENT_RPM_FILE="$OUT/rustproxy-docker-agent-${VERSION}-${PACKAGE_RELEASE}.x86_64.rpm"
|
||||
SUSE_RPM_FILE="$OUT/suse/${PACKAGE_NAME}-${VERSION}-${PACKAGE_RELEASE}.x86_64.rpm"
|
||||
SUSE_AGENT_RPM_FILE="$OUT/suse/rustproxy-docker-agent-${VERSION}-${PACKAGE_RELEASE}.x86_64.rpm"
|
||||
mkdir -p "$OUT/suse"
|
||||
|
||||
log "creating RustProxy and Docker Agent deb packages"
|
||||
nfpm package --config "$PKG/nfpm-deb.yaml" --packager deb --target "$DEB_FILE"
|
||||
@@ -131,11 +134,14 @@ nfpm package --config "$AGENT_PKG/nfpm-deb.yaml" --packager deb --target "$AGENT
|
||||
log "creating RustProxy and Docker Agent rpm packages"
|
||||
nfpm package --config "$PKG/nfpm-rpm.yaml" --packager rpm --target "$RPM_FILE"
|
||||
nfpm package --config "$AGENT_PKG/nfpm-rpm.yaml" --packager rpm --target "$AGENT_RPM_FILE"
|
||||
log "creating SUSE/openSUSE RPM packages"
|
||||
nfpm package --config "$PKG/nfpm-suse.yaml" --packager rpm --target "$SUSE_RPM_FILE"
|
||||
nfpm package --config "$AGENT_PKG/nfpm-suse.yaml" --packager rpm --target "$SUSE_AGENT_RPM_FILE"
|
||||
|
||||
for deb in "$DEB_FILE" "$AGENT_DEB_FILE"; do
|
||||
ar t "$deb" | grep '^_gpgorigin$' >/dev/null || fatal "DEB package is not signed: $deb"
|
||||
done
|
||||
for rpm_file in "$RPM_FILE" "$AGENT_RPM_FILE"; do
|
||||
for rpm_file in "$RPM_FILE" "$AGENT_RPM_FILE" "$SUSE_RPM_FILE" "$SUSE_AGENT_RPM_FILE"; do
|
||||
rpm -qpi "$rpm_file" | awk -F: '/^Signature/ && $0 !~ /\(none\)/ {ok=1} END{exit !ok}' \
|
||||
|| fatal "RPM package is not signed: $rpm_file"
|
||||
done
|
||||
@@ -143,6 +149,7 @@ log "Linux package signatures verified"
|
||||
|
||||
cp -f "$DEB_FILE" "$AGENT_DEB_FILE" "$DATA_DIR/packages/deb/"
|
||||
cp -f "$RPM_FILE" "$AGENT_RPM_FILE" "$DATA_DIR/packages/rpm/x86_64/"
|
||||
cp -f "$SUSE_RPM_FILE" "$SUSE_AGENT_RPM_FILE" "$DATA_DIR/packages/suse/x86_64/"
|
||||
|
||||
log "updating aptly internal repository"
|
||||
aptly -config="$APTLY_CONF" repo add -force-replace package-builder "$DEB_FILE" "$AGENT_DEB_FILE" >/dev/null
|
||||
@@ -167,7 +174,7 @@ APT_PUBLIC="$DATA_DIR/aptly/public"
|
||||
gpg --batch --verify "$APT_PUBLIC/dists/$REPO_DISTRIBUTION/Release.gpg" "$APT_PUBLIC/dists/$REPO_DISTRIBUTION/Release" >/dev/null 2>&1 \
|
||||
|| fatal "APT Release signature verification failed"
|
||||
|
||||
mkdir -p "$RELEASE_DIR/apt" "$RELEASE_DIR/rpm/x86_64" "$RELEASE_DIR/opnsense" "$RELEASE_DIR/freebsd"
|
||||
mkdir -p "$RELEASE_DIR/apt" "$RELEASE_DIR/rpm/x86_64" "$RELEASE_DIR/suse/x86_64" "$RELEASE_DIR/opnsense" "$RELEASE_DIR/freebsd"
|
||||
CURRENT_TARGET=""
|
||||
if [[ -L "$REPOSITORY/current" ]]; then
|
||||
CURRENT_LINK=$(readlink "$REPOSITORY/current")
|
||||
@@ -185,17 +192,22 @@ fi
|
||||
|
||||
rsync -a --delete "$APT_PUBLIC"/ "$RELEASE_DIR/apt"/
|
||||
rsync -a --delete "$DATA_DIR/packages/rpm"/ "$RELEASE_DIR/rpm"/
|
||||
rm -rf "$RELEASE_DIR/rpm/x86_64/repodata"
|
||||
createrepo_c --update "$RELEASE_DIR/rpm/x86_64" >/dev/null
|
||||
rsync -a --delete "$DATA_DIR/packages/suse"/ "$RELEASE_DIR/suse"/
|
||||
for rpm_root in "$RELEASE_DIR/rpm/x86_64" "$RELEASE_DIR/suse/x86_64"; do
|
||||
rm -rf "$rpm_root/repodata"
|
||||
createrepo_c --update "$rpm_root" >/dev/null
|
||||
done
|
||||
|
||||
GPG_SIGN_ARGS=(--batch --yes --pinentry-mode loopback)
|
||||
if [[ -r "$GPG_PASSPHRASE_FILE" ]]; then
|
||||
GPG_SIGN_ARGS+=(--passphrase-file "$GPG_PASSPHRASE_FILE")
|
||||
fi
|
||||
for rpm_root in "$RELEASE_DIR/rpm/x86_64" "$RELEASE_DIR/suse/x86_64"; do
|
||||
gpg "${GPG_SIGN_ARGS[@]}" --armor --detach-sign --local-user "$GPG_KEY_ID" \
|
||||
--output "$RELEASE_DIR/rpm/x86_64/repodata/repomd.xml.asc" "$RELEASE_DIR/rpm/x86_64/repodata/repomd.xml"
|
||||
gpg --batch --verify "$RELEASE_DIR/rpm/x86_64/repodata/repomd.xml.asc" "$RELEASE_DIR/rpm/x86_64/repodata/repomd.xml" >/dev/null 2>&1 \
|
||||
|| fatal "RPM metadata signature verification failed"
|
||||
--output "$rpm_root/repodata/repomd.xml.asc" "$rpm_root/repodata/repomd.xml"
|
||||
gpg --batch --verify "$rpm_root/repodata/repomd.xml.asc" "$rpm_root/repodata/repomd.xml" >/dev/null 2>&1 \
|
||||
|| fatal "RPM metadata signature verification failed: $rpm_root"
|
||||
done
|
||||
|
||||
gpg --batch --armor --export "$GPG_KEY_ID" > "$RELEASE_DIR/repo-key.gpg"
|
||||
[[ -s "$RELEASE_DIR/repo-key.gpg" ]] || fatal "public GPG key export failed"
|
||||
@@ -206,15 +218,20 @@ built_at=$(date -u "+%Y-%m-%dT%H:%M:%SZ")
|
||||
package_release=$PACKAGE_RELEASE
|
||||
packaging_revision=$PACKAGING_REVISION
|
||||
linux_packages=$PACKAGE_NAME,rustproxy-docker-agent
|
||||
linux_rpm_flavors=dnf,suse
|
||||
source_url=$SOURCE_REPO
|
||||
source_ref=$SOURCE_BRANCH
|
||||
source_commit=$SHA
|
||||
build_reason=$BUILD_REASON
|
||||
INFO
|
||||
cp -f "$RELEASE_DIR/LINUX-BUILD-INFO.txt" "$RELEASE_DIR/SUSE-BUILD-INFO.txt"
|
||||
printf '%s\n' 'rpm_flavor=suse' 'platforms=SLES_15_SP6+,SLES_16+,Leap_15.6+,Tumbleweed' >> "$RELEASE_DIR/SUSE-BUILD-INFO.txt"
|
||||
|
||||
[[ -s "$RELEASE_DIR/index.html" ]]
|
||||
[[ -f "$RELEASE_DIR/apt/dists/$REPO_DISTRIBUTION/InRelease" ]]
|
||||
[[ -f "$RELEASE_DIR/rpm/x86_64/repodata/repomd.xml" ]]
|
||||
[[ -f "$RELEASE_DIR/suse/x86_64/repodata/repomd.xml" ]]
|
||||
[[ -s "$RELEASE_DIR/SUSE-BUILD-INFO.txt" ]]
|
||||
|
||||
log "publishing Linux repository branch"
|
||||
rm -f "$REPOSITORY/current.new"
|
||||
|
||||
@@ -50,7 +50,7 @@ OPNSENSE_PACKAGE_FILE="$OUT/os-rustproxy-${OPNSENSE_PACKAGE_VERSION}.pkg"
|
||||
/opt/rust-package-builder/scripts/package-opnsense.sh \
|
||||
"$SRC" "$FREEBSD_BINARY" "$OPNSENSE_PACKAGE_FILE" "$OPNSENSE_PACKAGE_VERSION"
|
||||
|
||||
mkdir -p "$RELEASE_DIR/apt" "$RELEASE_DIR/rpm/x86_64" "$RELEASE_DIR/opnsense" "$RELEASE_DIR/freebsd"
|
||||
mkdir -p "$RELEASE_DIR/apt" "$RELEASE_DIR/rpm/x86_64" "$RELEASE_DIR/suse/x86_64" "$RELEASE_DIR/opnsense" "$RELEASE_DIR/freebsd"
|
||||
CURRENT_TARGET=""
|
||||
if [[ -L "$REPOSITORY/current" ]]; then
|
||||
CURRENT_LINK=$(readlink "$REPOSITORY/current")
|
||||
@@ -59,12 +59,12 @@ fi
|
||||
|
||||
log "staging OPNsense repository snapshot"
|
||||
if [[ -n "$CURRENT_TARGET" ]]; then
|
||||
for component in apt rpm opnsense freebsd; do
|
||||
for component in apt rpm suse opnsense freebsd; do
|
||||
if [[ -d "$CURRENT_TARGET/$component" ]]; then
|
||||
rsync -a --delete --link-dest="$CURRENT_TARGET/$component"/ "$CURRENT_TARGET/$component"/ "$RELEASE_DIR/$component"/
|
||||
fi
|
||||
done
|
||||
for file in repo-key.gpg index.html LINUX-BUILD-INFO.txt; do
|
||||
for file in repo-key.gpg index.html LINUX-BUILD-INFO.txt SUSE-BUILD-INFO.txt; do
|
||||
if [[ -f "$CURRENT_TARGET/$file" ]]; then
|
||||
cp -a "$CURRENT_TARGET/$file" "$RELEASE_DIR/$file"
|
||||
fi
|
||||
|
||||
@@ -10,12 +10,16 @@ linux_release_complete_for_commit() {
|
||||
[[ -d "$CURRENT" ]] || return 1
|
||||
[[ -f "$CURRENT/apt/dists/$REPO_DISTRIBUTION/InRelease" ]] || return 1
|
||||
[[ -f "$CURRENT/rpm/x86_64/repodata/repomd.xml" ]] || return 1
|
||||
[[ -f "$CURRENT/suse/x86_64/repodata/repomd.xml" ]] || return 1
|
||||
[[ -f "$CURRENT/SUSE-BUILD-INFO.txt" ]] || return 1
|
||||
# Both standalone packages must exist in the current Linux snapshot.
|
||||
find "$CURRENT/rpm/x86_64" -maxdepth 1 -type f -name 'rustproxy-docker-agent-*.rpm' -print -quit | grep -q . || return 1
|
||||
find "$CURRENT/suse/x86_64" -maxdepth 1 -type f -name 'rustproxy-docker-agent-*.rpm' -print -quit | grep -q . || return 1
|
||||
find "$CURRENT/apt/pool" -type f -name 'rustproxy-docker-agent_*.deb' -print -quit | grep -q . || return 1
|
||||
# A new builder revision must repackage even when RustProxy's SHA is unchanged.
|
||||
[[ -f "$CURRENT/LINUX-BUILD-INFO.txt" ]] || return 1
|
||||
grep -Fqx "packaging_revision=$PACKAGING_REVISION" "$CURRENT/LINUX-BUILD-INFO.txt" || return 1
|
||||
grep -Fqx "packaging_revision=$PACKAGING_REVISION" "$CURRENT/SUSE-BUILD-INFO.txt" || return 1
|
||||
grep -Fq ',rustproxy-docker-agent' "$CURRENT/LINUX-BUILD-INFO.txt" || return 1
|
||||
|
||||
if grep -Fqx "source_commit=$sha" "$CURRENT/LINUX-BUILD-INFO.txt"; then
|
||||
|
||||
@@ -62,6 +62,7 @@ mkdir -p \
|
||||
"$DATA_DIR/go/cache" \
|
||||
"$DATA_DIR/work" \
|
||||
"$DATA_DIR/packages/rpm/x86_64" \
|
||||
"$DATA_DIR/packages/suse/x86_64" \
|
||||
"$DATA_DIR/packages/deb"
|
||||
mkdir -p "$GNUPGHOME"
|
||||
chmod 0700 "$GNUPGHOME"
|
||||
|
||||
@@ -36,8 +36,8 @@ a{{color:inherit}} .meta{{display:flex;gap:16px;flex-wrap:wrap;opacity:.82;font-
|
||||
</head>
|
||||
<body>
|
||||
<h1>{h(package)} — package repository</h1>
|
||||
<p class="lead">Signed DEB and RPM packages for x86_64/amd64.</p>
|
||||
<div class="meta"><span class="ok">Repository active</span><span>{h(url)}</span><span>APT + RPM/DNF</span></div>
|
||||
<p class="lead">Signed DEB, DNF RPM and SUSE RPM packages for x86_64/amd64.</p>
|
||||
<div class="meta"><span class="ok">Repository active</span><span>{h(url)}</span><span>APT + RPM/DNF + RPM/Zypper</span></div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Debian / Ubuntu</h2>
|
||||
@@ -68,6 +68,17 @@ REPO
|
||||
sudo dnf install {h(package)}</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>SUSE Linux Enterprise / openSUSE Leap / Tumbleweed</h2>
|
||||
<p>Signed dedicated SUSE RPM repository (x86_64; glibc 2.34 or newer).</p>
|
||||
<pre><code>sudo rpm --import {h(url)}/repo-key.gpg
|
||||
sudo zypper addrepo --refresh --gpgcheck {h(url)}/suse/x86_64/ rustproxy-suse
|
||||
sudo zypper refresh rustproxy-suse
|
||||
sudo zypper install {h(package)}
|
||||
# Optional Docker host agent:
|
||||
sudo zypper install rustproxy-docker-agent</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Docker discovery agent — separate Linux package</h2>
|
||||
<p>Install <code>rustproxy-docker-agent</code> on the Docker host (systemd, Docker Engine, amd64/x86_64). This is independent from the RustProxy server and has no FreeBSD pkg.</p>
|
||||
@@ -95,9 +106,10 @@ sudo systemctl status rustproxy-docker-agent</code></pre>
|
||||
<ul>
|
||||
<li><a href="{h(url)}/repo-key.gpg">Public GPG key</a></li>
|
||||
<li><a href="{h(url)}/apt/dists/{h(dist)}/InRelease">APT InRelease</a></li>
|
||||
<li><a href="{h(url)}/rpm/x86_64/repodata/repomd.xml">RPM repomd.xml</a></li>
|
||||
<li><a href="{h(url)}/rpm/x86_64/repodata/repomd.xml">DNF RPM repomd.xml</a></li>
|
||||
<li><a href="{h(url)}/suse/x86_64/repodata/repomd.xml">SUSE RPM repomd.xml</a></li>
|
||||
</ul>
|
||||
<p>Supported targets: Debian 12/13, Ubuntu 24.04/26.04, RHEL 9/10; architecture: amd64/x86_64.</p>
|
||||
<p>Supported targets: Debian 12/13, Ubuntu 24.04/26.04, RHEL 9/10, SLES 15 SP6+, SLES 16+, openSUSE Leap 15.6+/Tumbleweed; architecture: amd64/x86_64.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -34,7 +34,7 @@ if ! aptly -config="$APTLY_CONF" repo list -raw | grep -Fx package-builder >/dev
|
||||
package-builder >/dev/null
|
||||
fi
|
||||
|
||||
for item in apt rpm opnsense freebsd repo-key.gpg index.html LINUX-BUILD-INFO.txt; do
|
||||
for item in apt rpm suse opnsense freebsd repo-key.gpg index.html LINUX-BUILD-INFO.txt SUSE-BUILD-INFO.txt; do
|
||||
if [[ -e "$REPOSITORY/$item" && ! -L "$REPOSITORY/$item" ]]; then
|
||||
fatal "$REPOSITORY/$item exists and is not a symlink; refusing to overwrite"
|
||||
fi
|
||||
@@ -42,8 +42,10 @@ done
|
||||
|
||||
ln -sfn current/apt "$REPOSITORY/apt"
|
||||
ln -sfn current/rpm "$REPOSITORY/rpm"
|
||||
ln -sfn current/suse "$REPOSITORY/suse"
|
||||
ln -sfn current/opnsense "$REPOSITORY/opnsense"
|
||||
ln -sfn current/freebsd "$REPOSITORY/freebsd"
|
||||
ln -sfn current/repo-key.gpg "$REPOSITORY/repo-key.gpg"
|
||||
ln -sfn current/index.html "$REPOSITORY/index.html"
|
||||
ln -sfn current/LINUX-BUILD-INFO.txt "$REPOSITORY/LINUX-BUILD-INFO.txt"
|
||||
ln -sfn current/SUSE-BUILD-INFO.txt "$REPOSITORY/SUSE-BUILD-INFO.txt"
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
set -Eeuo pipefail
|
||||
|
||||
# Increment when package payload/installation semantics change without a source commit.
|
||||
PACKAGING_REVISION=5
|
||||
PACKAGING_REVISION=6
|
||||
OPNSENSE_PACKAGING_REVISION=4
|
||||
FREEBSD_NATIVE_PACKAGING_REVISION=2
|
||||
|
||||
|
||||
@@ -189,4 +189,32 @@ rpm:
|
||||
key_file: $GPG_Q
|
||||
YAML
|
||||
|
||||
log "prepared signed Linux DEB/RPM metadata for $AGENT_NAME $VERSION-$PACKAGE_RELEASE"
|
||||
cat > "$PKG_AGENT/nfpm-suse.yaml" <<YAML
|
||||
name: $AGENT_NAME_Q
|
||||
arch: amd64
|
||||
platform: linux
|
||||
version: $VERSION_Q
|
||||
release: "$PACKAGE_RELEASE"
|
||||
section: net
|
||||
priority: optional
|
||||
maintainer: $MAINTAINER_Q
|
||||
description: "RustProxy Docker discovery agent (HTTPS and bearer token)"
|
||||
license: "Proprietary"
|
||||
homepage: $HOMEPAGE_Q
|
||||
contents:
|
||||
$(cat "$PKG_AGENT/contents.yaml")
|
||||
depends:
|
||||
- ca-certificates
|
||||
- shadow
|
||||
- systemd
|
||||
scripts:
|
||||
postinstall: "$PKG_AGENT/scripts/rpm-postinstall.sh"
|
||||
preremove: "$PKG_AGENT/scripts/rpm-preremove.sh"
|
||||
postremove: "$PKG_AGENT/scripts/rpm-postremove.sh"
|
||||
rpm:
|
||||
compression: gzip
|
||||
signature:
|
||||
key_file: $GPG_Q
|
||||
YAML
|
||||
|
||||
log "prepared signed Linux DEB/RPM/SUSE metadata for $AGENT_NAME $VERSION-$PACKAGE_RELEASE"
|
||||
@@ -239,6 +239,17 @@ deb:
|
||||
type: origin
|
||||
YAML
|
||||
|
||||
# The SUSE flavor keeps the RPM name/version identical but uses native
|
||||
# dependencies and an isolated Python launcher for Leap/SLES 15 systems.
|
||||
# SUSE may ship /usr/bin/python3 older than the separately installed python311.
|
||||
install -D -m 0755 "$BUILDER_ROOT/packaging/suse-python3" \
|
||||
"$PKG/payload/usr/libexec/$PACKAGE_NAME/python3"
|
||||
mkdir -p "$PKG/payload/usr/lib/systemd/system/${PACKAGE_NAME}.service.d"
|
||||
cat > "$PKG/payload/usr/lib/systemd/system/${PACKAGE_NAME}.service.d/50-suse-python.conf" <<SUSE_UNIT
|
||||
[Service]
|
||||
Environment=PATH=/usr/libexec/${PACKAGE_NAME}:/usr/local/bin:/usr/bin:/bin
|
||||
SUSE_UNIT
|
||||
|
||||
cat > "$PKG/nfpm-rpm.yaml" <<YAML
|
||||
name: $NAME_Q
|
||||
arch: amd64
|
||||
@@ -270,3 +281,47 @@ rpm:
|
||||
signature:
|
||||
key_file: $GPG_KEY_Q
|
||||
YAML
|
||||
|
||||
# SUSE Linux Enterprise, openSUSE Leap and Tumbleweed use shadow (not
|
||||
# RHEL's shadow-utils). Versioned Python enables Leap/SLES 15 installations.
|
||||
# Compression gzip is understood by older rpm clients as well as current ones.
|
||||
cat > "$PKG/nfpm-suse.yaml" <<YAML
|
||||
name: $NAME_Q
|
||||
arch: amd64
|
||||
platform: linux
|
||||
version: $VERSION_Q
|
||||
release: "$PACKAGE_RELEASE"
|
||||
section: net
|
||||
priority: optional
|
||||
maintainer: $MAINTAINER_Q
|
||||
description: $DESC_Q
|
||||
license: $LICENSE_Q
|
||||
homepage: $HOMEPAGE_Q
|
||||
vendor: $NAME_Q
|
||||
contents:
|
||||
$(cat "$CONTENTS_FILE")
|
||||
- src: $(yaml_quote "$PKG/payload/usr/libexec/$PACKAGE_NAME/python3")
|
||||
dst: /usr/libexec/$PACKAGE_NAME/python3
|
||||
file_info:
|
||||
mode: 0755
|
||||
- src: $(yaml_quote "$PKG/payload/usr/lib/systemd/system/${PACKAGE_NAME}.service.d/50-suse-python.conf")
|
||||
dst: /usr/lib/systemd/system/${PACKAGE_NAME}.service.d/50-suse-python.conf
|
||||
file_info:
|
||||
mode: 0644
|
||||
depends:
|
||||
- ca-certificates
|
||||
- 'glibc >= 2.34'
|
||||
- gzip
|
||||
- logrotate
|
||||
- shadow
|
||||
- systemd
|
||||
- '((python310 and python310-pip) or (python311 and python311-pip) or (python312 and python312-pip) or (python313 and python313-pip) or (python314 and python314-pip) or (python3 >= 3.10 and python3-pip))'
|
||||
scripts:
|
||||
postinstall: "$PKG/scripts/rpm-postinstall.sh"
|
||||
preremove: "$PKG/scripts/rpm-preremove.sh"
|
||||
postremove: "$PKG/scripts/rpm-postremove.sh"
|
||||
rpm:
|
||||
compression: gzip
|
||||
signature:
|
||||
key_file: $GPG_KEY_Q
|
||||
YAML
|
||||
@@ -117,7 +117,7 @@ case "$SOURCE_REPO" in
|
||||
*) die "SOURCE_REPO ma nieobslugiwany format: $SOURCE_REPO" ;;
|
||||
esac
|
||||
|
||||
normalize_repo_url REPOSITORY_URL HTTP_PORT "$DEFAULT_HTTP_PORT" "APT/RPM"
|
||||
normalize_repo_url REPOSITORY_URL HTTP_PORT "$DEFAULT_HTTP_PORT" "APT/RPM/SUSE"
|
||||
normalize_repo_url OPNSENSE_REPOSITORY_URL OPNSENSE_HTTP_PORT "$DEFAULT_OPNSENSE_HTTP_PORT" "OPNsense"
|
||||
[[ "$HTTP_PORT" != "$OPNSENSE_HTTP_PORT" ]] || die "HTTP_PORT i OPNSENSE_HTTP_PORT musza byc rozne"
|
||||
|
||||
@@ -185,6 +185,7 @@ fingerprint=""
|
||||
log "gotowe"
|
||||
printf '\nSOURCE_REPO: %s\n' "$SOURCE_REPO"
|
||||
printf 'APT/RPM URL: %s/\n' "${REPOSITORY_URL%/}"
|
||||
printf 'SUSE/Zypper RPM URL: %s/suse/x86_64/\n' "${REPOSITORY_URL%/}"
|
||||
printf 'APT/RPM local HTTP port: %s\n' "$HTTP_PORT"
|
||||
printf 'OPNsense pkg URL: %s/\n' "${OPNSENSE_REPOSITORY_URL%/}"
|
||||
printf 'OPNsense local HTTP port: %s\n' "$OPNSENSE_HTTP_PORT"
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Offline verification of SUSE nFPM metadata and catalog integration.
|
||||
|
||||
Run: python3 -m unittest discover -s tests -v
|
||||
Does not require nfpm, root, Docker, or access to the RustProxy upstream.
|
||||
"""
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class SusePackagingTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.tmp = tempfile.TemporaryDirectory()
|
||||
cls.work = Path(cls.tmp.name)
|
||||
cls.src = cls.work / "source"
|
||||
(cls.src / "docker-agent").mkdir(parents=True)
|
||||
agent = cls.src / "docker-agent"
|
||||
(agent / "rustproxy-docker-agent.service").write_text(
|
||||
"[Unit]\nDescription=Test Agent\n[Service]\nExecStart=/usr/local/bin/rustproxy-docker-agent\n")
|
||||
(agent / "docker-agent.env.example").write_text("BIND_ADDRESS=127.0.0.1\n")
|
||||
(agent / "README.md").write_text("Test fixture")
|
||||
(cls.work / "server").write_text("#!/bin/sh\necho server\n")
|
||||
(cls.work / "agent").write_text("#!/bin/sh\necho agent\n")
|
||||
(cls.work / "server").chmod(0o755)
|
||||
(cls.work / "agent").chmod(0o755)
|
||||
cls.env = {
|
||||
**os.environ,
|
||||
"BUILDER_ROOT": str(ROOT),
|
||||
"PACKAGE_NAME": "rustproxy",
|
||||
"BINARY_NAME": "rust-proxy",
|
||||
"VERSION": "0.99.1",
|
||||
"PACKAGE_RELEASE": "7",
|
||||
"MAINTAINER": "Test Builder <test@example.invalid>",
|
||||
"DESCRIPTION": "Test RPM",
|
||||
"LICENSE": "MIT",
|
||||
"HOMEPAGE": "https://example.invalid",
|
||||
"GPG_PRIVATE_KEY_FILE": "/not/needed/until-nfpm-signs",
|
||||
}
|
||||
subprocess.run(
|
||||
["bash", str(ROOT / "scripts/prepare-package.sh"), str(cls.src),
|
||||
str(cls.work / "package"), str(cls.work / "server")],
|
||||
env=cls.env, check=True, capture_output=True, text=True,
|
||||
)
|
||||
subprocess.run(
|
||||
["bash", str(ROOT / "scripts/prepare-agent-package.sh"), str(cls.src),
|
||||
str(cls.work / "package-agent"), str(cls.work / "agent")],
|
||||
env=cls.env, check=True, capture_output=True, text=True,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.tmp.cleanup()
|
||||
|
||||
def test_suse_rpm_has_native_dependencies_and_paths(self):
|
||||
contents = (self.work / "package/nfpm-suse.yaml").read_text()
|
||||
self.assertIn(" - shadow\n", contents)
|
||||
self.assertIn(" - 'glibc >= 2.34'", contents)
|
||||
self.assertNotIn("shadow-utils", contents)
|
||||
self.assertIn("(python311 and python311-pip)", contents)
|
||||
self.assertIn("/usr/libexec/rustproxy/python3", contents)
|
||||
self.assertIn("50-suse-python.conf", contents)
|
||||
self.assertIn("compression: gzip", contents)
|
||||
self.assertIn("key_file:", contents)
|
||||
self.assertTrue((self.work / "package/payload/usr/lib/systemd/system/rustproxy.service.d/50-suse-python.conf").exists())
|
||||
self.assertIn("/usr/libexec/rustproxy", (self.work / "package/payload/usr/lib/systemd/system/rustproxy.service.d/50-suse-python.conf").read_text())
|
||||
|
||||
def test_suse_agent_has_native_dependencies(self):
|
||||
contents = (self.work / "package-agent/nfpm-suse.yaml").read_text()
|
||||
self.assertIn(" - shadow\n", contents)
|
||||
self.assertNotIn("shadow-utils", contents)
|
||||
self.assertIn("compression: gzip", contents)
|
||||
self.assertIn("name: \"rustproxy-docker-agent\"", contents)
|
||||
self.assertIn("/usr/lib/systemd/system/rustproxy-docker-agent.service", contents)
|
||||
|
||||
def test_suse_python_launcher(self):
|
||||
wrapper = self.work / "package/payload/usr/libexec/rustproxy/python3"
|
||||
result = subprocess.run([str(wrapper), "-c", "import sys; print(sys.version_info.major)"],
|
||||
capture_output=True, text=True, timeout=5)
|
||||
# Builder test machine has Python 3; a host without Python >=3.10
|
||||
# will deliberately fail the wrapper rather than run obsolete Python.
|
||||
if result.returncode == 0:
|
||||
self.assertEqual(result.stdout.strip(), "3")
|
||||
else:
|
||||
self.assertIn("Python 3.10", result.stderr)
|
||||
|
||||
|
||||
class SuseCatalogTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
spec = importlib.util.spec_from_file_location("rustproxy_dashboard", ROOT / "dashboard/app.py")
|
||||
self.assertIsNotNone(spec)
|
||||
self.api = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(self.api)
|
||||
self.tmp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.tmp.cleanup)
|
||||
self.repo = Path(self.tmp.name) / "repository"
|
||||
release = self.repo / "releases" / "new"
|
||||
(release / "suse/x86_64/repodata").mkdir(parents=True)
|
||||
(release / "suse/x86_64/repodata/repomd.xml").write_text("<repomd/>")
|
||||
(release / "suse/x86_64/rustproxy-0.99.1-7.x86_64.rpm").write_bytes(b"rpm-test")
|
||||
(release / "suse/x86_64/rustproxy-docker-agent-0.99.1-7.x86_64.rpm").write_bytes(b"rpm-test")
|
||||
(release / "SUSE-BUILD-INFO.txt").write_text(
|
||||
"app_version=0.99.1\npackage_release=7\n"
|
||||
"built_at=2026-10-22T12:00:00Z\nsource_commit=abcdef123456\n"
|
||||
)
|
||||
(self.repo / "current").symlink_to("releases/new")
|
||||
self.release = release
|
||||
|
||||
def test_catalog_publishes_suse_packages_only_in_suse_channel(self):
|
||||
catalog = self.api.generate_catalog(self.repo)
|
||||
self.assertTrue(catalog["builds"]["suse"]["published"])
|
||||
self.assertEqual(catalog["builds"]["suse"]["package_version"], "0.99.1-7")
|
||||
suse_pkgs = [p for p in catalog["packages"] if p["channel"] == "suse"]
|
||||
self.assertEqual(len(suse_pkgs), 2)
|
||||
self.assertTrue(all(p["format"] == "RPM" for p in suse_pkgs))
|
||||
self.assertTrue(all(p["download_url"].endswith(".x86_64.rpm") for p in suse_pkgs))
|
||||
self.assertTrue(all("/suse/x86_64/" in p["download_url"] for p in suse_pkgs))
|
||||
self.assertEqual(catalog["summary"]["channel_counts"]["suse"], 2)
|
||||
|
||||
def test_old_build_does_not_fake_suse_publication(self):
|
||||
(self.release / "SUSE-BUILD-INFO.txt").unlink()
|
||||
catalog = self.api.generate_catalog(self.repo)
|
||||
self.assertFalse(catalog["builds"]["suse"]["published"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user