Author SHA1 Message Date
Joachim Schlöffel 0d85e29b5e revert dynamic matrix, add rclone-openrc to static build matrix
Build Alpine Packages / preflight (pull_request) Successful in 8s
Build Alpine Packages / build (gitea) (pull_request) Successful in 7s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 6s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 6s
Build Alpine Packages / build (nifi) (pull_request) Successful in 5s
Build Alpine Packages / build (rclone-openrc) (pull_request) Successful in 9s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 3s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 27s
2026-10-07 14:09:12 +02:00
Joachim Schlöffel 55ce31db00 change build behaviour to support dynamic package selection
Build Alpine Packages / preflight (pull_request) Successful in 5s
Build Alpine Packages / verify-and-publish (pull_request) Canceled after 0s
Build Alpine Packages / build (pull_request) Canceled after 7m9s
2026-10-07 14:02:11 +02:00
Joachim Schlöffel b40ccdf370 add rclone-openrc
Build Alpine Packages / preflight (pull_request) Successful in 5s
Build Alpine Packages / build (gitea) (pull_request) Successful in 3s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 4s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 4s
Build Alpine Packages / build (nifi) (pull_request) Successful in 3s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 4s
Build Alpine Packages / verify-and-publish (pull_request) Failing after 7s
2026-10-07 13:42:30 +02:00
Joachim Schlöffel 7bdcc83050 bump Gitea version to 28.1.0
Build Alpine Packages / preflight (pull_request) Successful in 6s
Build Alpine Packages / build (gitea) (pull_request) Successful in 54s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 2m58s
Build Alpine Packages / build (nifi) (pull_request) Successful in 6s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 38m57s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 1h12m41s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 1m49s
Build Alpine Packages / preflight (push) Successful in 5s
Build Alpine Packages / build (gitea) (push) Successful in 52s
Build Alpine Packages / build (lavinmq) (push) Successful in 2m30s
Build Alpine Packages / build (nifi) (push) Successful in 4s
Build Alpine Packages / build (seaweedfs) (push) Successful in 40m11s
Build Alpine Packages / build (greptimedb) (push) Successful in 1h8m59s
Build Alpine Packages / verify-and-publish (push) Successful in 2m2s
2026-10-06 23:02:04 +02:00
Joachim Schlöffel 57fc0e658c remove artificial package status from readme
Build Alpine Packages / preflight (pull_request) Successful in 16s
Build Alpine Packages / build (gitea) (pull_request) Successful in 56s
Build Alpine Packages / build (nifi) (pull_request) Successful in 11s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 39m22s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 1h29m31s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 2m56s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 1m47s
2026-10-06 22:54:17 +02:00
Joachim Schlöffel c9543e113b add logrotate subpackages
Build Alpine Packages / preflight (pull_request) Successful in 14s
Build Alpine Packages / build (gitea) (pull_request) Successful in 1m0s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 2m51s
Build Alpine Packages / build (nifi) (pull_request) Successful in 5s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 39m45s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 1h31m44s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 1m42s
2026-10-06 22:39:50 +02:00
Joachim Schlöffel 450d4815dd add support for AMQP, RClone and SQLite to SeaweedFS
Build Alpine Packages / preflight (pull_request) Successful in 6s
Build Alpine Packages / build (gitea) (pull_request) Successful in 4s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 4s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 4s
Build Alpine Packages / build (nifi) (pull_request) Successful in 4s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 26m9s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 56s
Build Alpine Packages / preflight (push) Successful in 15s
Build Alpine Packages / build (gitea) (push) Successful in 5s
Build Alpine Packages / build (greptimedb) (push) Successful in 6s
Build Alpine Packages / build (lavinmq) (push) Successful in 6s
Build Alpine Packages / build (nifi) (push) Successful in 5s
Build Alpine Packages / build (seaweedfs) (push) Successful in 26m15s
Build Alpine Packages / verify-and-publish (push) Successful in 1m30s
2026-10-06 14:46:59 +02:00
Joachim Schlöffel 53747a13cc update readme
Build Alpine Packages / preflight (push) Successful in 7s
Build Alpine Packages / build (gitea) (push) Skipped
Build Alpine Packages / build (greptimedb) (push) Skipped
Build Alpine Packages / build (lavinmq) (push) Skipped
Build Alpine Packages / build (nifi) (push) Skipped
Build Alpine Packages / build (seaweedfs) (push) Skipped
Build Alpine Packages / verify-and-publish (push) Skipped
2026-10-05 22:03:36 +02:00
Joachim Schlöffel 13570ccbd9 Merge branch 'main' into development
Build Alpine Packages / preflight (pull_request) Successful in 5s
Build Alpine Packages / build (gitea) (pull_request) Successful in 3s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 4s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 4s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 6s
Build Alpine Packages / build (nifi) (pull_request) Successful in 3m22s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 2m53s
Build Alpine Packages / preflight (push) Successful in 5s
Build Alpine Packages / build (gitea) (push) Successful in 2s
Build Alpine Packages / build (greptimedb) (push) Successful in 3s
Build Alpine Packages / build (lavinmq) (push) Successful in 3s
Build Alpine Packages / build (seaweedfs) (push) Successful in 6s
Build Alpine Packages / build (nifi) (push) Successful in 3m22s
Build Alpine Packages / verify-and-publish (push) Successful in 4m12s
2026-10-05 21:09:31 +02:00
fspjo f89ebac967 add Apache Nifi (#15)
Reviewed-on: #15
2026-10-05 21:06:42 +02:00
fspjoandJoachim Schlöffel bded7c8adc 2026/10 (#14)
Build Alpine Packages / preflight (push) Successful in 4s
Build Alpine Packages / build (greptimedb) (push) Successful in 4s
Build Alpine Packages / build (gitea) (push) Successful in 53s
Build Alpine Packages / build (seaweedfs) (push) Successful in 4s
Build Alpine Packages / build (lavinmq) (push) Successful in 2m20s
Build Alpine Packages / verify-and-publish (push) Successful in 42s
Co-authored-by: Joachim Schlöffel <me@joachim-schloeffel.com>
Reviewed-on: #14
2026-10-05 20:23:33 +02:00
Joachim Schlöffel 158fd18984 bump LavinMQ to 2.10.1
Build Alpine Packages / preflight (pull_request) Successful in 4s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 5s
Build Alpine Packages / build (gitea) (pull_request) Successful in 52s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 3s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 2m19s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 38s
2026-10-05 20:18:27 +02:00
Joachim Schlöffel fd0f484d4a WIP: check CI build
Build Alpine Packages / build (gitea) (pull_request) Canceled after 0s
Build Alpine Packages / build (greptimedb) (pull_request) Canceled after 0s
Build Alpine Packages / build (lavinmq) (pull_request) Canceled after 0s
Build Alpine Packages / build (seaweedfs) (pull_request) Canceled after 0s
Build Alpine Packages / verify-and-publish (pull_request) Canceled after 0s
Build Alpine Packages / preflight (pull_request) Canceled after 5s
2026-10-05 09:31:46 +02:00
fspjo 1716f42970 update package build process (#12)
Build Alpine Packages / preflight (push) Successful in 15s
Build Alpine Packages / build (gitea) (push) Successful in 4s
Build Alpine Packages / build (greptimedb) (push) Successful in 5s
Build Alpine Packages / build (lavinmq) (push) Successful in 4s
Build Alpine Packages / build (seaweedfs) (push) Successful in 34m15s
Build Alpine Packages / verify-and-publish (push) Successful in 1m15s
Reviewed-on: #12
2026-10-02 09:16:46 +02:00
Joachim Schlöffel 37b6e4cf2c bump Gitea to 28.0.0 (breaking network changes!)
Build Alpine Packages / preflight (pull_request) Successful in 6s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 7s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 5s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 4s
Build Alpine Packages / build (gitea) (pull_request) Successful in 54s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 36s
2026-09-30 11:30:25 +02:00
Joachim Schlöffel a97bafbd92 Merge branch 'main' into development
Build Alpine Packages / preflight (pull_request) Successful in 23s
Build Alpine Packages / build (gitea) (pull_request) Successful in 11s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 13s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 12s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 28m48s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 1m6s
2026-09-30 11:00:52 +02:00
Joachim Schlöffel 573608a04b add graceful shutdown to OpenRC script 2026-09-30 10:55:45 +02:00
fspjo b94463642a Parallel builds and package updates and source build for SeaweedFS (#11)
Build Alpine Packages / preflight (push) Successful in 16s
Build Alpine Packages / build (gitea) (push) Successful in 18s
Build Alpine Packages / build (lavinmq) (push) Successful in 2m51s
Build Alpine Packages / build (seaweedfs) (push) Successful in 21m35s
Build Alpine Packages / build (greptimedb) (push) Successful in 1h20m0s
Build Alpine Packages / verify-and-publish (push) Successful in 2m3s
Reviewed-on: #11
2026-09-29 11:00:07 +02:00
Joachim Schlöffel fc965e072c fix trivy db download n CI
Build Alpine Packages / preflight (pull_request) Successful in 15s
Build Alpine Packages / build (gitea) (pull_request) Successful in 16s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 2m57s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 20m41s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 1h14m12s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 1m47s
2026-09-29 09:33:26 +02:00
fspjo 1c3994a7c4 Merge branch 'main' into development
Build Alpine Packages / preflight (pull_request) Successful in 15s
Build Alpine Packages / build (gitea) (pull_request) Successful in 11s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 3m56s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 25m55s
Build Alpine Packages / verify-and-publish (pull_request) Canceled after 0s
Build Alpine Packages / build (greptimedb) (pull_request) Canceled after 1h29m33s
2026-09-29 08:00:21 +02:00
fspjo e8333709a5 Parallel Builds (#10)
Build Alpine Packages / preflight (push) Successful in 12s
Build Alpine Packages / build (gitea) (push) Successful in 21s
Build Alpine Packages / build (lavinmq) (push) Successful in 2m54s
Build Alpine Packages / build (seaweedfs) (push) Successful in 20m49s
Build Alpine Packages / build (greptimedb) (push) Successful in 1h42m55s
Build Alpine Packages / verify-and-publish (push) Failing after 1m26s
Reviewed-on: #10
2026-09-29 07:17:00 +02:00
Joachim Schlöffel 03daf40d6e remove vendor src archives
Build Alpine Packages / preflight (pull_request) Successful in 20s
Build Alpine Packages / build (gitea) (pull_request) Successful in 15s
Build Alpine Packages / build (lavinmq) (pull_request) Successful in 3m30s
Build Alpine Packages / build (seaweedfs) (pull_request) Successful in 29m27s
Build Alpine Packages / build (greptimedb) (pull_request) Successful in 56m19s
Build Alpine Packages / verify-and-publish (pull_request) Successful in 1m31s
2026-09-29 01:02:15 +02:00
Joachim Schlöffel 40eaf081ad fix CI key collision
Build Alpine Packages / preflight (pull_request) Successful in 16s
Build Alpine Packages / build (gitea) (pull_request) Canceled after 0s
Build Alpine Packages / build (greptimedb) (pull_request) Canceled after 0s
Build Alpine Packages / build (lavinmq) (pull_request) Canceled after 0s
Build Alpine Packages / build (seaweedfs) (pull_request) Canceled after 0s
Build Alpine Packages / verify-and-publish (pull_request) Canceled after 0s
2026-09-29 00:34:41 +02:00
Joachim Schlöffel 254fa76a7d Merge branch 'features/source-build' into development 2026-09-28 23:46:45 +02:00
Joachim Schlöffel 0e6bc657a9 update readme 2026-09-28 23:18:01 +02:00
Joachim Schlöffel d21dadada7 Merge branch 'main' into development 2026-09-28 23:14:02 +02:00
Joachim Schlöffel b75fa2eac9 build only main branch in CI 2026-09-28 23:01:45 +02:00
Joachim Schlöffel 5e2093afec bump SeaweedFS to 4.48 2026-09-28 22:54:39 +02:00
Joachim Schlöffel 74a31e6f45 run Alpine runtime tests in Docker
Build Alpine Packages / preflight (push) Successful in 20s
Build Alpine Packages / build (gitea) (push) Successful in 16s
Build Alpine Packages / build (lavinmq) (push) Successful in 2m28s
Build Alpine Packages / build (seaweedfs) (push) Successful in 48m41s
Build Alpine Packages / build (greptimedb) (push) Successful in 1h39m5s
Build Alpine Packages / verify-and-publish (push) Failing after 20s
2026-09-28 22:50:32 +02:00
Joachim Schlöffel 815a47e19f parallel CI package builds
Build Alpine Packages / preflight (push) Successful in 23s
Build Alpine Packages / build (gitea) (push) Successful in 18s
Build Alpine Packages / build (lavinmq) (push) Successful in 2m30s
Build Alpine Packages / build (seaweedfs) (push) Successful in 47m10s
Build Alpine Packages / build (greptimedb) (push) Successful in 1h33m37s
Build Alpine Packages / verify-and-publish (push) Failing after 2m32s
2026-09-28 20:55:46 +02:00
Joachim Schlöffel 96bd8a20e0 fix greptimedb test linker memory
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Failing after 3h0m4s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Failing after 3h0m8s
2026-09-28 00:48:25 +02:00
Joachim Schlöffel 0a9ed89a47 fix lavinmq crystal dependency
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Failing after 2h41m8s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Failing after 3h0m4s
2026-09-27 17:55:35 +02:00
Joachim Schlöffel 001bd51931 fix greptimedb openrc shutdown
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Failing after 1h18m35s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Canceled after 55m50s
2026-09-27 09:42:13 +02:00
Joachim Schlöffel f01d209780 build greptimedb dashboard from source
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Canceled after 59s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Canceled after 8m22s
2026-09-27 02:27:30 +02:00
Joachim Schlöffel f5efea2160 add package update status badge
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Successful in 35m57s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 1h17m58s
2026-09-26 23:51:50 +02:00
Joachim Schlöffel e4093a3c9f retain package registries as CI artifacts 2026-09-26 23:40:12 +02:00
Joachim Schlöffel d70e9ce84c Merge branch 'main' into features/source-build 2026-09-26 23:30:24 +02:00
Joachim Schlöffel fed4ad011d Revert "add -ip and -port to openrc script"
This reverts commit 2825e1bfef.
2026-09-26 23:29:05 +02:00
Joachim Schlöffel dae1f755a2 vendor lavinmq build inputs 2026-09-26 23:22:14 +02:00
Joachim Schlöffel b3d5424349 vendor lavinmq build inputs 2026-09-26 23:21:44 +02:00
Joachim Schlöffel 13a2d0dd16 build seaweedfs from vendored source 2026-09-26 16:26:27 +02:00
Joachim Schlöffel a2da4acc53 update LavinMQ and update SeaweedFS configs
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 1h9m3s
2026-09-26 14:14:07 +02:00
Joachim Schlöffel 2825e1bfef add -ip and -port to openrc script
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 1h2m47s
2026-09-24 10:33:41 +02:00
Joachim Schlöffel fadbde6c6d update seaweedfs to 4.47
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 1h7m42s
2026-09-20 23:08:00 +02:00
Joachim Schlöffel ace376e5c1 update lavinmq to 2.9.3
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Canceled after 6m55s
2026-09-20 22:59:00 +02:00
Joachim Schlöffel f8189786c8 update greptimedb to 1.2.1 2026-09-20 22:59:00 +02:00
Joachim Schlöffel 684b9ded73 fix typo 2026-09-20 22:59:00 +02:00
Joachim Schlöffel 4b30c5bb93 update tooling 2026-09-20 22:59:00 +02:00
fspjo 7119330286 ci: skip Alpine builds already published (#7)
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 1h17m59s
Reviewed-on: #7
2026-09-07 08:01:15 +02:00
Joachim Schlöffel b0ed3584a1 Merge branch 'development' of ssh://code.factoring.digital:2022/public/alpine-packages into development
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Successful in 1h17m14s
2026-09-06 22:02:38 +02:00
Joachim Schlöffel 5dd92f94d5 docs: describe version-aware Alpine CI 2026-09-06 22:02:09 +02:00
fspjo fe180c01a7 Merge branch 'main' into development
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Canceled after 7m40s
2026-09-06 22:02:00 +02:00
Joachim Schlöffel 6968a72209 ci: skip Alpine builds already published
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Canceled after 1h11m37s
2026-09-06 20:51:31 +02:00
fspjo ba56882ab8 SeaweedFS 4.45 with source build for lance worker'(#6)
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Canceled after 27m57s
Reviewed-on: #6
2026-09-06 16:55:06 +02:00
Joachim Schlöffel f1af2660eb add source build for lance (rust) worker to avoid glibc compat dependency
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Successful in 49m43s
2026-09-06 10:53:23 +02:00
Joachim Schlöffel b5af335ec5 update seaweedfs to 4.45, add new rust worker 2026-09-06 04:46:51 +02:00
Joachim Schlöffel 0384306d4e pin dev tooling 2026-09-06 04:44:23 +02:00
Joachim Schlöffel 8275d25ae7 update Gitea to 1.27.3
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 32m42s
2026-08-31 12:10:58 +02:00
Joachim Schlöffel 86460ee2ba Fix LavinMQ CI toolchain
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 2h32m5s
2026-08-24 23:55:39 +02:00
Joachim Schlöffel 8d98ccf093 Add APK security reports 2026-08-24 10:09:00 +02:00
Joachim Schlöffel 479886d37d Optimize APK update checks and CI builds
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Failing after 2h20m30s
2026-08-24 08:51:30 +02:00
Joachim Schlöffel 9b9473f497 package updates
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Failing after 30m3s
2026-08-24 03:24:35 +02:00
fspjo 53f2a988de upgrade seaweedfs to 4.41 (#5)
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 30m29s
---------
Reviewed-on: #5
2026-08-13 16:42:23 +02:00
Joachim Schlöffel e6d9b173f2 Merge branch 'main' of ssh://code.factoring.digital:2022/public/alpine-packages
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Failing after 51s
2026-07-28 12:05:13 +02:00
Joachim Schlöffel 107e17b959 Gitea patch upgrade to 1.27.1 2026-07-28 12:04:49 +02:00
fspjoandJoachim Schlöffel 57bf04fa87 PKG Upgrade 2026-07-24 (#4)
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 2h27m37s
---------

Co-authored-by: Joachim Schlöffel <me@joachim-schloeffel.com>
Reviewed-on: #4
2026-07-24 16:54:31 +02:00
Joachim Schlöffel 88abf51ca5 Gitea version bump to 1.27.0
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 2h20m16s
2026-07-16 11:01:59 +02:00
Joachim Schlöffel 85122866ac fix publisher bug for multiarch packages
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 18s
2026-07-13 03:06:06 +02:00
Joachim Schlöffel 89db986774 Optimize Alpine packaging workflow
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 2h16m43s
2026-07-12 10:24:15 +02:00
Joachim Schlöffel faf7d5e404 Filter stale APKs from CI package cache
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Has been cancelled
2026-07-12 10:09:45 +02:00
Joachim Schlöffel 7781653941 Use repository owner as CI packager
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 27m36s
2026-07-12 08:05:55 +02:00
Joachim Schlöffel b19a3288fd Update SeaweedFS and add outdated checks
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Has been cancelled
2026-07-12 07:49:15 +02:00
Joachim Schlöffel 95834e55d5 simplify CI runtime checks
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 26m54s
2026-07-09 13:58:55 +02:00
Joachim Schlöffel 95f8f1597a fix package key check during CI build
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Failing after 27m11s
2026-07-09 10:54:06 +02:00
Joachim Schlöffel 2be2a6d5b0 fix lavinMQ runtime test
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Failing after 38s
2026-07-09 10:47:42 +02:00
Joachim Schlöffel a812b075d0 docs update
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Failing after 29m40s
2026-07-09 10:08:25 +02:00
Joachim Schlöffel 6b8488d7cc Skip cached Alpine package rebuilds in CI
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Has been cancelled
2026-07-09 09:59:35 +02:00
Joachim Schlöffel 368a112568 Merge branch 'main' of ssh://code.factoring.digital:2022/public/alpine-packages
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Has been cancelled
2026-07-09 09:35:47 +02:00
Joachim Schlöffel 04b1244a8c Fix LavinMQ OpenRC data ownership 2026-07-09 09:34:16 +02:00
95 changed files with 2636 additions and 676 deletions
+5
View File
@@ -0,0 +1,5 @@
.git
.cache
packages
packaging/**/pkg
packaging/**/src
+159 -37
View File
@@ -3,76 +3,198 @@ name: Build Alpine Packages
on:
push:
branches:
- master
- main
tags:
- "*"
pull_request:
workflow_dispatch:
env:
ALPINE_VERSION: "3.24"
ALPINE_ARCHES: "x86_64 aarch64"
ALPINE_REGISTRY_BRANCH: "v3.24"
ALPINE_REGISTRY_REPOSITORY: "${{ vars.PACKAGE_NAME }}"
INSTANCE_URL: "${{ vars.INSTANCE_URL }}"
PACKAGE_OWNER: "${{ vars.PACKAGE_OWNER }}"
PACKAGE_USER: "${{ secrets.PACKAGE_USER }}"
PACKAGE_TOKEN: "${{ secrets.PACKAGE_TOKEN }}"
PACKAGER: "${{ gitea.repository_owner }}"
ALPINE_RUST_CACHE_ROOT: "/cache/public-alpine-packages/v3.24/rust"
TRIVY_VERSION: "0.74.0"
TRIVY_SHA256: "2ae6fe3ee734b7fdf11335663e18c75ea12dccc76062f09f164a3b0f8be4371a"
jobs:
build-and-publish:
preflight:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- alpine_version: "3.24"
alpine_registry_branch: "v3.24"
timeout-minutes: 180
container:
image: "alpine:${{ matrix.alpine_version }}"
env:
ALPINE_VERSION: "${{ matrix.alpine_version }}"
ALPINE_ARCHES: "x86_64 aarch64"
ALPINE_REGISTRY_BRANCH: "${{ matrix.alpine_registry_branch }}"
ALPINE_REGISTRY_REPOSITORY: "${{ vars.PACKAGE_NAME }}"
INSTANCE_URL: "${{ vars.INSTANCE_URL }}"
PACKAGE_OWNER: "${{ vars.PACKAGE_OWNER }}"
PACKAGE_USER: "${{ secrets.PACKAGE_USER }}"
PACKAGE_TOKEN: "${{ secrets.PACKAGE_TOKEN }}"
PACKAGER: "Joachim Schlöffel <me@joachim-schloeffel.com>"
CARGO_HOME: "/cache/public-alpine-packages/${{ matrix.alpine_registry_branch }}/greptimedb/cargo"
RUSTUP_HOME: "/cache/public-alpine-packages/${{ matrix.alpine_registry_branch }}/greptimedb/rustup"
CARGO_TARGET_DIR: "/cache/public-alpine-packages/${{ matrix.alpine_registry_branch }}/greptimedb/target"
image: "alpine:3.24"
outputs:
packages_selected: "${{ steps.package-selection.outputs.packages_selected }}"
selected_packages: "${{ steps.package-selection.outputs.selected_packages }}"
greptimedb_selected: "${{ steps.package-selection.outputs.greptimedb_selected }}"
steps:
- name: Prepare Environment
run: |
apk add --no-cache --update abuild-rootbld alpine-sdk atools-apkbuild-lint bash ca-certificates curl doas git nodejs sudo tar
mkdir -p "$CARGO_HOME" "$RUSTUP_HOME" "$CARGO_TARGET_DIR"
chown 1000:1000 /cache /cache/public-alpine-packages /cache/public-alpine-packages/${{ matrix.alpine_registry_branch }} /cache/public-alpine-packages/${{ matrix.alpine_registry_branch }}/greptimedb "$CARGO_HOME" "$RUSTUP_HOME" "$CARGO_TARGET_DIR"
printf '%s\n' 'https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories
apk add --no-cache --update atools-apkbuild-lint bash ca-certificates curl git jq nodejs shellcheck tar
- name: Checkout
uses: actions/checkout@v3
- name: Build packages
- name: Select packages
run: |
scripts/apk/clean.sh
find packaging/alpine/local -mindepth 2 -maxdepth 2 -name APKBUILD -exec apkbuild-lint {} +
scripts/apk/lint-shell.sh
scripts/apk/outdated.sh | tee update-check.txt
if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
{
echo "## Upstream update check"
echo
echo '```text'
cat update-check.txt
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
fi
- name: Prepare package cache
id: package-selection
run: scripts/apk/ci-package-cache.sh prepare
- name: Validate selected package matrix
run: |
for package in ${ALPINE_PACKAGES}; do
case "${package}" in
seaweedfs|greptimedb|lavinmq|gitea|nifi|rclone-openrc) ;;
*)
printf 'selected package is missing from the CI build matrix: %s\n' "${package}" >&2
exit 1
;;
esac
done
build:
needs: preflight
if: needs.preflight.outputs.packages_selected == 'true'
runs-on: ubuntu-latest
timeout-minutes: 180
strategy:
fail-fast: false
matrix:
package: [seaweedfs, greptimedb, lavinmq, gitea, nifi, rclone-openrc]
container:
image: "alpine:3.24"
env:
ALPINE_PACKAGE: "${{ matrix.package }}"
steps:
- name: Prepare Environment
run: |
printf '%s\n' 'https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories
apk add --no-cache --update abuild-rootbld alpine-sdk bash ca-certificates doas git nodejs sudo
mkdir -p "$ALPINE_RUST_CACHE_ROOT"
chown -R 1000:1000 /cache/public-alpine-packages/v3.24
- name: Checkout
uses: actions/checkout@v3
- name: Build package
if: contains(needs.preflight.outputs.selected_packages, matrix.package)
run: |
scripts/apk/ci-build.sh
scripts/apk/export-ci-assets.sh
scripts/apk/list-packages.sh
- name: Check artifact upload support
id: artifact-upload
if: contains(needs.preflight.outputs.selected_packages, matrix.package)
run: |
if [ -n "${ACTIONS_RUNTIME_TOKEN:-}" ]; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "available=false" >> "$GITHUB_OUTPUT"
fi
test -n "${ACTIONS_RUNTIME_TOKEN:-}" || {
echo "artifact upload support is required for split package builds" >&2
exit 1
}
- name: Upload generated CI assets
if: steps.artifact-upload.outputs.available == 'true'
- name: Upload package artifacts
if: contains(needs.preflight.outputs.selected_packages, matrix.package)
uses: actions/upload-artifact@v3
with:
name: greptimedb-musl-binaries-${{ matrix.alpine_registry_branch }}
name: alpine-package-${{ matrix.package }}-${{ github.sha }}
path: packages/local/
retention-days: 1
verify-and-publish:
needs: [preflight, build]
if: needs.preflight.outputs.packages_selected == 'true'
runs-on: ubuntu-latest
timeout-minutes: 180
container:
image: "alpine:3.24"
env:
ALPINE_PACKAGES: "${{ needs.preflight.outputs.selected_packages }}"
steps:
- name: Prepare Environment
run: |
printf '%s\n' 'https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories
apk add --no-cache --update abuild-rootbld alpine-sdk bash ca-certificates curl doas docker-cli git jq nodejs rsync shellcheck sudo tar
trivy_archive="trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz"
curl -fsSL -o "/tmp/${trivy_archive}" "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/${trivy_archive}"
echo "${TRIVY_SHA256} /tmp/${trivy_archive}" | sha256sum -c -
tar -xzf "/tmp/${trivy_archive}" -C /usr/local/bin trivy
- name: Checkout
uses: actions/checkout@v3
- name: Prepare registry fallback
run: |
selected_packages="$ALPINE_PACKAGES"
scripts/apk/ci-package-cache.sh prepare
printf 'ALPINE_PACKAGES=%s\n' "$selected_packages" >> "$GITHUB_ENV"
- name: Download package artifacts
uses: actions/download-artifact@v3
with:
path: packages/worker-artifacts
- name: Merge package artifacts
run: scripts/apk/merge-ci-artifacts.sh
- name: Export GreptimeDB CI assets
if: needs.preflight.outputs.greptimedb_selected == 'true'
run: scripts/apk/export-ci-assets.sh
- name: Upload generated CI assets
if: needs.preflight.outputs.greptimedb_selected == 'true'
uses: actions/upload-artifact@v3
with:
name: greptimedb-musl-binaries-v3.24
path: packages/ci-assets/
- name: Upload local Alpine registry
uses: actions/upload-artifact@v3
with:
name: alpine-local-registry-v3.24-${{ github.sha }}
path: packages/local/
retention-days: 30
- name: Smoke test
run: scripts/apk/ci-smoke.sh
- name: Generate security reports
run: |
scripts/apk/security-report.sh
if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
find packages/security-reports -name summary.md -type f -print | sort | while IFS= read -r summary; do
cat "$summary"
done >> "$GITHUB_STEP_SUMMARY"
fi
- name: Upload security reports
uses: actions/upload-artifact@v3
with:
name: apk-security-reports-v3.24
path: packages/security-reports/
- name: Runtime test
run: scripts/apk/runtime-test.sh
run: ALPINE_RUNTIME_TEST_MODE=docker scripts/apk/runtime-test.sh
- name: Publish Alpine packages
if: github.event_name != 'pull_request'
if: github.ref == 'refs/heads/main'
run: scripts/apk/publish-gitea.sh
+3
View File
@@ -1,6 +1,9 @@
.cache/
.vscode/
packages/
packaging/alpine/*/*/pkg/
packaging/alpine/*/*/src/
packaging/alpine/*/*/tmp/
packaging/alpine/*/*/*.apk
packaging/alpine/*/*/*.tar.*
!packaging/alpine/*/*/*-vendor.tar.gz
+80 -19
View File
@@ -1,6 +1,15 @@
# Alpine Packages
Alpine stable packaging for internal packages.
Alpine stable packaging for internal packages. This repository carries selected
upstream releases ahead of Alpine community packages when we need newer
features, packaging fixes, or service layouts on the current Alpine branch.
Packages are either source builds or binary repackages:
- Source builds compile upstream source releases inside the Alpine build
environment and link against Alpine libraries.
- Binary repackages wrap official upstream Linux release artifacts in Alpine
package metadata, OpenRC services, config defaults, and role subpackages.
```text
https://code.factoring.digital/api/packages/public/alpine/v3.24/alpine-packages
@@ -8,10 +17,14 @@ https://code.factoring.digital/api/packages/public/alpine/v3.24/alpine-packages
## Available Packages
- [SeaweedFS](packaging/alpine/local/seaweedfs/README.md): `seaweedfs`
- [GreptimeDB](packaging/alpine/local/greptimedb/README.md): `greptimedb`
- [LavinMQ](packaging/alpine/local/lavinmq/README.md): `lavinmq`
- [Gitea](packaging/alpine/local/gitea/README.md): `gitea`
| Package | APK Name | Package Version | Package Type | Purpose |
|-----------------------------------------------------------|--------------|-----------------|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
| [SeaweedFS](packaging/alpine/local/seaweedfs/README.md) | `seaweedfs` | `4.48` | Binary repackaging of official upstream release tarballs | Ships current SeaweedFS features with Alpine OpenRC role splits. |
| [GreptimeDB](packaging/alpine/local/greptimedb/README.md) | `greptimedb` | `1.2.1` | Source build from upstream release | Provides a current GreptimeDB build and component OpenRC packages before it is available from Alpine community. |
| [LavinMQ](packaging/alpine/local/lavinmq/README.md) | `lavinmq` | `2.10.1` | Source build from upstream release | Provides a current LavinMQ build on Alpine 3.24 with matching Crystal support. |
| [Gitea](packaging/alpine/local/gitea/README.md) | `gitea` | `28.1.0` | Binary repackaging of official upstream release binaries | Ships current Gitea releases with the expected Alpine runtime layout and OpenRC service. |
| [Apache NiFi](packaging/alpine/local/nifi/README.md) | `nifi` | `2.12.0` | Binary repackaging of the official Standard distribution | Provides Apache NiFi 2 with a secure default configuration and OpenRC service. |
| [rclone OpenRC](packaging/alpine/local/rclone-openrc/README.md) | `rclone-openrc` | `0.1.0` | OpenRC integration for Alpine's rclone package | Provides reusable, instance-capable OpenRC supervision for rclone commands. |
## Use In Production
@@ -50,15 +63,6 @@ Package sources live under:
packaging/alpine/local/<pkgname>/
```
Currently packaged:
```text
seaweedfs SeaweedFS 4.31 release binary and OpenRC role splits
greptimedb GreptimeDB 1.1.2 built from source for x86_64
lavinmq LavinMQ 2.9.1 built from source for x86_64
gitea Gitea 1.26.4 release binary and OpenRC service
```
Local build output is written under:
```text
@@ -86,13 +90,16 @@ apk:ci-build Build all configured Alpine packages directly in the curre
apk:ci-smoke Install-test built packages directly in the current Alpine environment
apk:clean Remove generated Alpine package build outputs
apk:lint Run Alpine APKBUILD lint in Docker
apk:lint-shell Run ShellCheck for packaging automation
apk:packages List built Alpine packages and dependencies
apk:publish-check Run lint, multi-arch build, package listing, and smoke test
apk:publish-gitea Publish built packages to the Gitea Alpine package registry
apk:outdated Check packaged upstream versions and release summaries
apk:security-report Generate Trivy and CycloneDX reports for built packages
apk:shell Open an Alpine package build shell in Docker
apk:smoke Install-test built packages from the local repository in Docker
apk:test-install Test README installation instructions in a fresh Alpine container
apk:test-shell Open an Alpine shell with the current local package build installed
apk:test-shell Open an Alpine shell with the local APK repository configured
apk:update-generated Refresh packaged upstream examples and shell completions
apk:runtime-test Run package-local Docker runtime tests against the local...
gitea-workflow-build Run the Gitea build workflow locally through act as a pull_request event
@@ -127,11 +134,17 @@ ALPINE_APK_CACHE_SCOPE=public-alpine-packages ALPINE_PACKAGE=greptimedb mise run
ALPINE_APK_CACHE_PREFIX=alpine-apk-ci ALPINE_PACKAGE=greptimedb mise run apk:build
```
Open an Alpine test shell:
Local packages use `local` as the default package metadata identity. Override it
when needed:
```sh
PACKAGER="Example Builder <builder@example.com>" ALPINE_PACKAGE=seaweedfs mise run apk:build
```
Open an Alpine package build shell:
```sh
ALPINE_PACKAGE=seaweedfs mise run apk:shell
mise run apk:test-shell
```
Run the install test:
@@ -147,6 +160,20 @@ SKIP_BUILD=1 mise run apk:test-install
SKIP_BUILD=1 mise run apk:test-shell
```
`apk:test-shell` opens an Alpine shell with the local APK repository configured.
Install whichever built packages you want inside the container:
```sh
apk add seaweedfs seaweedfs-master-openrc
weed version
apk add greptimedb greptimedb-docs greptimedb-standalone-openrc
greptime --version
apk add rclone-openrc
rclone version
```
Run package-local runtime tests:
```sh
@@ -194,10 +221,43 @@ ALPINE_PACKAGE=seaweedfs mise run apk:update-generated
mise run apk:checksum
```
### Upstream Update Visibility
Check whether packaged upstream versions are current:
```sh
mise run apk:outdated
ALPINE_PACKAGE=seaweedfs mise run apk:outdated
```
By default this is a warning-only signal. To make outdated or unknown package
versions fail the command:
```sh
APK_UPDATE_CHECK_MODE=fail mise run apk:outdated
```
When an update is available, the command also lists compact release-note
summaries for every release between the packaged and latest versions.
### Security Reports and Roadmap
The [project review and development roadmap](docs/project-review.md) tracks
release-reliability goals. Generate advisory Trivy and CycloneDX reports for
built packages with:
```sh
ALPINE_PACKAGE=seaweedfs mise run apk:security-report
```
Reports are written to `packages/security-reports/` and are uploaded by CI for
each selected package build. Local runs scan the newest compatible package set
available in the signed local repository.
### Gitea Workflow
`.gitea/workflows/build.yml` builds and publishes `v3.24`. Pull requests
build only.
The smoke test installs rebuilt artifacts from the local repository and uses
the published registry as a fallback for unchanged packages.
Repository variables:
@@ -246,6 +306,7 @@ Then test at least one installed role in the package shell:
```sh
mise run apk:test-shell
apk add seaweedfs seaweedfs-master-openrc
rc-service seaweedfs.master start
weed version
```
-13
View File
@@ -1,13 +0,0 @@
#!/usr/bin/env -S mise tool-stub
# GrepTimeDB 1.0.2 release binary.
version = "1.0.2"
bin = "greptime"
[platforms.linux-x64]
url = "https://github.com/GreptimeTeam/greptimedb/releases/download/v1.0.2/greptime-linux-amd64-v1.0.2.tar.gz"
checksum = "sha256:1ad1f9312ce18a49494434cf52cf9fa00093c4712728508bff4578d060fb2d89"
[platforms.linux-arm64]
url = "https://github.com/GreptimeTeam/greptimedb/releases/download/v1.0.2/greptime-linux-arm64-v1.0.2.tar.gz"
checksum = "sha256:e6567f5d97fd34b876b5653c22877c238a1633ecbe26b3b7c22b95892656c39c"
-15
View File
@@ -1,15 +0,0 @@
#!/usr/bin/env -S mise tool-stub
# SeaweedFS 4.31 release binary.
version = "4.31"
bin = "weed"
[platforms.linux-x64]
url = "https://github.com/seaweedfs/seaweedfs/releases/download/4.31/linux_amd64.tar.gz"
checksum = "sha256:81103c53453fddfa75d9d611cd3e61aa57e7a3099dc7a1de5977ab4b19211958"
size = 43223476
[platforms.linux-arm64]
url = "https://github.com/seaweedfs/seaweedfs/releases/download/4.31/linux_arm64.tar.gz"
checksum = "sha256:76ac1ffce87a2a710a3913282a19de6d9a3785f4a3586556858ec7b81a87d958"
size = 38036794
+44
View File
@@ -0,0 +1,44 @@
# Project Review and Development Roadmap
## Current State
This repository packages four upstream services for Alpine 3.24, with source
builds, binary repackages, OpenRC integration, Docker-based local builds, and
CI publication to the Gitea Alpine registry. Package selection avoids rebuilding
unchanged versions already present in the registry.
The main release risks are missing retained build artifacts, permissive duplicate
publish handling, rolling toolchain inputs, and limited end-to-end service
validation. Documentation and test defaults must remain synchronized with each
`APKBUILD` version.
## Prioritized Goals
1. **Reproducible, auditable releases.** Split build and publish work so publish
consumes a retained APK artifact plus a checksum manifest; verify registry
contents after upload and reject mismatched duplicate versions.
2. **Build security visibility.** Generate an installed-rootfs CycloneDX SBOM
and advisory Trivy report for every package and architecture selected by CI.
Retain reports as Gitea workflow artifacts.
3. **Service-level confidence.** Add bounded readiness checks for Gitea,
LavinMQ, and GreptimeDB; retain SeaweedFS role startup coverage.
4. **Automation correctness.** Add fixture-based tests for package selection,
APKINDEX parsing, metadata/version drift, and registry error paths.
5. **Developer feedback and cost.** Record build durations/cache outcomes,
keep package-scoped validation, and add a scheduled update-report workflow.
## Security Reports
`mise run apk:security-report` scans the installed root filesystem for each
selected local package. It writes advisory reports under:
```text
packages/security-reports/<package>/<architecture>/
├── trivy.json
├── sbom.cdx.json
└── summary.md
```
The scan includes the package, its selected subpackages, and resolved runtime
dependencies from the signed local repository. Findings do not block a build yet; report generation,
package installation, and report validation do.
+204
View File
@@ -0,0 +1,204 @@
# @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html
lockfile_version = 1
[[tools.act]]
version = "0.2.89"
backend = "aqua:nektos/act"
specifiers = ["latest"]
[tools.act."platforms.linux-arm64"]
checksum = "sha256:daa8679ba9615a74d2d0cec321dc593f21948a2a11bb65862b063d8b930f4bcb"
url = "https://github.com/nektos/act/releases/download/v0.2.89/act_Linux_arm64.tar.gz"
url_api = "https://api.github.com/repos/nektos/act/releases/assets/434891274"
[tools.act."platforms.linux-arm64-musl"]
checksum = "sha256:daa8679ba9615a74d2d0cec321dc593f21948a2a11bb65862b063d8b930f4bcb"
url = "https://github.com/nektos/act/releases/download/v0.2.89/act_Linux_arm64.tar.gz"
url_api = "https://api.github.com/repos/nektos/act/releases/assets/434891274"
[tools.act."platforms.linux-x64"]
checksum = "sha256:0191d6f1f3b716b5c55820032605d05fc3c1cdbf581ebeff655019e5dd1524c0"
url = "https://github.com/nektos/act/releases/download/v0.2.89/act_Linux_x86_64.tar.gz"
url_api = "https://api.github.com/repos/nektos/act/releases/assets/434891246"
[tools.act."platforms.linux-x64-musl"]
checksum = "sha256:0191d6f1f3b716b5c55820032605d05fc3c1cdbf581ebeff655019e5dd1524c0"
url = "https://github.com/nektos/act/releases/download/v0.2.89/act_Linux_x86_64.tar.gz"
url_api = "https://api.github.com/repos/nektos/act/releases/assets/434891246"
[tools.act."platforms.macos-arm64"]
checksum = "sha256:48ae218af96725f7635a66de2b87e1e346893b02add0f16b92f560296b2151fc"
url = "https://github.com/nektos/act/releases/download/v0.2.89/act_Darwin_arm64.tar.gz"
url_api = "https://api.github.com/repos/nektos/act/releases/assets/434891257"
[tools.act."platforms.macos-x64"]
checksum = "sha256:41b31488e7c254baec31cce12c7dade3e35973b8a31b9486206ad43f233d814e"
url = "https://github.com/nektos/act/releases/download/v0.2.89/act_Darwin_x86_64.tar.gz"
url_api = "https://api.github.com/repos/nektos/act/releases/assets/434891248"
[tools.act."platforms.windows-x64"]
checksum = "sha256:0f8cf866ad7e32421a219fc551a0a0ea5d12ead464de12ebfeafd334a5973b50"
url = "https://github.com/nektos/act/releases/download/v0.2.89/act_Windows_x86_64.zip"
url_api = "https://api.github.com/repos/nektos/act/releases/assets/434891261"
[[tools.docker-cli]]
version = "29.8.2"
backend = "aqua:docker/cli"
specifiers = ["latest"]
[tools.docker-cli."platforms.linux-arm64"]
url = "https://download.docker.com/linux/static/stable/aarch64/docker-29.8.2.tgz"
[tools.docker-cli."platforms.linux-arm64-musl"]
url = "https://download.docker.com/linux/static/stable/aarch64/docker-29.8.2.tgz"
[tools.docker-cli."platforms.linux-x64"]
checksum = "blake3:3a70b254f51e6a0fb384e1d93bc859c19b975ae979abbec968e378f79335da5d"
url = "https://download.docker.com/linux/static/stable/x86_64/docker-29.8.2.tgz"
[tools.docker-cli."platforms.linux-x64-musl"]
url = "https://download.docker.com/linux/static/stable/x86_64/docker-29.8.2.tgz"
[tools.docker-cli."platforms.macos-arm64"]
url = "https://download.docker.com/mac/static/stable/aarch64/docker-29.8.2.tgz"
[tools.docker-cli."platforms.macos-x64"]
url = "https://download.docker.com/mac/static/stable/x86_64/docker-29.8.2.tgz"
[tools.docker-cli."platforms.windows-x64"]
url = "https://download.docker.com/win/static/stable/x86_64/docker-29.8.2.zip"
[[tools.jq]]
version = "1.8.2"
backend = "aqua:jqlang/jq"
specifiers = ["latest"]
[tools.jq."platforms.linux-arm64"]
checksum = "sha256:8b85c817833814ddca00a144c33705546355afccf0cf39b188f3cdb48b852309"
url = "https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-linux-arm64"
url_api = "https://api.github.com/repos/jqlang/jq/releases/assets/453012756"
provenance = "github-attestations"
[tools.jq."platforms.linux-arm64-musl"]
checksum = "sha256:8b85c817833814ddca00a144c33705546355afccf0cf39b188f3cdb48b852309"
url = "https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-linux-arm64"
url_api = "https://api.github.com/repos/jqlang/jq/releases/assets/453012756"
provenance = "github-attestations"
[tools.jq."platforms.linux-x64"]
checksum = "sha256:b1c22172dd303f3be49e935aa56aa48a8b7a46e0bc838b4997d3bb451495870f"
url = "https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-linux-amd64"
url_api = "https://api.github.com/repos/jqlang/jq/releases/assets/453012752"
provenance = "github-attestations"
[tools.jq."platforms.linux-x64-musl"]
checksum = "sha256:b1c22172dd303f3be49e935aa56aa48a8b7a46e0bc838b4997d3bb451495870f"
url = "https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-linux-amd64"
url_api = "https://api.github.com/repos/jqlang/jq/releases/assets/453012752"
provenance = "github-attestations"
[tools.jq."platforms.macos-arm64"]
checksum = "sha256:2d75340ba57a4b4b4c8708a21c2dc8e958a48aaa8bba13b27f77f6e4c0eca07e"
url = "https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-macos-arm64"
url_api = "https://api.github.com/repos/jqlang/jq/releases/assets/453012783"
provenance = "github-attestations"
[tools.jq."platforms.macos-x64"]
checksum = "sha256:e94b266e3c26690550006abe63152b782280f4e14374accdf04cbde844f00bc0"
url = "https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-macos-amd64"
url_api = "https://api.github.com/repos/jqlang/jq/releases/assets/453012782"
provenance = "github-attestations"
[tools.jq."platforms.windows-x64"]
checksum = "sha256:a6fc67fedaf9128a3309a1e2ebb8b986aeccf70122ee46d2cb4849e423f0c627"
url = "https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-windows-amd64.exe"
url_api = "https://api.github.com/repos/jqlang/jq/releases/assets/453012788"
provenance = "github-attestations"
[[tools.shellcheck]]
version = "0.11.0"
backend = "aqua:koalaman/shellcheck"
specifiers = ["latest"]
[tools.shellcheck."platforms.linux-arm64"]
checksum = "sha256:12b331c1d2db6b9eb13cfca64306b1b157a86eb69db83023e261eaa7e7c14588"
url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.aarch64.tar.xz"
url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/279056934"
[tools.shellcheck."platforms.linux-arm64-musl"]
checksum = "sha256:12b331c1d2db6b9eb13cfca64306b1b157a86eb69db83023e261eaa7e7c14588"
url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.aarch64.tar.xz"
url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/279056934"
[tools.shellcheck."platforms.linux-x64"]
checksum = "sha256:8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198"
url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.x86_64.tar.xz"
url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/279056942"
[tools.shellcheck."platforms.linux-x64-musl"]
checksum = "sha256:8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198"
url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.x86_64.tar.xz"
url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/279056942"
[tools.shellcheck."platforms.macos-arm64"]
checksum = "sha256:56affdd8de5527894dca6dc3d7e0a99a873b0f004d7aabc30ae407d3f48b0a79"
url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.darwin.aarch64.tar.xz"
url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/279056932"
[tools.shellcheck."platforms.macos-x64"]
checksum = "sha256:3c89db4edcab7cf1c27bff178882e0f6f27f7afdf54e859fa041fca10febe4c6"
url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.darwin.x86_64.tar.xz"
url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/279056930"
[tools.shellcheck."platforms.windows-x64"]
checksum = "sha256:8a4e35ab0b331c85d73567b12f2a444df187f483e5079ceffa6bda1faa2e740e"
url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.zip"
url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/279056944"
[[tools.trivy]]
version = "0.75.0"
backend = "aqua:aquasecurity/trivy"
specifiers = ["latest"]
[tools.trivy."platforms.linux-arm64"]
checksum = "sha256:a1ee9f6ffb7d112b64ff726a2a0717c21175c1114361391f4a132956751a13b3"
url = "https://github.com/aquasecurity/trivy/releases/download/v0.75.0/trivy_0.75.0_Linux-ARM64.tar.gz"
url_api = "https://api.github.com/repos/aquasecurity/trivy/releases/assets/603335583"
provenance = "cosign"
[tools.trivy."platforms.linux-arm64-musl"]
checksum = "sha256:a1ee9f6ffb7d112b64ff726a2a0717c21175c1114361391f4a132956751a13b3"
url = "https://github.com/aquasecurity/trivy/releases/download/v0.75.0/trivy_0.75.0_Linux-ARM64.tar.gz"
url_api = "https://api.github.com/repos/aquasecurity/trivy/releases/assets/603335583"
provenance = "cosign"
[tools.trivy."platforms.linux-x64"]
checksum = "sha256:c6e65abddb348e25f10549df887045629cf28cc72453cd1c63acb717316b3f3f"
url = "https://github.com/aquasecurity/trivy/releases/download/v0.75.0/trivy_0.75.0_Linux-64bit.tar.gz"
url_api = "https://api.github.com/repos/aquasecurity/trivy/releases/assets/603335432"
provenance = "cosign"
[tools.trivy."platforms.linux-x64-musl"]
checksum = "sha256:c6e65abddb348e25f10549df887045629cf28cc72453cd1c63acb717316b3f3f"
url = "https://github.com/aquasecurity/trivy/releases/download/v0.75.0/trivy_0.75.0_Linux-64bit.tar.gz"
url_api = "https://api.github.com/repos/aquasecurity/trivy/releases/assets/603335432"
provenance = "cosign"
[tools.trivy."platforms.macos-arm64"]
checksum = "sha256:4a77108cccf8e55c8d6823e1e759939a622277e66cd0daa3c1fc621ed69e4568"
url = "https://github.com/aquasecurity/trivy/releases/download/v0.75.0/trivy_0.75.0_macOS-ARM64.tar.gz"
url_api = "https://api.github.com/repos/aquasecurity/trivy/releases/assets/603335435"
provenance = "cosign"
[tools.trivy."platforms.macos-x64"]
checksum = "sha256:291edaa9778acbe4693d067b5ad60ee11570e5ac68296e85595417528ca641e4"
url = "https://github.com/aquasecurity/trivy/releases/download/v0.75.0/trivy_0.75.0_macOS-64bit.tar.gz"
url_api = "https://api.github.com/repos/aquasecurity/trivy/releases/assets/603335728"
provenance = "cosign"
[tools.trivy."platforms.windows-x64"]
checksum = "sha256:4e43bd71a30f51aee39525f60f2b47043af77eb8df8fe082aae4372b69c6660f"
url = "https://github.com/aquasecurity/trivy/releases/download/v0.75.0/trivy_0.75.0_windows-64bit.zip"
url_api = "https://api.github.com/repos/aquasecurity/trivy/releases/assets/603335433"
provenance = "cosign"
+15 -2
View File
@@ -1,8 +1,9 @@
[tools]
act = "latest"
codex = "latest"
docker-cli = "latest"
jq = "latest"
shellcheck = "latest"
trivy = "latest"
[tasks."apk:build"]
description = "Build the Alpine package in Docker for the default architecture"
@@ -36,6 +37,10 @@ run = "scripts/apk/update-generated-sources.sh"
description = "Run Alpine APKBUILD lint in Docker"
run = "scripts/apk/build.sh lint"
[tasks."apk:lint-shell"]
description = "Run ShellCheck for packaging automation"
run = "scripts/apk/lint-shell.sh"
[tasks."apk:smoke"]
description = "Install-test built packages from the local repository in Docker"
run = "scripts/apk/smoke.sh"
@@ -45,7 +50,7 @@ description = "Install-test built packages directly in the current Alpine enviro
run = "scripts/apk/ci-smoke.sh"
[tasks."apk:test-shell"]
description = "Open an Alpine shell with the current local package build installed"
description = "Open an Alpine shell with the local APK repository configured"
run = "scripts/apk/test-shell.sh"
[tasks."apk:test-install"]
@@ -61,6 +66,14 @@ env = { ALPINE_ARCH = "x86_64", ALPINE_REPO_NAME = "local", ALPINE_VERSION = "3.
description = "List built Alpine packages and dependencies"
run = "scripts/apk/list-packages.sh"
[tasks."apk:outdated"]
description = "Check packaged upstream versions against latest GitHub releases"
run = "scripts/apk/outdated.sh"
[tasks."apk:security-report"]
description = "Generate Trivy and CycloneDX reports for built selected packages"
run = "scripts/apk/security-report.sh"
[tasks."apk:publish-check"]
description = "Run lint, multi-arch build, package listing, and smoke test"
run = "scripts/apk/publish-check.sh"
+17 -6
View File
@@ -1,6 +1,6 @@
# Maintainer: Joachim Schlöffel <me@joachim-schloeffel.com>
# Maintainer: Joachim Schlöffel <joachim.schloeffel@financial-service-plus.de>
pkgname=gitea
pkgver=1.26.4
pkgver=28.1.0
pkgrel=0
pkgdesc="Self-hosted Git service written in Go"
url="https://about.gitea.com/"
@@ -14,6 +14,7 @@ pkgusers="gitea"
pkggroups="www-data"
subpackages="
$pkgname-doc
$pkgname-logrotate:_logrotate:noarch
$pkgname-openrc:_openrc:noarch
"
options="!check !strip !tracedeps"
@@ -33,6 +34,7 @@ source="
$pkgname-src-$pkgver.tar.gz::https://github.com/go-gitea/gitea/releases/download/v$pkgver/gitea-src-$pkgver.tar.gz
gitea.ini
gitea.initd
gitea.logrotate
"
builddir="$srcdir/gitea-src-$pkgver"
@@ -68,10 +70,19 @@ _openrc() {
install -Dm755 "$srcdir"/gitea.initd "$subpkgdir"/etc/init.d/gitea
}
_logrotate() {
pkgdesc="Log rotation configuration for $pkgname"
depends="$pkgname=$pkgver-r$pkgrel logrotate"
install -Dm644 "$srcdir"/gitea.logrotate \
"$subpkgdir"/etc/logrotate.d/$pkgname
}
sha512sums="
fa4d6a388f22f1f20e99a7a73143b5541aacaf2f60f9bf8b47cdb5c9cb192a16b0a1a2f8dd1fe9710817edf6ce5ea6fea4ef4acdb8e363fe9f25c53f6e682962 gitea-1.26.4-linux-amd64.xz
f17868d979ca1ec37f7793d6286789a788abc674e06265011938cfa5b6bf6c1c259af2633fbf8d6371221240c4e3987b7f55ba50b893da74b77ce33265464c92 gitea-1.26.4-linux-arm64.xz
9298d2d6eaf03d708a869e8fe5b2cbdcede3fc5e3ae640d3f43a27b7c9a3e10b353ae6135bfb634360679b5793a759c9ae9c7531cde331b11ae81c03b4904ddb gitea-src-1.26.4.tar.gz
431184faffa8996873d92d7b0d16bc4b1a0178d264cd2928d1f49b13ad3e6470d9ede7a18c12112deeeb38f0647ccc0b012e98bcbd96e7b8496a3dc18f5b1fb7 gitea.ini
dee8e5f0b088403e70829f193763e3cc9f3a9ab4b4fe7d5dca72e858bdc4859f2b03cd38314086e2bf7a421eb34f6141b92e11679ad6f9980b8a979a6cabb213 gitea-28.1.0-linux-amd64.xz
413ed83dab64d0bd20684d1ea5350b58c6e74e5aa6f034ee91004d0ee3edadc2ce242e9a298d434744ed00a7bdc5ff4a369d508d385cd40f3b81c59db061ce3a gitea-28.1.0-linux-arm64.xz
619b6ef374153816dfdb24896f455b3d5e96c033eae98f0c6f6ad027f817f57328cca3b239caa1bba8fe3c3f0f89fc87c9dac741f7719bb1c3501577048cb0bd gitea-src-28.1.0.tar.gz
4e20b24c34af01a27589a13d9140d559909cc44507febe5de692d7bc154d65f4b01b79d2f1dcce9fed77b60ac3b1a52cc0ec72161e5a2484a4c718d26d3c630d gitea.ini
9474d707df8b049c93ec4642f71195adff699e1e812f315cac4295b3ab29eeb9ba8b83bf3307c50b04e072a4a9dc4c4f84ac490ee22291bd50015009795c1598 gitea.initd
456a565123b46c0c3a36adbde4c881ee04557a2f1ba492a76205c28f72598bf3b7b96192ddeae4f9ab197fdc75bb5e10a3421574e1bf831192220b4540bb39fc gitea.logrotate
"
+8 -1
View File
@@ -1,6 +1,6 @@
# Gitea Alpine Package
Repackages upstream Gitea 1.26.4 Linux release binaries for `x86_64` and
Repackages upstream Gitea 1.27.0 Linux release binaries for `x86_64` and
`aarch64`.
The package follows Alpine's Gitea runtime layout:
@@ -19,6 +19,13 @@ rc-update add gitea default
rc-service gitea start
```
Install daily rotation for the OpenRC service log, retaining 14 compressed
archives:
```sh
apk add gitea-logrotate
```
Refresh checksums:
```sh
+2 -1
View File
@@ -1,4 +1,5 @@
# Configuration cheat sheet: https://docs.gitea.io/en-us/config-cheat-sheet/
# Configuration cheat sheet: https://docs.gitea.com/administration/config-cheat-sheet/
# Example configuration: https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini
RUN_USER = gitea
RUN_MODE = prod
@@ -0,0 +1,10 @@
/var/log/gitea/http.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
copytruncate
su gitea www-data
}
@@ -2,45 +2,10 @@
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-gitea}"
package_version="${PACKAGE_VERSION:-1.26.4-r0}"
alpine_version="${ALPINE_VERSION:-3.24}"
arch="${ALPINE_ARCH:-x86_64}"
repository_url="${ALPINE_REPOSITORY_URL:-}"
repository_key_url="${ALPINE_REPOSITORY_KEY_URL:-}"
# shellcheck source=scripts/apk/test-install-lib.sh
. "${repo_root}/scripts/apk/test-install-lib.sh"
case "${arch}" in
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ -z "${repository_url}" && "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ -z "${repository_url}" && ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-e "PACKAGE_VERSION=${package_version}" \
-e "ALPINE_REPOSITORY_URL=${repository_url}" \
-e "ALPINE_REPOSITORY_KEY_URL=${repository_key_url}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-gitea}" "${PACKAGE_VERSION:-28.0.0-r1}" <<'SCRIPT'
set -e
if [ -n "${ALPINE_REPOSITORY_URL}" ]; then
@@ -64,7 +29,7 @@ docker run --rm --platform "${platform}" \
printf "%s\n" /repo >> /etc/apk/repositories
fi
apk update
apk add --upgrade "${PACKAGE_NAME}" "${PACKAGE_NAME}-doc" "${PACKAGE_NAME}-openrc"
apk add --upgrade "${PACKAGE_NAME}" "${PACKAGE_NAME}-doc" "${PACKAGE_NAME}-logrotate" "${PACKAGE_NAME}-openrc"
installed_after="$(apk list -I "${PACKAGE_NAME}" | awk "{print \$1}")"
printf "Installed package after local upgrade: %s\n" "${installed_after}"
test "${installed_after}" = "${PACKAGE_NAME}-${PACKAGE_VERSION}"
@@ -80,9 +45,12 @@ docker run --rm --platform "${platform}" \
test -d /usr/share/webapps/gitea/public
test -d /usr/share/webapps/gitea/templates
test -f /etc/init.d/gitea
test -f /etc/logrotate.d/gitea
apk info -e logrotate
logrotate -d /etc/logrotate.conf
gitea --version
rc-update add gitea default
test -L /etc/runlevels/default/gitea
'
SCRIPT
@@ -0,0 +1,3 @@
provider=github
repo=go-gitea/gitea
version_prefix=v
+42 -13
View File
@@ -1,7 +1,7 @@
# Maintainer: Joachim Schlöffel <me@joachim-schloeffel.com>
# Maintainer: Joachim Schlöffel <joachim.schloeffel@financial-service-plus.de>
pkgname=greptimedb
pkgver=1.1.2
pkgrel=0
pkgver=1.2.1
pkgrel=4
pkgdesc="Cloud-native observability database for metrics, logs, and traces"
url="https://github.com/GreptimeTeam/greptimedb"
arch="x86_64"
@@ -12,14 +12,17 @@ makedepends="
clang
cmake
coreutils
curl
cargo-auditable
git
lld
linux-headers
make
mold
nodejs
openssl-dev
openssl-libs-static
perl
pnpm
protobuf
protobuf-dev
rustup
@@ -28,12 +31,14 @@ makedepends="
zstd-dev
zstd-static
"
checkdepends="cargo-nextest"
install="$pkgname.pre-install"
subpackages="
$pkgname-datanode-openrc:_openrc_datanode:noarch
$pkgname-docs:_docs:noarch
$pkgname-flownode-openrc:_openrc_flownode:noarch
$pkgname-frontend-openrc:_openrc_frontend:noarch
$pkgname-logrotate:_logrotate:noarch
$pkgname-metasrv-openrc:_openrc_metasrv:noarch
$pkgname-standalone-openrc:_openrc_standalone:noarch
"
@@ -41,7 +46,7 @@ options="net"
_dashboard_version="v0.12.0"
source="
$pkgname-$pkgver.tar.gz::https://github.com/GreptimeTeam/greptimedb/archive/refs/tags/v$pkgver.tar.gz
dashboard-$_dashboard_version.tar.gz::https://github.com/GreptimeTeam/dashboard/releases/download/$_dashboard_version/build.tar.gz
dashboard-$_dashboard_version.tar.gz::https://github.com/GreptimeTeam/dashboard/archive/refs/tags/$_dashboard_version.tar.gz
datanode.toml
flownode.toml
frontend.toml
@@ -49,6 +54,7 @@ source="
greptimedb.flownode.confd
greptimedb.frontend.confd
greptimedb.initd
greptimedb.logrotate
greptimedb.metasrv.confd
greptimedb.standalone.confd
metasrv.toml
@@ -64,31 +70,45 @@ export CARGO_BUILD_JOBS="${CARGO_BUILD_JOBS:-2}"
export CARGO_PROFILE_NIGHTLY_CODEGEN_UNITS="${CARGO_PROFILE_NIGHTLY_CODEGEN_UNITS:-16}"
export CARGO_PROFILE_NIGHTLY_DEBUG="${CARGO_PROFILE_NIGHTLY_DEBUG:-false}"
export CARGO_PROFILE_NIGHTLY_LTO="${CARGO_PROFILE_NIGHTLY_LTO:-thin}"
export CARGO_PROFILE_TEST_DEBUG="${CARGO_PROFILE_TEST_DEBUG:-false}"
export LIBRARY_PATH="/usr/lib"
export RUSTFLAGS="${RUSTFLAGS:-} -C link-arg=-fuse-ld=mold"
prepare() {
default_prepare
if [ ! -d "$builddir"/src/servers/dashboard/dist ]; then
mv "$srcdir"/dist "$builddir"/src/servers/dashboard/dist
fi
rustup-init \
-y \
--no-modify-path \
--profile minimal \
--default-toolchain "$_rust_toolchain"
"$CARGO_HOME"/bin/rustup run "$_rust_toolchain" cargo fetch \
--locked
local _dashboard_builddir="$srcdir"/dashboard-${_dashboard_version#v}
(
cd "$_dashboard_builddir"
pnpm install --frozen-lockfile --store-dir "$srcdir"/pnpm-store
pnpm run build:docker
)
rm -rf "$builddir"/src/servers/dashboard/dist
cp -a "$_dashboard_builddir"/dist "$builddir"/src/servers/dashboard/
}
build() {
"$CARGO_HOME"/bin/rustup run "$_rust_toolchain" cargo build \
"$CARGO_HOME"/bin/rustup run "$_rust_toolchain" cargo auditable build \
--profile "$_cargo_profile" \
--frozen \
--locked \
--bin greptime \
--features servers/dashboard
}
check() {
"$CARGO_TARGET_DIR"/"$_cargo_profile"/greptime --version
"$CARGO_HOME"/bin/rustup run "$_rust_toolchain" cargo nextest run \
-p cmd \
--lib \
--frozen
}
package() {
@@ -118,6 +138,14 @@ _openrc_frontend() { _openrc_service frontend; }
_openrc_metasrv() { _openrc_service metasrv; }
_openrc_standalone() { _openrc_service standalone; }
_logrotate() {
pkgdesc="Log rotation configuration for $pkgname"
depends="$pkgname=$pkgver-r$pkgrel logrotate"
install -Dm644 "$srcdir"/greptimedb.logrotate \
"$subpkgdir"/etc/logrotate.d/$pkgname
}
_docs() {
pkgdesc="$pkgdesc (configuration examples and reference)"
depends=""
@@ -127,15 +155,16 @@ _docs() {
}
sha512sums="
bc449d2f2a2513e6ba326cac951ddfc87461e8fa7bbdd3d9935990d7718b24a298547154786c2129379d79f5e3cbf0515e5b82a2e79d28ea8d00fcc7384da447 greptimedb-1.1.2.tar.gz
4260acae5bed00a693dceffe9f53d0f8b25fd677b15638e951cf973dc29681f4bacde352c661a12bd78af7be9181a3740812f814fc3c4c8c87ea4eee6ee07e2d dashboard-v0.12.0.tar.gz
fc580f6e34df84b4f37219047d751968324c356f3cad352d1515abb4b441515a1ad98f0d01e2de33aac5129a2d7a5335edc4d8888923da7683a084a484769bea greptimedb-1.2.1.tar.gz
3f853b6767a86cfa97ec640a17de59b2e798561c9402026e9b3a749907780b9b686149dba8a932b5d61ae538c430deab2410248e5c9e6e1961909000445ee2ee dashboard-v0.12.0.tar.gz
29cc3376753487b216748e3f85e12639830e1ac4a763e94f330f87c3651a8ef9de35732958311c0049e1b7cbb4e90a9e602b3aff43297fe088c5ce795a110a79 datanode.toml
52790808cb4f5cf0220ac2ab169b623fe76b6318d27d7f003e1197e850373cb915bfd40556098bcb7650f293d751039cb3bccbf9107bb160b8284887794ba975 flownode.toml
e3e19ab3c7a345ecf8cf0a507f7fc95dd3b036a4a797385cf77fcf1999f2e4f053042c7bbda8de73ed43ff72e87aad81e4ac6d4a34d01773bbc1f6d0d967d9f7 frontend.toml
313ed7d9ccd174b1869f3009e174266cdc414599e0b0f8307c8aaf2b73841eb36ce4c1b2f6244a0358b5a587a4edaa621b781fbd767835088b3fa13623fcc0df greptimedb.datanode.confd
daf8efacc8bf2b74abd9f4900f889585295b57333a8a562a722de0596d35f25d5f9149e0879f4140bfdf727caa59c3f55b1380212722df92c588d912275530b8 greptimedb.flownode.confd
e3e61b1df00f8172a3b1d4a0d37ed2574a8c5cd27676b4e2ce14d15ad8933d233baabe8da374f715d00cfaee26f665244c1ba00f70197fcc713c4e9af9c3229e greptimedb.frontend.confd
c00740aee566b161bbe3610e0e0d6e8340022055750e6778772262474ffd6484d9f58be2fd498beafe28d0943e259e2277930af691bedea7650726e6c8998881 greptimedb.initd
f72f52aa8277fc56eb071b5118990b8f4e09d143634c2f7fc54ed1f5ff065631c8630c45fe90d3db1f3ea0540c1ab3154a383d2000b4c5978e889ca02a1b6564 greptimedb.initd
775b4db7e7bc6127376b22fed8330b952c5027e3bfbfa29bb6ae034e6c75e7fed8ddfc0ad9761f369acd37398dfbd145cfea210828f2fc0bec9be92b051e6a75 greptimedb.logrotate
df495367d85844dcba99e5aa01e5a23fd14799b7521a72d9ea00d29fc0e5fbc5c5d06ee88e88d9637e260f8337249a39d2b0115de58da4899824d20bd844254a greptimedb.metasrv.confd
882a79e969cac42adfada22060e6507fb687755a6d266d6728154b3e4da5777d2eaf5ad9bc331ed050448249ca609e6a61977b624d9faf25d83ed975345452cf greptimedb.standalone.confd
8120ec338ebe1330d43b20d9b34a8f5f778ea13cb056febd3c8e9dc189d0de2380b90e5474a0990294d7004827c6133d44d2dd3e32d463b9259c47c82592d257 metasrv.toml
+14 -4
View File
@@ -1,14 +1,22 @@
# GreptimeDB Alpine Package
Builds `greptime` from the upstream source release and packages OpenRC service
subpackages plus `/etc/greptimedb` defaults.
Builds `greptime` and its embedded dashboard from their upstream source
releases, and packages OpenRC service subpackages plus `/etc/greptimedb`
defaults.
Build command:
```sh
cargo build --profile nightly --locked --bin greptime --features servers/dashboard
cargo auditable build --profile nightly --frozen --locked --bin greptime --features servers/dashboard
```
GreptimeDB requires the nightly pinned in its source release
(`nightly-2026-03-21`). The package uses Rustup to install that toolchain and
uses locked Cargo and pnpm dependency resolution, so `options="net"` is
intentional. Cargo dependencies are fetched before compilation; the Rust build
then runs frozen. The dashboard is built from the matching `v0.12.0` source tag
with its checked-in `pnpm-lock.yaml`.
## Runtime Layout
Installs `/usr/bin/greptime` and component OpenRC packages:
@@ -20,6 +28,8 @@ Installs `/usr/bin/greptime` and component OpenRC packages:
- `greptimedb-datanode-openrc`: `greptime datanode start`
- `greptimedb-flownode-openrc`: `greptime flownode start`
- `greptimedb-frontend-openrc`: `greptime frontend start`
- `greptimedb-logrotate`: daily rotation for the OpenRC service logs, retaining
14 compressed archives
Default TOML files are installed in `/etc/greptimedb`. Standalone ports:
@@ -92,4 +102,4 @@ ALPINE_REPOSITORY_KEY_URL=https://code.factoring.digital/api/packages/public/alp
mise run apk:test-install
```
Full builds take close to an hour.
Full builds and the targeted upstream Nextest check take close to an hour.
@@ -6,6 +6,7 @@ description="GreptimeDB ${service_name} service"
command="/usr/bin/greptime"
command_user="${GREPTIMEDB_USER:-greptimedb}:${GREPTIMEDB_GROUP:-greptimedb}"
command_background="yes"
retry="TERM/30/KILL/5"
pidfile="/run/greptimedb/${RC_SVCNAME}.pid"
output_log="${GREPTIMEDB_LOG:-/var/log/greptimedb/${RC_SVCNAME}.log}"
error_log="${GREPTIMEDB_ERRLOG:-/var/log/greptimedb/${RC_SVCNAME}.log}"
@@ -0,0 +1,10 @@
/var/log/greptimedb/greptimedb.*.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
copytruncate
su greptimedb greptimedb
}
@@ -21,3 +21,14 @@ greptime --version
rc-update add greptimedb.standalone default || true
test -L /etc/runlevels/default/greptimedb.standalone
rc-service greptimedb.standalone start
for _attempt in $(seq 1 30); do
if wget -qO- http://127.0.0.1:4000/status >/dev/null; then
break
fi
sleep 1
done
wget -qO- http://127.0.0.1:4000/status >/dev/null
wget -qO- http://127.0.0.1:4000/dashboard/ | grep -qi '<!doctype html>'
rc-service greptimedb.standalone stop
@@ -2,43 +2,10 @@
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-greptimedb}"
alpine_version="${ALPINE_VERSION:-3.24}"
arch="${ALPINE_ARCH:-x86_64}"
repository_url="${ALPINE_REPOSITORY_URL:-}"
repository_key_url="${ALPINE_REPOSITORY_KEY_URL:-}"
# shellcheck source=scripts/apk/test-install-lib.sh
. "${repo_root}/scripts/apk/test-install-lib.sh"
case "${arch}" in
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ -z "${repository_url}" && "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ -z "${repository_url}" && ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-e "ALPINE_REPOSITORY_URL=${repository_url}" \
-e "ALPINE_REPOSITORY_KEY_URL=${repository_key_url}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-greptimedb}" "${PACKAGE_VERSION:-}" <<'SCRIPT'
set -e
if [ -n "${ALPINE_REPOSITORY_URL}" ]; then
@@ -59,6 +26,7 @@ docker run --rm --platform "${platform}" \
"${PACKAGE_NAME}-docs" \
"${PACKAGE_NAME}-flownode-openrc" \
"${PACKAGE_NAME}-frontend-openrc" \
"${PACKAGE_NAME}-logrotate" \
"${PACKAGE_NAME}-metasrv-openrc" \
"${PACKAGE_NAME}-standalone-openrc"
@@ -67,5 +35,8 @@ docker run --rm --platform "${platform}" \
ls -1 /etc/greptimedb
test -f "/usr/share/doc/${PACKAGE_NAME}/config/config.md"
test -f "/usr/share/doc/${PACKAGE_NAME}/config/standalone.example.toml"
test -f /etc/logrotate.d/greptimedb
apk info -e logrotate
logrotate -d /etc/logrotate.conf
find /etc/init.d -maxdepth 1 -name "greptimedb.*" -print | sort
'
SCRIPT
@@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
package_dir="${PACKAGE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
printf 'No generated sources for %s\n' "${package_dir}"
@@ -0,0 +1,3 @@
provider=github
repo=GreptimeTeam/greptimedb
version_prefix=v
+34 -13
View File
@@ -1,15 +1,14 @@
# Maintainer: Joachim Schlöffel <me@joachim-schloeffel.com>
# Maintainer: Joachim Schlöffel <joachim.schloeffel@financial-service-plus.de>
pkgname=lavinmq
pkgver=2.9.1
pkgrel=0
pkgver=2.10.1
pkgrel=1
pkgdesc="High-performance AMQP and MQTT message queue server"
url="https://github.com/cloudamqp/lavinmq"
arch="x86_64"
license="Apache-2.0"
depends="ca-certificates /bin/sh"
makedepends="
crystal>=1.20.1
curl
crystal>=1.21.0
gc-dev
help2man
libevent-dev
@@ -23,35 +22,45 @@ makedepends="
yaml-dev
"
install="$pkgname.pre-install"
pkgusers="lavinmq"
pkggroups="lavinmq"
subpackages="
$pkgname-doc
$pkgname-logrotate:_logrotate:noarch
$pkgname-openrc:_openrc:noarch
"
options="net"
source="
$pkgname-$pkgver.tar.gz::https://github.com/cloudamqp/lavinmq/archive/refs/tags/v$pkgver.tar.gz
$pkgname-$pkgver-shards.tar.gz
$pkgname-$pkgver-assets.tar.gz
lavinmq.confd
lavinmq.initd
lavinmq.logrotate
use-vendored-build-inputs.patch
"
export CRYSTAL_CACHE_DIR="${CRYSTAL_CACHE_DIR:-$srcdir/crystal-cache}"
export SHARDS_CACHE_PATH="${SHARDS_CACHE_PATH:-$srcdir/shards-cache}"
prepare() {
default_prepare
tar -xzf "$srcdir/$pkgname-$pkgver-shards.tar.gz" -C "$builddir"
mkdir -p "$builddir/.alpine-assets"
tar -xzf "$srcdir/$pkgname-$pkgver-assets.tar.gz" -C "$builddir/.alpine-assets"
}
build() {
crystal --version
make
make man
}
check() {
bin/lavinmq -v
bin/lavinmqctl --version
bin/lavinmqperf --version
crystal spec spec/config_spec.cr
}
package() {
make DESTDIR="$pkgdir" install
rm -r "$pkgdir"/lib/systemd "$pkgdir"/usr/lib/sysusers.d
rmdir "$pkgdir"/lib "$pkgdir"/usr/lib
install -d -m 0750 -o lavinmq -g lavinmq "$pkgdir"/var/lib/lavinmq
}
_openrc() {
@@ -64,8 +73,20 @@ _openrc() {
"$subpkgdir"/etc/conf.d/lavinmq
}
_logrotate() {
pkgdesc="Log rotation configuration for $pkgname"
depends="$pkgname=$pkgver-r$pkgrel logrotate"
install -Dm644 "$srcdir"/lavinmq.logrotate \
"$subpkgdir"/etc/logrotate.d/$pkgname
}
sha512sums="
5f88de7a1e093b1f6e2ead5c340140bd489a99ca8adfa9f40052148490d0bdf8ff1e2dad67727e9799ad1f942755df01525e63d24b0901684a743f43c42110b9 lavinmq-2.9.1.tar.gz
1c2c932a0698227abfe8353988ea75b48f9048f183d85410797af5bc14495e2cb4497e72acc8fc9ff9ef8f78e8ebb648a1b40b5cf7f1b86e18597d10297417ff lavinmq-2.10.1.tar.gz
d0dfdd5c0e474024f57deb9e31c76e3f176e798c8d21dea53d3aea1b05436bd03fa34e69ccddf322bc89adedce5f379df5a316cddbbdfe12520e5bf672ad8228 lavinmq-2.10.1-shards.tar.gz
ae3cea2534b211abbcbd1e4fcb6da73dfaf383a19aef1c45f367cba77492cc20a7ce8283fc42f26c0a023149114c369bed307fb8cde0b8f27fba61165092e986 lavinmq-2.10.1-assets.tar.gz
62a609d50f28db960098c4c84ce4f1dad78413366a9a9aca18fe321114d687be3bf7b71924d4ace69bd74383c5ac40d2ee09ae0eef9c1bfe653b97448e42e110 lavinmq.confd
76fbfa1b14c58631e92f817e689584239eb644e68460c091decdcabe7661aeb210f9128545262add2fb07eeee155c8734f1e612fc59ebb897d3c67e95a56350f lavinmq.initd
1853196e70297b5c4a2207fde50df735620cf6d99c4994644fd676bffaf863d67300ad7ae771c4bbb86fce1a0485c2a7968cf912c5f5bb878e08b15e5a28ba1b lavinmq.initd
9999dd6a96bd29a3d0bda1b2110af940b15acf1250a0f3ba6c93d16bd62063ab1c1dfa4c237da99bbb401150517abde59e2c7275f4b72c3eb7c90e1ce61d43b9 lavinmq.logrotate
e7617099f745ecbf2f0686830d0a1b28044741ebd543798505b5b3c08f1be96b6cc478eb18f6785af49b100c2f49d837775f0721ac27519ddf3f081e681c581c use-vendored-build-inputs.patch
"
+41 -3
View File
@@ -1,7 +1,9 @@
# LavinMQ Alpine Package
Builds LavinMQ from the upstream source release for `x86_64` and packages the
OpenRC service plus `/etc/lavinmq` defaults.
OpenRC service plus `/etc/lavinmq` defaults. The locked Shards dependencies and
frontend assets are versioned, checksummed source inputs, so the build does not
need network access.
Build command:
@@ -9,8 +11,9 @@ Build command:
make
```
LavinMQ 2.9.1 requires Crystal 1.20.1 or newer, so build with Alpine 3.24 or
newer.
LavinMQ 2.10.1 requires Crystal 1.21.0 or newer. The package uses Alpine
edge's native Crystal package, avoiding a glibc toolchain in the Alpine musl
build.
## Runtime Layout
@@ -35,12 +38,47 @@ rc-update add lavinmq default
rc-service lavinmq start
```
Install daily rotation for the OpenRC service log, retaining 14 compressed
archives:
```sh
apk add lavinmq-logrotate
```
Wrapper settings in `/etc/conf.d/lavinmq`:
- `LAVINMQ_CONFIG`: config file path passed with `--config`
- `LAVINMQ_DATA_DIR`: data directory passed with `-D`
- `LAVINMQ_OPTS`: extra LavinMQ arguments appended after package defaults
## Updating LavinMQ
1. In `APKBUILD`, set `pkgver` to the new upstream version and reset `pkgrel`
to `0`.
2. Add versioned vendored archives for the locked Shards dependencies and
frontend assets. If the new upstream `shard.lock` and the asset rules in its
`Makefile` are unchanged, the existing archives can be reused under the new
names:
```sh
cd packaging/alpine/local/lavinmq
cp lavinmq-2.10.1-shards.tar.gz lavinmq-<version>-shards.tar.gz
cp lavinmq-2.10.1-assets.tar.gz lavinmq-<version>-assets.tar.gz
git add -f lavinmq-<version>-shards.tar.gz lavinmq-<version>-assets.tar.gz
```
When `shard.lock` changes, extract the upstream source, run
`shards install --production` in it, and create the shards archive with
`tar -czf lavinmq-<version>-shards.tar.gz lib`. If the asset rules change,
download the files specified by the new `Makefile` to a staging directory
and create `lavinmq-<version>-assets.tar.gz` from that directory's contents.
3. From the repository root, refresh checksums and build the package:
```sh
ALPINE_PACKAGE=lavinmq mise run apk:checksum
ALPINE_PACKAGE=lavinmq mise run apk:build
```
## Package Commands
Refresh checksums:
+5 -3
View File
@@ -18,9 +18,11 @@ depend() {
}
start_pre() {
checkpath -d -m 0755 -o "${LAVINMQ_USER:-lavinmq}:${LAVINMQ_GROUP:-lavinmq}" \
local service_owner="${LAVINMQ_USER:-lavinmq}:${LAVINMQ_GROUP:-lavinmq}"
checkpath -d -m 0755 -o "$service_owner" \
/run/lavinmq \
/var/log/lavinmq
checkpath -d -m 0750 -o "${LAVINMQ_USER:-lavinmq}:${LAVINMQ_GROUP:-lavinmq}" \
"$data_dir"
checkpath -d -m 0750 -o "$service_owner" "$data_dir"
checkpath -f -m 0640 -o "$service_owner" "$data_dir"/.lock
}
@@ -0,0 +1,10 @@
/var/log/lavinmq/lavinmq.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
copytruncate
su lavinmq lavinmq
}
@@ -8,6 +8,7 @@ test -x /usr/bin/lavinmqctl
test -x /usr/bin/lavinmqperf
test -f /etc/lavinmq/lavinmq.ini
test -d /var/lib/lavinmq
test "$(stat -c '%U:%G %a' /var/lib/lavinmq)" = "lavinmq:lavinmq 750"
test -f /etc/conf.d/lavinmq
test -f /etc/init.d/lavinmq
test -f /usr/share/doc/lavinmq/README.md
@@ -2,43 +2,10 @@
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-lavinmq}"
alpine_version="${ALPINE_VERSION:-3.24}"
arch="${ALPINE_ARCH:-x86_64}"
repository_url="${ALPINE_REPOSITORY_URL:-}"
repository_key_url="${ALPINE_REPOSITORY_KEY_URL:-}"
# shellcheck source=scripts/apk/test-install-lib.sh
. "${repo_root}/scripts/apk/test-install-lib.sh"
case "${arch}" in
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ -z "${repository_url}" && "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ -z "${repository_url}" && ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-e "ALPINE_REPOSITORY_URL=${repository_url}" \
-e "ALPINE_REPOSITORY_KEY_URL=${repository_key_url}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-lavinmq}" "${PACKAGE_VERSION:-}" <<'SCRIPT'
set -e
if [ -n "${ALPINE_REPOSITORY_URL}" ]; then
@@ -53,15 +20,19 @@ docker run --rm --platform "${platform}" \
printf "%s\n" /repo >> /etc/apk/repositories
fi
apk update
apk add "${PACKAGE_NAME}" "${PACKAGE_NAME}-doc" "${PACKAGE_NAME}-openrc"
apk add "${PACKAGE_NAME}" "${PACKAGE_NAME}-doc" "${PACKAGE_NAME}-logrotate" "${PACKAGE_NAME}-openrc"
test -x /usr/bin/lavinmq
test -x /usr/bin/lavinmqctl
test -x /usr/bin/lavinmqperf
test -f /etc/lavinmq/lavinmq.ini
test -d /var/lib/lavinmq
test "$(stat -c "%U:%G %a" /var/lib/lavinmq)" = "lavinmq:lavinmq 750"
test -f /etc/conf.d/lavinmq
test -f /etc/init.d/lavinmq
test -f /etc/logrotate.d/lavinmq
apk info -e logrotate
logrotate -d /etc/logrotate.conf
test -f /usr/share/doc/lavinmq/README.md
test -f /usr/share/doc/lavinmq/changelog
@@ -71,4 +42,4 @@ docker run --rm --platform "${platform}" \
rc-update add lavinmq default
test -L /etc/runlevels/default/lavinmq
'
SCRIPT
@@ -0,0 +1,3 @@
provider=github
repo=cloudamqp/lavinmq
version_prefix=v
@@ -0,0 +1,36 @@
--- a/Makefile
+++ b/Makefile
@@ -8,0 +9 @@
+LAVINMQ_ASSET_DIR ?= .alpine-assets
@@ -55,2 +56,2 @@
-lib: shard.yml shard.lock
- shards install --production
+lib:
+ test -d lib
@@ -62,3 +63 @@
- curl --fail --retry 5 -sL https://github.com/chartjs/Chart.js/releases/download/v4.0.1/chart.js-4.0.1.tgz | \
- tar -zxOf- package/dist/chart.js > $@
- [ "038d0a4f9c61f0b35ff70f883e7591403a349542625a4caaf48caa141adedfd5 *$@" = "$$(openssl dgst -sha256 -r $@)" ]
+ install -Dm644 "$(LAVINMQ_ASSET_DIR)/chart.js" "$@"
@@ -67,3 +66 @@
- curl --fail --retry 5 -sL https://github.com/chartjs/Chart.js/releases/download/v4.0.1/chart.js-4.0.1.tgz | \
- tar -zxOf- package/dist/chunks/helpers.segment.js > $@
- [ "b4746b748fe583a18ef921e341b8b65166c2ebd0b737fde6527b254baaeb1aa1 *$@" = "$$(openssl dgst -sha256 -r $@)" ]
+ install -Dm644 "$(LAVINMQ_ASSET_DIR)/helpers.segment.js" "$@"
@@ -72,2 +69 @@
- curl --fail --retry 5 -sLo $@ https://moment.github.io/luxon/es6/luxon.mjs
- [ "b495ad5cabea3439d04387e6622f2c3fa81d319424d9d76d9e7f874ac5a0807a *$@" = "$$(openssl dgst -sha256 -r $@)" ]
+ install -Dm644 "$(LAVINMQ_ASSET_DIR)/luxon.js" "$@"
@@ -76,3 +72 @@
- curl --fail --retry 5 -sLo $@ https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.3.1/dist/chartjs-adapter-luxon.esm.js
- sed -i'' -e "s|\(import { _adapters } from\).*|\1 './chart.js'|; s|\(import { DateTime } from\).*|\1 './luxon.js'|" $@
- [ "17d7b6567d656a004f86b6b5cbdbe64cb308e9a2ebfa7675caa79ba0bc72ef91 *$@" = "$$(openssl dgst -sha256 -r $@)" ]
+ install -Dm644 "$(LAVINMQ_ASSET_DIR)/chartjs-adapter-luxon.esm.js" "$@"
@@ -81,2 +75 @@
- curl --fail --retry 5 -sLo $@ https://unpkg.com/@stoplight/elements@8.2.0/web-components.min.js
- [ "598862da6d551769ebad9d61d4e3037535de573a13d3e0bd1ded4c5fc65c5885 *$@" = "$$(openssl dgst -sha256 -r $@)" ]
+ install -Dm644 "$(LAVINMQ_ASSET_DIR)/elements-8.2.0.js" "$@"
@@ -85,2 +78 @@
- curl --fail --retry 5 -sLo $@ https://unpkg.com/@stoplight/elements@8.2.0/styles.min.css
- [ "119784e23ffc39b6fa3fdb3df93f391f8250e8af141b78dfc3b6bed86079f93b *$@" = "$$(openssl dgst -sha256 -r $@)" ]
+ install -Dm644 "$(LAVINMQ_ASSET_DIR)/elements-8.2.0.css" "$@"
+75
View File
@@ -0,0 +1,75 @@
# Maintainer: Joachim Schlöffel <joachim.schloeffel@financial-service-plus.de>
pkgname=nifi
pkgver=2.12.0
pkgrel=0
pkgdesc="Reliable system for processing and distributing data"
url="https://nifi.apache.org/"
arch="x86_64 aarch64"
license="Apache-2.0"
depends="openjdk21-jre-headless"
makedepends="unzip"
install="$pkgname.pre-install"
pkgusers="nifi"
pkggroups="nifi"
subpackages="
$pkgname-openrc:_openrc:noarch
"
options="!check !strip !tracedeps"
source="
$pkgname-$pkgver-bin.zip::https://dlcdn.apache.org/nifi/$pkgver/nifi-$pkgver-bin.zip
nifi.confd
nifi.initd
nifi.wrapper
"
package() {
local _dir
install -d "$pkgdir"/usr/lib/nifi "$pkgdir"/etc/nifi
cp -a "$builddir"/. "$pkgdir"/usr/lib/nifi/
chmod -R a+rX "$pkgdir"/usr/lib/nifi
cp -a "$pkgdir"/usr/lib/nifi/conf/. "$pkgdir"/etc/nifi/
rm -r "$pkgdir"/usr/lib/nifi/conf
ln -s /etc/nifi "$pkgdir"/usr/lib/nifi/conf
install -d -m 0750 -o nifi -g nifi "$pkgdir"/var/lib/nifi
for _dir in \
assets \
connector_assets \
content_repository \
database_repository \
diagnostics \
extensions \
flowfile_repository \
nar_repository \
provenance_repository \
state \
status_repository \
work; do
install -d -m 0750 -o nifi -g nifi "$pkgdir"/var/lib/nifi/$_dir
ln -s /var/lib/nifi/$_dir "$pkgdir"/usr/lib/nifi/$_dir
done
install -d -m 0750 -o nifi -g nifi "$pkgdir"/var/log/nifi
ln -s /var/log/nifi "$pkgdir"/usr/lib/nifi/logs
ln -s /run/nifi "$pkgdir"/usr/lib/nifi/run
chown -R nifi:nifi "$pkgdir"/etc/nifi
chmod 0750 "$pkgdir"/etc/nifi
install -Dm755 "$srcdir"/nifi.wrapper "$pkgdir"/usr/bin/nifi
}
_openrc() {
pkgdesc="$pkgdesc (OpenRC service)"
depends="$pkgname=$pkgver-r$pkgrel openrc"
install -Dm755 "$srcdir"/nifi.initd "$subpkgdir"/etc/init.d/nifi
install -Dm644 "$srcdir"/nifi.confd "$subpkgdir"/etc/conf.d/nifi
}
sha512sums="
5891039ccf15234bb21c2d1ce65027357ca7603ad8fdfc946dd4b6499ab8061fb07a6a56f8e8c5bb7635d446354ca7cc76ba40e55921818931f193a75f247334 nifi-2.12.0-bin.zip
fd576c2d2333aa79f7dac90e83f9cf6e0faed9748ebce0dfc1c18bcd1da0ec1d0da90d4004055bbddcb0f011a0e9efdc08f0eed2f3c19d49b1746019f2be1da9 nifi.confd
9f8a005fcd6a6f75a553321c27c672c4c202e8b86ff5fa0a1bd5eb0e7305592e67d8dc6a915d1f1bc01b39916b0fb0e61478cb6ae5aee4ae8b3be36c80c5662a nifi.initd
7764c6a53f0fb109ecde4959b438a0eeb669b00eafdbdb2abe5255f4053a237d4e97349594b3bf053abd55a96f8e217aa0cf0fec59a7c14f1db2490e747f713e nifi.wrapper
"
+50
View File
@@ -0,0 +1,50 @@
# Apache NiFi Alpine Package
Repackages Apache NiFi 2.12.0 Standard for Alpine. The package requires Java
21 and retains NiFi 2's secure default: HTTPS listens on `127.0.0.1:8443` and
uses generated single-user credentials.
## Install
```sh
apk add nifi nifi-openrc
rc-update add nifi default
rc-service nifi start
```
Open `https://127.0.0.1:8443/nifi` and retrieve the generated credentials:
```sh
grep 'Generated \(Username\|Password\)' /var/log/nifi/nifi-app.log
```
Set fixed single-user credentials as the service account:
```sh
doas -u nifi nifi set-single-user-credentials '<username>' '<password>'
rc-service nifi restart
```
## Runtime Layout
```text
/usr/bin/nifi Administration command wrapper
/usr/lib/nifi NiFi binaries and bundled NARs
/etc/nifi Mutable NiFi configuration and authorization state
/var/lib/nifi Repositories, state, extensions, and work files
/var/log/nifi Application logs
/etc/conf.d/nifi OpenRC account defaults
/etc/init.d/nifi OpenRC service
```
Edit `/etc/nifi/nifi.properties` to bind a different HTTPS address, configure
TLS, or select LDAP, OIDC, or another supported authentication provider.
## Package Commands
```sh
ALPINE_PACKAGE=nifi mise run apk:checksum
ALPINE_PACKAGE=nifi mise run apk:build
ALPINE_PACKAGE=nifi SKIP_BUILD=1 mise run apk:test-install
ALPINE_PACKAGE=nifi mise run apk:runtime-test
```
+3
View File
@@ -0,0 +1,3 @@
# Defaults for Apache NiFi.
NIFI_USER="nifi"
NIFI_GROUP="nifi"
+26
View File
@@ -0,0 +1,26 @@
#!/sbin/openrc-run
description="Apache NiFi dataflow service"
supervisor=supervise-daemon
name=nifi
command="/usr/lib/nifi/bin/nifi.sh"
command_args="run"
command_user="${NIFI_USER:-nifi}:${NIFI_GROUP:-nifi}"
directory="/usr/lib/nifi"
pidfile="/run/nifi/nifi.pid"
supervise_daemon_args="--chdir /usr/lib/nifi --env HOME=/var/lib/nifi --pidfile ${pidfile}"
depend() {
need net
use dns logger
}
start_pre() {
local service_owner="${NIFI_USER:-nifi}:${NIFI_GROUP:-nifi}"
checkpath -d -m 0750 -o "$service_owner" \
/run/nifi \
/var/lib/nifi \
/var/log/nifi
}
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
addgroup -S nifi 2>/dev/null
adduser -S -D -H -h /var/lib/nifi -s /sbin/nologin \
-G nifi -g nifi nifi 2>/dev/null
exit 0
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
exec /usr/lib/nifi/bin/nifi.sh "$@"
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -euo pipefail
apk add nifi nifi-openrc curl
test -x /usr/bin/nifi
test -x /usr/lib/nifi/bin/nifi.sh
test -d /etc/nifi
test -L /usr/lib/nifi/conf
test "$(readlink /usr/lib/nifi/conf)" = /etc/nifi
test -d /var/lib/nifi
test -d /var/log/nifi
test -f /etc/init.d/nifi
test -f /etc/conf.d/nifi
test -d /usr/lib/nifi/docs
test "$(stat -c '%U:%G %a' /var/lib/nifi)" = "nifi:nifi 750"
rc-update add nifi default || true
test -L /etc/runlevels/default/nifi
rc-service nifi start
for _attempt in $(seq 1 300); do
if curl --fail --insecure --silent --show-error \
https://localhost:8443/nifi/ >/dev/null; then
break
fi
sleep 1
done
curl --fail --insecure --silent --show-error https://localhost:8443/nifi/ >/dev/null
grep -q 'Generated Username' /var/log/nifi/nifi-app.log
grep -q 'Generated Password' /var/log/nifi/nifi-app.log
rc-service nifi status
rc-service nifi stop
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
# shellcheck source=scripts/apk/test-install-lib.sh
. "${repo_root}/scripts/apk/test-install-lib.sh"
apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-nifi}" "${PACKAGE_VERSION:-2.12.0-r0}" <<'SCRIPT'
set -e
if [ -n "${ALPINE_REPOSITORY_URL}" ]; then
if [ -n "${ALPINE_REPOSITORY_KEY_URL}" ]; then
apk add --no-cache curl >/dev/null
cd /etc/apk/keys
curl -fsSLOJ "${ALPINE_REPOSITORY_KEY_URL}"
fi
printf "%s\n" "${ALPINE_REPOSITORY_URL}" >> /etc/apk/repositories
else
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories
fi
apk update
apk add "${PACKAGE_NAME}" "${PACKAGE_NAME}-openrc"
test -x /usr/bin/nifi
test -x /usr/lib/nifi/bin/nifi.sh
test -d /etc/nifi
test -L /usr/lib/nifi/conf
test "$(readlink /usr/lib/nifi/conf)" = /etc/nifi
test -d /var/lib/nifi
test -d /var/log/nifi
test -f /etc/init.d/nifi
test -f /etc/conf.d/nifi
test -d /usr/lib/nifi/docs
test "$(stat -c '%U:%G %a' /var/lib/nifi)" = "nifi:nifi 750"
rc-update add nifi default
test -L /etc/runlevels/default/nifi
SCRIPT
@@ -0,0 +1,3 @@
provider="github"
repo="apache/nifi"
version_prefix="rel/nifi-"
@@ -0,0 +1,29 @@
# Maintainer: Joachim Schlöffel <joachim.schloeffel@financial-service-plus.de>
pkgname=rclone-openrc
pkgver=0.1.0
pkgrel=0
pkgdesc="Generic, instance-capable OpenRC service for rclone"
url="https://rclone.org/"
arch="noarch"
license="MIT"
depends="openrc rclone"
install="$pkgname.pre-install"
pkgusers="rclone"
pkggroups="rclone"
options="!check"
source="
rclone.confd
rclone.initd
"
package() {
install -d -m 0750 -o root -g rclone "$pkgdir"/etc/rclone
install -d -m 0750 -o rclone -g rclone "$pkgdir"/var/lib/rclone/cache
install -Dm644 "$srcdir"/rclone.confd "$pkgdir"/etc/conf.d/rclone
install -Dm755 "$srcdir"/rclone.initd "$pkgdir"/etc/init.d/rclone
}
sha512sums="
91a05da2c5740a810faf0226ab5fcb3d92a9db56b42c10decaed91481d3129cfc37f5f726a6dc1b5b1246ad4d1386cbe918e109f152969912ea670dbff35fe70 rclone.confd
e92ce86aa21ce1a94beb8304c806b4c0045d412477d7a232e37b0f28354af3060de054c5ae3d1ea353b92d19137a0cfa00b0891b0e179aa32bc6b2c7ecdfc7ea rclone.initd
"
@@ -0,0 +1,59 @@
# rclone OpenRC Alpine Package
Provides a generic, instance-capable OpenRC service for Alpine's `rclone`
package. It does not repackage the rclone binary.
## Install
```sh
apk add rclone-openrc
```
The package creates the unprivileged `rclone` account, `/etc/rclone` for
configuration and credentials, and `/var/lib/rclone/cache` for rclone state.
It deliberately does not create remotes, credentials, authorized-key files, or
SSH host keys; provision those as machine-specific secrets.
## Create an Instance
Copy the template and symlink the generic service under an instance name:
```sh
cp /etc/conf.d/rclone /etc/conf.d/rclone.sftp
ln -s rclone /etc/init.d/rclone.sftp
```
For an SFTP server, configure `/etc/conf.d/rclone.sftp`:
```sh
RCLONE_COMMAND="serve sftp"
RCLONE_REMOTE="/srv/storage"
RCLONE_ARGS="
--addr :2022
--authorized-keys /etc/rclone/authorized_keys
--key /etc/rclone/ssh_host_ed25519_key
--log-level INFO
"
```
Then enable and start it:
```sh
rc-update add rclone.sftp default
rc-service rclone.sftp start
```
Other instances, such as `rclone.webdav` or `rclone.rcd`, use their own
`/etc/conf.d/rclone.<name>` file with the same generic init script. The service
runs rclone in the foreground under `supervise-daemon`, which restarts it after
an unexpected exit. Set `RCLONE_RESPAWN_MAX` to a positive value to limit
restart attempts.
## Package Commands
```sh
ALPINE_PACKAGE=rclone-openrc mise run apk:checksum
ALPINE_PACKAGE=rclone-openrc mise run apk:build
ALPINE_PACKAGE=rclone-openrc SKIP_BUILD=1 mise run apk:test-install
ALPINE_PACKAGE=rclone-openrc mise run apk:runtime-test
```
@@ -0,0 +1,7 @@
#!/bin/sh
addgroup -S rclone 2>/dev/null
adduser -S -D -H -h /var/lib/rclone -s /sbin/nologin \
-G rclone -g rclone rclone 2>/dev/null
exit 0
@@ -0,0 +1,23 @@
# Defaults for rclone OpenRC instances.
#
# To create an instance, copy this file to /etc/conf.d/rclone.<name> and create
# /etc/init.d/rclone.<name> as a symlink to /etc/init.d/rclone. For example:
#
# cp /etc/conf.d/rclone /etc/conf.d/rclone.sftp
# ln -s rclone /etc/init.d/rclone.sftp
#
# Each instance must set RCLONE_COMMAND. RCLONE_REMOTE is optional because
# commands such as "rcd" do not use a remote.
RCLONE_COMMAND=""
RCLONE_REMOTE=""
RCLONE_ARGS=""
RCLONE_CONFIG="/etc/rclone/rclone.conf"
RCLONE_CACHE_DIR="/var/lib/rclone/cache"
RCLONE_USER="rclone"
RCLONE_GROUP="rclone"
# Restart a long-running rclone command after an unexpected exit. Set
# RCLONE_RESPAWN_MAX to a positive number to limit restart attempts.
RCLONE_RESPAWN_DELAY="5"
RCLONE_RESPAWN_MAX="0"
@@ -0,0 +1,31 @@
#!/sbin/openrc-run
instance_name="${RC_SVCNAME#rclone.}"
description="rclone ${instance_name} service"
supervisor="supervise-daemon"
command="/usr/bin/rclone"
command_user="${RCLONE_USER:-rclone}:${RCLONE_GROUP:-rclone}"
pidfile="/run/rclone/${RC_SVCNAME}.pid"
respawn_delay="${RCLONE_RESPAWN_DELAY:-5}"
respawn_max="${RCLONE_RESPAWN_MAX:-0}"
supervise_daemon_args="--chdir /var/lib/rclone --pidfile ${pidfile}"
command_args="${RCLONE_COMMAND:-} ${RCLONE_REMOTE:-} --config ${RCLONE_CONFIG:-/etc/rclone/rclone.conf} --cache-dir ${RCLONE_CACHE_DIR:-/var/lib/rclone/cache} ${RCLONE_ARGS:-}"
depend() {
need net
use dns logger
}
start_pre() {
local service_owner="${RCLONE_USER:-rclone}:${RCLONE_GROUP:-rclone}"
if [ -z "${RCLONE_COMMAND:-}" ]; then
eerror "RCLONE_COMMAND is required; configure /etc/conf.d/${RC_SVCNAME}"
return 1
fi
checkpath -d -m 0750 -o "$service_owner" \
/run/rclone \
"${RCLONE_CACHE_DIR:-/var/lib/rclone/cache}"
}
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
apk add rclone-openrc
test -x /usr/bin/rclone
test -f /etc/conf.d/rclone
test -f /etc/init.d/rclone
test "$(stat -c '%U:%G %a' /etc/rclone)" = "root:rclone 750"
test "$(stat -c '%U:%G %a' /var/lib/rclone/cache)" = "rclone:rclone 750"
cp /etc/conf.d/rclone /etc/conf.d/rclone.rcd
ln -s rclone /etc/init.d/rclone.rcd
sed -i 's|^RCLONE_COMMAND=""|RCLONE_COMMAND="rcd"|' /etc/conf.d/rclone.rcd
sed -i 's|^RCLONE_ARGS=""|RCLONE_ARGS="--rc-addr 127.0.0.1:5572 --rc-no-auth"|' /etc/conf.d/rclone.rcd
rc-update add rclone.rcd default || true
rc-service rclone.rcd start
rc-service rclone.rcd status
rc-service rclone.rcd stop
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
# shellcheck source=scripts/apk/test-install-lib.sh
. "${repo_root}/scripts/apk/test-install-lib.sh"
apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-rclone-openrc}" "${PACKAGE_VERSION:-}" <<'SCRIPT'
set -e
if [ -n "${ALPINE_REPOSITORY_URL}" ]; then
if [ -n "${ALPINE_REPOSITORY_KEY_URL}" ]; then
apk add --no-cache curl >/dev/null
cd /etc/apk/keys
curl -fsSLOJ "${ALPINE_REPOSITORY_KEY_URL}"
fi
printf "%s\n" "${ALPINE_REPOSITORY_URL}" >> /etc/apk/repositories
else
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories
fi
apk update
apk add "${PACKAGE_NAME}"
test -x /usr/bin/rclone
test -f /etc/conf.d/rclone
test -f /etc/init.d/rclone
test -d /etc/rclone
test "$(stat -c '%U:%G %a' /etc/rclone)" = "root:rclone 750"
test "$(stat -c '%U:%G %a' /var/lib/rclone/cache)" = "rclone:rclone 750"
cp /etc/conf.d/rclone /etc/conf.d/rclone.sftp
ln -s rclone /etc/init.d/rclone.sftp
rc-update add rclone.sftp default
test -L /etc/runlevels/default/rclone.sftp
SCRIPT
+69 -35
View File
@@ -1,12 +1,13 @@
# Maintainer: Joachim Schlöffel <me@joachim-schloeffel.com>
# Maintainer: Joachim Schlöffel <joachim.schloeffel@financial-service-plus.de>
pkgname=seaweedfs
pkgver=4.31
pkgver=4.48
pkgrel=3
pkgdesc="Distributed storage system for object storage, file systems, and Iceberg tables"
url="https://github.com/seaweedfs/seaweedfs"
arch="x86_64 aarch64"
license="Apache-2.0"
depends="ca-certificates /bin/sh"
makedepends="build-base cargo go protobuf-dev rust"
provides="!$pkgname-openrc cmd:weed=$pkgver-r$pkgrel"
install="$pkgname.pre-install"
subpackages="
@@ -14,66 +15,78 @@ subpackages="
$pkgname-bash-completion:_bashcomp:noarch
$pkgname-doc
$pkgname-filer-openrc:_openrc_filer:noarch
$pkgname-logrotate:_logrotate:noarch
$pkgname-master-openrc:_openrc_master:noarch
$pkgname-s3-openrc:_openrc_s3:noarch
$pkgname-sftp-openrc:_openrc_sftp:noarch
$pkgname-volume-openrc:_openrc_volume:noarch
$pkgname-webdav-openrc:_openrc_webdav:noarch
$pkgname-worker-openrc:_openrc_worker:noarch
$pkgname-worker-lance:_worker_lance
$pkgname-worker-lance-openrc:_openrc_worker_lance:noarch
"
options="!check !strip !tracedeps"
case "$CARCH" in
x86_64)
_archive="$pkgname-$pkgver-linux-amd64.tar.gz"
;;
aarch64)
_archive="$pkgname-$pkgver-linux-arm64.tar.gz"
;;
esac
options="!strip !tracedeps net"
source="
$pkgname-$pkgver-linux-amd64.tar.gz::https://github.com/seaweedfs/seaweedfs/releases/download/$pkgver/linux_amd64.tar.gz
$pkgname-$pkgver-linux-arm64.tar.gz::https://github.com/seaweedfs/seaweedfs/releases/download/$pkgver/linux_arm64.tar.gz
$pkgname-$pkgver-src.tar.gz::https://github.com/seaweedfs/seaweedfs/archive/refs/tags/$pkgver.tar.gz
admin.toml
credential.toml
example-admin.toml
example-credential.toml
example-filer.toml
example-master.toml
example-volume.toml
example-notification.toml
example-replication.toml
example-security.toml
example-shell.toml
filer.toml
master.toml
notification.toml
replication.toml
security.toml
shell.toml
seaweedfs.admin.confd
seaweedfs.filer.confd
seaweedfs.initd
seaweedfs.logrotate
seaweedfs.master.confd
seaweedfs.s3.confd
seaweedfs.sftp.confd
seaweedfs.volume.confd
seaweedfs.webdav.confd
seaweedfs.worker.confd
seaweedfs.worker-lance.confd
weed.bash-completion
"
builddir="$srcdir"
_worker_builddir="$srcdir/$pkgname-$pkgver/seaweed-worker"
prepare() {
default_prepare
tar -xzf "$srcdir/$_archive" -C "$builddir"
}
build() {
go build -mod=readonly -buildvcs=false -trimpath \
-tags "sqlite rclone gocdk" -o "$builddir/weed-bin" ./weed
cd "$_worker_builddir"
cargo build --locked --release -p weed-lance-worker
}
check() {
"$builddir/weed-bin" version
"$builddir/weed-bin" scaffold -config master >/dev/null
"${CARGO_TARGET_DIR:-$_worker_builddir/target}/release/weed-worker" --help >/dev/null
}
package() {
install -Dm755 "$srcdir"/weed "$pkgdir"/usr/bin/weed
install -Dm755 "$builddir"/weed-bin "$pkgdir"/usr/bin/weed
install -Dm755 "${CARGO_TARGET_DIR:-$_worker_builddir/target}/release/weed-worker" \
"$pkgdir"/usr/bin/weed-worker
local _config
for _config in credential filer master notification replication security shell; do
for _config in admin credential filer master security; do
install -Dm644 "$srcdir"/$_config.toml \
"$pkgdir"/etc/seaweedfs/$_config.toml
done
for _config in admin credential filer master volume notification replication security shell; do
install -Dm644 "$srcdir"/example-$_config.toml \
"$pkgdir"/usr/share/doc/$pkgname/examples/$_config.toml
done
@@ -99,6 +112,26 @@ _openrc_volume() { _openrc_service volume; }
_openrc_webdav() { _openrc_service webdav; }
_openrc_worker() { _openrc_service worker; }
_logrotate() {
pkgdesc="Log rotation configuration for $pkgname"
depends="$pkgname=$pkgver-r$pkgrel logrotate"
install -Dm644 "$srcdir"/seaweedfs.logrotate \
"$subpkgdir"/etc/logrotate.d/$pkgname
}
_worker_lance() {
pkgdesc="SeaweedFS Lance table maintenance worker"
depends="$pkgname=$pkgver-r$pkgrel libgcc"
amove usr/bin/weed-worker
}
_openrc_worker_lance() {
_openrc_service worker-lance
depends="$pkgname-worker-lance=$pkgver-r$pkgrel $depends"
}
_bashcomp() {
pkgdesc="Bash completions for $pkgname"
depends=""
@@ -109,30 +142,31 @@ _bashcomp() {
}
sha512sums="
60c758d6d565d0cbc533e4e5677186a4700d48be12ebbd2bd1c6b4bcf38f687d0ab1f66e0953c8a27c663549cdbae73e5fd7eda74bb422c20e10e0d0850b5ead seaweedfs-4.31-linux-amd64.tar.gz
93c7539fe15a0aa6192d26ac2360003961f0643e302d910179d02341b10a7243df776294fb1b0134ec2a2a9596b1abc3ce9ab701f9bc3d78f2b965ea464a4b18 seaweedfs-4.31-linux-arm64.tar.gz
b6ce09d6d83dd70e2797a185171eea3587436fb024a99b4998f714b713244d6f768ef59f67c9b7251650d4f19d414eea231eab92099763d85cd92e41cb2bdc3f credential.toml
91a34fec9bb78832f421b54dd823adb1c1690b746083d947c5f72e4ad7670362512bbb920432f42342482774fd8be2b396645ff3bc764b10f328432601733fe3 seaweedfs-4.48-src.tar.gz
58be6587b082f45b4dd22ad8ebb1b8bf84cea2a7c0cb6b4ad4a749ac0bfdf92d10d22281a432f9e5a87afa0b940cd0172671a292fbe17803e56425cd940d47f9 admin.toml
7f77ad8787629e3defbc89e39e5432482aa50d87ddd723de927a9c6c77b14b1673cbf5b3fc3c18dd7d0eba26fbcd4220d2da6939ed097d0294b24ccd5c002635 credential.toml
507b389f6373b5f4d8ca69f27bc806b39bda8edf7f58e4f32720958e7782ee171dd0461bdecb285e5a8bf2cf4ea3d6cbe8b62ae6ac43c2a40d0eb053d50a22f8 example-admin.toml
7105de7053654b8c0502521ce58585915fc831c3152801e1db02b1c5214dc3c3ed31f4fc18000665d8338c7a10ffbf0d248368bef2ef3a6d37d46cd856398366 example-credential.toml
6213e9cff227d66a7a04237d15e2f77904f1bcdf5709fd985c1e12fe4aca0d0327db6997d567303eff47dabec3650db2a6d874b03adda41b239e04ee0c3557ee example-filer.toml
e5753bd0bcc60dc84428c40ba556c08acae61dec083a5b76640125f637532e7c5759a72cdfd95114222a7a0901a916ec3c4d12f306853cfca0fe9a0b1857893e example-master.toml
c6ec4fc7709c42dc6771b5039203c44cbd693742abcd7720936c00b1bd5f99bb2999bb1545680ae4418efedd65d71c234f4602f52ce9d58b1ff7ec53eafb1a1a example-filer.toml
59965fd2649a956677c6d4104ff07ff010d6edd1d3733eaa5c5bc01eabe54429c413e35d52ed4a4c0129bfa798e434828b32a5f0ef19dbbe4eab0199faa2738c example-master.toml
aea1b3114311304230cb30143825329ef7353a302d094c131ca4e049b847305e2143b76078e6574c6d7d4039c03a2e2d5a4925de80cd7cb2be75b2b522ce47f7 example-volume.toml
2c200c28172a5d0b1c80ab28e849287e7af8d103355638fd3183b8614d3e2b1b3482132522663f7c6d844e10e13b8c6e23fb5fba0dec2cc83de45c2f17b33477 example-notification.toml
4b507540d57799e42ec0ee84073c6fa32c577a2f4a98bf66ee7302355080c63c65d70709115185debdee3c957e9294e79a8e461347d7148af7fdd368dc548af6 example-replication.toml
a0f307bc73b1aa03653c42c22a1fc704640cbd86957a417f947fe33356e03734c33782777cb1d6cb17360fc6b3930ffbe1386f89123e9dc3c21468210418aae2 example-security.toml
328cfe43d0c2ebf5092a1178af45c37b07593085135c31649754f0df9fd4c043847c13b56c3c7c45194541db8082309c4845c825d7011e4c3e503b1e6576528d example-replication.toml
b7caad9dff0bb812d4046b8e0285ac4e88a7af3a742a168579df08762da735a025725f78286e17bdd4b19a966a3d7ab88e0e52efbb5cf1c69d7a4ff071390e0f example-security.toml
70069f97edf261a2cd0669dd60adad80533609a25d7429254e0c3322d7e80337f5ff69a5581bc39e6a15442098d14d610ce5f0cb14f02c461c8d3dd440b22c56 example-shell.toml
be5771a5e1bf626c53f9dffbfa2a400d9b8f9626d55a7b61dcd853753561989427ba872a2638a5e6343f44dea6790678483bd29101d6495dbbfcd3029947b9a7 filer.toml
2cd6c73a5e23e0395b6f099dcc3acf9280cbb3e13f54408571e91741c4e6b0dad85f6d4e5a92f23ad541bad57ce295c28bb8450fe11da35acbd4da25848f61e5 master.toml
0a1b3d0fd1671744f96e7642fb9aee9b80debd0d9a82f586beb36fe32f9ad440332acd2a8b0ee0b210b912cb281d88ca56fd15e3a2ece61be9dcf96afc00a6f8 notification.toml
5a607ce6cdd11ffbe528b9a85e0012b48accefa6ccfeda9d6aa70d92ccf7f219e75c93cd2f1c36f3eb16204b3652a45dcd52ffcb64bceef91d081702b19cef3c replication.toml
d21981923b5964cf8365185a4f7c28a14e33ba6f60ad63e797e315544a6c22efdaa72814292824c07ef14554738769e0fd4c670fe797cf77b0226b2595a8b43b security.toml
7a91ce9da79b92e5ef42d4915f56a010bceaaa6c96dcef1f7b1821ee208d381aaa88b9cf495248276132e66d3215927f589b7fabc4eae2c2cb195645f904fac7 shell.toml
130b9932f99d0a3ec3c30c74eaf1dc441c1a9252da30e2c5365084f2a0679f58531e6180689c24b71f92cf9a7966b02ea25ee31d356e7118cbb82743d0bfcbd9 filer.toml
088c3aebc142054af1b54a92a2c5bd30d53be61bdf382f7cae2efef2d917d7b57022d9b494a60f32c7bf56689d4ce2f971e19c98da1d87e27021a3e948035605 master.toml
79a078133c259473e601488cd1d8032b74c5fa32da6f34a4ed46efa9736bf5369365a77d775e3d78512b1060cd87012eb40226829eecb30544e1542d165af7d6 security.toml
82e2793bf483ffb5b0c8fbe38e6c9df75afe01f824f8414cafd91e4bed5c79c13dae1ca659070401d4968d16ed4b26455b0c6208f777705527bceb2e5f286988 seaweedfs.admin.confd
5ad952c37c62a770327bd70f7349fa677406606f0b9bf03fdc8f6c6804701f1e77710ab20d6153f9e0cfb549ec161d68a3316abab9c59837bbe3f91ee99e5ce0 seaweedfs.filer.confd
6c7ebdaf8f941868051a025fda36278bdf5e5438a2d478ca1cbe35064f933e7b07bf6d56bdd2268894f01c4e232e48f69099f793baeb2d6011063ac56a132fe4 seaweedfs.initd
19cbd65d701b0995e088f265d88f481f14e214ecbd8a783f7e7b17e811e421a28425f96d073757cc07fbb17e8eb084d14d41f46baee82ee13e043ce0c0c5bde9 seaweedfs.initd
816e763164c2cec66509c213ed56cb633f13d1daf48a511d1a9cfdf692a6ad945cf599cb0e706202b8fd522022ce512eae6170422e478abdf95334b0088ac4cc seaweedfs.logrotate
57ba77519bb266f0117eaadae3af5ae6bc99bb653668ff526202f327df1c8d93973c0e19dae0c53a19e06389868043c04e53f16f01c851b77fe1387e92cc993b seaweedfs.master.confd
22a3ea6c83266a979ea7c848fc74b40fc0f2ade960b273fa11e63d4a72a1328bd688c9918be3e9234cfb19f889fd9c931388bb5c2863cea3500e534b8bd90282 seaweedfs.s3.confd
3e9c41bc61cdd9a4c53ece64d847eca26ab7d0ce0cc98e72462c3dbb225a40de10a02201362801015a9c629d77d5c0d54c7228e9d20111fb6f478b2267d2db98 seaweedfs.sftp.confd
262cc5132a70a43f9f154d24da16fe2f34f736c0bfdafd56cd341b7f34b48b82aa3a38a93d64206360c391e1167e2b665a3ade5c7eddfe4b322253521629f4e0 seaweedfs.volume.confd
84a9caa8f5203a31f2f96ef812dca8e4f7597f8f06ed3f55db38daff167448b0332564a421dcb356405d761c7a9e815656208d431e84b8106951554ab7ef2142 seaweedfs.webdav.confd
b586dfbdbcf17591366a7a62c4da6f2b13e1bd5dfb5b066beea114d01057eeb3d81172814655d812c48e02336277b3d70fa9f9550923cfe616e9dd8162661f51 seaweedfs.worker.confd
0a06a1ea007a6e4e0110a6208830f080685b81f6e1aae8453a75941ef54e4506155e4c7be125b2eed0b971050d0743118cf1454b6e9d01cf8eec02005125b6b2 seaweedfs.worker-lance.confd
2815330810545d17cffd993d93502c934c24af5aeff8f7096bcf0f020f895f1da50b74c356c028b67de552cbd8e4ccfa176636da2642feae99542035e4272171 weed.bash-completion
"
+31 -6
View File
@@ -1,17 +1,24 @@
# SeaweedFS Alpine Package
Repackages official SeaweedFS 4.31 Linux release tarballs for `x86_64` and
`aarch64`.
Builds SeaweedFS 4.48 from its upstream source release for `x86_64` and
`aarch64`. The package intentionally builds the upstream baseline feature set,
with the `sqlite`, `rclone`, and `gocdk` optional Go build tags enabled. Go and
Cargo dependencies are resolved from the versions pinned in the upstream
`go.sum` and `Cargo.lock` files.
## Package Commands
Refresh generated sources:
When updating SeaweedFS, generate the config scaffolds and refresh checksums:
```sh
ALPINE_PACKAGE=seaweedfs mise run apk:update-generated
ALPINE_PACKAGE=seaweedfs mise run apk:checksum
```
The refresh command generates every SeaweedFS scaffold configuration:
`admin`, `credential`, `filer`, `master`, `volume`, `notification`,
`replication`, `security`, and `shell`.
Build:
```sh
@@ -54,6 +61,7 @@ seaweedfs-webdav-openrc -> /etc/init.d/seaweedfs.webdav
seaweedfs-sftp-openrc -> /etc/init.d/seaweedfs.sftp
seaweedfs-admin-openrc -> /etc/init.d/seaweedfs.admin
seaweedfs-worker-openrc -> /etc/init.d/seaweedfs.worker
seaweedfs-worker-lance-openrc -> /etc/init.d/seaweedfs.worker-lance
```
Replace Alpine's old generic OpenRC package before installing a role split:
@@ -74,13 +82,16 @@ Runtime paths:
/etc/init.d/seaweedfs.*
```
Edit `/etc/conf.d/seaweedfs.<role>` for flags and `/etc/seaweedfs/*.toml` for
SeaweedFS config. Upstream examples:
Edit `/etc/conf.d/seaweedfs.<role>` for flags. The package supplies a small set
of safe defaults in `/etc/seaweedfs/`; the complete upstream-generated scaffold
configs are available at:
```text
/usr/share/doc/seaweedfs/examples/
```
Copy and customize a scaffold file only when enabling its related feature.
Enable services:
```sh
@@ -92,6 +103,11 @@ rc-service seaweedfs.volume start
rc-update add seaweedfs.filer default
rc-service seaweedfs.filer start
# Optional: Lance table maintenance (requires a Lance namespace endpoint)
apk add seaweedfs-worker-lance-openrc
rc-update add seaweedfs.worker-lance default
rc-service seaweedfs.worker-lance start
```
Check status:
@@ -115,6 +131,15 @@ Bash completion:
apk add bash-completion seaweedfs-bash-completion
```
Log rotation for the default OpenRC service logs:
```sh
apk add seaweedfs-logrotate
```
This rotates `/var/log/seaweedfs/seaweedfs.*.log` daily and retains 14
compressed archives.
## Upgrade Or Pin
Upgrade:
@@ -127,5 +152,5 @@ rc-service seaweedfs.master restart
Pin:
```sh
apk add seaweedfs=4.31-r3
apk add seaweedfs=4.47-r3
```
@@ -0,0 +1,4 @@
# Disable automatic maintenance until the cluster's storage and replication
# policy has been reviewed. This setting is persisted in the admin data directory.
[maintenance]
enabled = false
@@ -1,19 +1,3 @@
# Use the existing filer store for credentials by default.
[credential.filer_etc]
enabled = true
[credential.postgres]
enabled = false
hostname = "localhost"
port = 5432
username = "seaweedfs"
password = ""
database = "seaweedfs"
schema = "public"
sslmode = "disable"
table_prefix = "sw_"
connection_max_idle = 10
connection_max_open = 100
connection_max_lifetime_seconds = 3600
[credential.memory]
enabled = false
@@ -0,0 +1,71 @@
# Put this file in one of the locations, with descending priority
# ./admin.toml
# $HOME/.seaweedfs/admin.toml
# /etc/seaweedfs/admin.toml
# this file is read by "weed admin"
# Maintenance task settings declared here are applied every time the admin
# server starts, overriding values saved from the admin UI under
# <dataDir>/conf. Commented-out keys keep their saved or default values.
# Requires -dataDir.
# Each value can also be set via environment variable, e.g.
# export WEED_MAINTENANCE_VACUUM_GARBAGE_THRESHOLD=0.3
[s3]
# The address clients reach the S3 gateway at, including the scheme.
# The file browser uses it to offer copyable object URLs; without it,
# the copy action is hidden.
# public_endpoint = "https://s3.example.com"
[maintenance]
# toggle the entire maintenance system (task detection and execution)
# enabled = true
[maintenance.vacuum]
# enabled = true
# vacuum volumes with more deleted content than this ratio
# garbage_threshold = 0.3
# how often to scan for volumes needing vacuum
# scan_interval_seconds = 7200
# max_concurrent = 2
# only vacuum volumes older than this (rounded up to whole hours)
# min_volume_age_seconds = 86400
# max retry attempts for a failed vacuum job (admin runtime default)
# retry_limit = 1
# seconds to wait between retry attempts
# retry_backoff_seconds = 10
[maintenance.balance]
# enabled = true
# trigger balancing when volume distribution exceeds this ratio
# imbalance_threshold = 0.2
# scan_interval_seconds = 1800
# max_concurrent = 1
# minimum number of volume servers before balancing
# min_server_count = 2
# max retry attempts for a failed balance job
# retry_limit = 1
# seconds to wait between retry attempts
# retry_backoff_seconds = 15
[maintenance.erasure_coding]
# enabled = true
# only erasure code volumes this full
# fullness_ratio = 0.95
# only erasure code volumes not modified for this long
# quiet_for_seconds = 3600
# scan_interval_seconds = 3600
# max_concurrent = 1
# min_size_mb = 30
# only process volumes from these collections, comma separated, "*" and "?" wildcards
# and regex patterns allowed ("" = all collections)
# collection_filter = ""
# disk tags preferred for shard placement
# preferred_tags = ["fast", "ssd"]
# EC shard placement constraint, e.g. "020"; empty uses the master default replication
# replica_placement = ""
# max retry attempts for a failed erasure coding job
# retry_limit = 1
# seconds to wait between retry attempts
# retry_backoff_seconds = 30
@@ -68,7 +68,7 @@ port = 3306
username = "root"
password = ""
database = "" # create or use an existing database
connection_max_idle = 10
connection_max_idle = 50
connection_max_open = 50
connection_max_lifetime_seconds = 300
interpolateParams = false
@@ -97,7 +97,7 @@ port = 3306
username = "root"
password = ""
database = "" # create or use an existing database
connection_max_idle = 10
connection_max_idle = 50
connection_max_open = 50
connection_max_lifetime_seconds = 300
interpolateParams = false
@@ -106,13 +106,9 @@ enableUpsert = true
upsertQuery = """INSERT INTO `%s` (`dirhash`,`name`,`directory`,`meta`) VALUES (?,?,?,?) AS `new` ON DUPLICATE KEY UPDATE `meta` = `new`.`meta`"""
[postgres] # or cockroachdb, YugabyteDB
# CREATE TABLE IF NOT EXISTS filemeta (
# dirhash BIGINT,
# name VARCHAR(65535),
# directory VARCHAR(65535),
# meta bytea,
# PRIMARY KEY (dirhash, name)
# );
# createTable = true # auto-create filemeta with the default schema
# createTable = false # skip table creation (default; for restricted DB roles)
# createTable = """CREATE TABLE IF NOT EXISTS "%s" (...)""" # custom template
enabled = false
hostname = "localhost"
port = 5432
@@ -127,7 +123,7 @@ sslmode = "disable"
# sslkey = "/path/to/client.key" # client private key file
# sslrootcert = "/path/to/ca.crt" # CA certificate file
# sslcrl = "/path/to/client.crl" # Certificate Revocation List (CRL) (optional)
connection_max_idle = 10
connection_max_idle = 50
connection_max_open = 50
connection_max_lifetime_seconds = 300
# Set to true when using PgBouncer connection pooler
@@ -166,7 +162,7 @@ sslmode = "disable"
# sslkey = "/path/to/client.key" # client private key file
# sslrootcert = "/path/to/ca.crt" # CA certificate file
# sslcrl = "/path/to/client.crl" # Certificate Revocation List (CRL) (optional)
connection_max_idle = 10
connection_max_idle = 50
connection_max_open = 50
connection_max_lifetime_seconds = 300
# Set to true when using PgBouncer connection pooler
@@ -230,6 +226,23 @@ client_cert_path = ""
client_key_path = ""
# This changes the data layout. Only add new directories. Removing/Updating will cause data loss.
superLargeDirectories = []
# Connection tuning, accepted by every redis filer store section. Each key keeps the go-redis
# default when left at 0, and a timeout cannot be turned off - a filer that never times out a read
# is what stalls a failover. Shorter read timeouts make the filer notice a dead redis sooner, which
# matters most for the sentinel store: every pooled connection to the old master has to time out
# before a failover is absorbed.
# max_retries = 0 # 0 is three retries, -1 disables retrying
# min_retry_backoff_millisecond = 0 # default 8
# max_retry_backoff_millisecond = 0 # default 512
# dial_timeout_millisecond = 0 # default 5000
# read_timeout_millisecond = 0 # default 3000
# write_timeout_millisecond = 0 # default 3000, follows read_timeout_millisecond
# pool_size = 0 # default 10 per CPU
# pool_timeout_millisecond = 0 # default read_timeout_millisecond + 1000
# min_idle_conns = 0
# max_idle_conns = 0
# conn_max_idle_time_seconds = 0 # default 1800
# conn_max_lifetime_seconds = 0 # default unlimited
[redis2_sentinel]
enabled = false
@@ -237,6 +250,9 @@ addresses = ["172.22.12.7:26379","172.22.12.8:26379","172.22.12.9:26379"]
masterName = "master"
username = ""
password = ""
# credentials used to authenticate against the sentinel nodes themselves (if they require auth)
sentinel_username = ""
sentinel_password = ""
database = 0
# prefix for filer redis keys
keyPrefix = ""
@@ -244,6 +260,7 @@ enable_tls = false
ca_cert_path = ""
client_cert_path = ""
client_key_path = ""
# see [redis2] for the connection tuning keys
[redis_cluster2]
enabled = false
@@ -264,7 +281,7 @@ ca_cert_path = ""
client_cert_path = ""
client_key_path = ""
# allows reads from slave servers or the master, but all writes still go to the master
readOnly = false
useReadOnly = false
# automatically use the closest Redis server for reads
routeByLatency = false
# This changes the data layout. Only add new directories. Removing/Updating will cause data loss.
@@ -366,6 +383,21 @@ healthcheck_enabled = false
# increase the value is recommend, be sure the value in Elastic is greater or equal here
index.max_result_window = 10000
# for Elasticsearch 8.x clusters
[elastic8]
enabled = false
servers = [
"http://localhost1:9200",
"http://localhost2:9200",
"http://localhost3:9200",
]
username = ""
password = ""
sniff_enabled = false
healthcheck_enabled = false
# increase the value is recommend, be sure the value in Elastic is greater or equal here
index.max_result_window = 10000
[arangodb] # in development dont use it
enabled = false
@@ -52,6 +52,7 @@ copy_2 = 6 # create 2 x 6 = 12 actual volumes
copy_3 = 3 # create 3 x 3 = 9 actual volumes
copy_other = 1 # create n x 1 = n actual volumes
threshold = 0.9 # create threshold
reservation_timeout = "5m"# capacity reservation timeout before unreleased reservations expire
disable = false # disables volume growth if true
# configuration flags for replication
@@ -59,7 +59,17 @@ is_incremental = false
# experimental, let me know if it works
enabled = false
account_name = ""
# leave account_key empty to authenticate with Entra ID instead of a shared key,
# picking up a workload identity or managed identity from the environment. The
# identity needs a data-plane role such as Storage Blob Data Contributor.
account_key = ""
# optional user-assigned identity, when account_key is empty. Workload identity
# takes its tenant and token from AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE,
# which the Azure workload identity webhook projects into the pod.
client_id = ""
# blob service url, for accounts outside the public cloud. Empty resolves to
# https://<account_name>.blob.core.windows.net/
endpoint = ""
container = "mycontainer" # an existing container
directory = "/" # destination directory
is_incremental = false
@@ -4,6 +4,15 @@
# /etc/seaweedfs/security.toml
# this file is read by master, volume server, filer, and worker
# Any value below can also be supplied as an environment variable instead of
# living in this file: prefix the key with WEED_, upper-case it, and replace
# "." with "_". This is the recommended way to inject the secrets in here from
# a Kubernetes Secret (env valueFrom.secretKeyRef) rather than a ConfigMap.
# The JWT signing keys map to:
# WEED_JWT_SIGNING_KEY, WEED_JWT_SIGNING_READ_KEY (master <-> volume)
# WEED_JWT_FILER_SIGNING_KEY, WEED_JWT_FILER_SIGNING_READ_KEY (s3/clients <-> filer)
# A set env var wins over the file, so the file can stay empty (or absent).
# comma separated origins allowed to make requests to the filer and s3 gateway.
# enter in this format: https://domain.com, or http://localhost:port
[cors.allowed_origins]
@@ -68,6 +77,12 @@ expires_after_seconds = 10 # seconds
# All gRPC TLS authentications are mutual (mTLS)
# The values for ca, cert, and key are paths to the certificate/key files
# The host name is not checked, so the certificate files can be shared
# Each [grpc.<component>] section also accepts optional client_cert/client_key,
# presented when that component dials other servers. Set them when your CA
# issues separate serverAuth-only and clientAuth-only certificates; when unset,
# the component reuses cert/key for both directions.
# If client and server certificates come from different issuing CAs, put both
# CA certificates in the ca PEM file.
[grpc]
ca = ""
# Set wildcard domain for enable TLS authentication by common names
@@ -78,6 +93,8 @@ allowed_wildcard_domain = "" # .mycompany.com
[grpc.volume]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
# Master server gRPC options (server-side)
@@ -85,6 +102,8 @@ allowed_commonNames = "" # comma-separated SSL certificate common names
[grpc.master]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
# Filer server gRPC options (server-side)
@@ -92,6 +111,8 @@ allowed_commonNames = "" # comma-separated SSL certificate common names
[grpc.filer]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
# S3 server gRPC options (server-side)
@@ -99,31 +120,43 @@ allowed_commonNames = "" # comma-separated SSL certificate common names
[grpc.s3]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
[grpc.msg_broker]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
[grpc.msg_agent]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
[grpc.admin]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
[grpc.worker]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
[grpc.mq]
cert = ""
key = ""
client_cert = ""
client_key = ""
allowed_commonNames = "" # comma-separated SSL certificate common names
# gRPC client configuration for outgoing gRPC connections
@@ -199,6 +232,15 @@ kek = ""
# Cannot be used while /etc/s3/sse_kek exists on the filer — delete it first.
key = ""
# Trusted reverse proxies allowed to set X-Forwarded-For / X-Real-Ip for
# aws:SourceIp condition evaluation in S3 bucket and IAM policies. When the
# direct TCP peer is in this list, forwarded headers are honored; otherwise
# the direct peer address is used (matching AWS S3 semantics). Leave empty to
# always use the direct peer, which is the safe default.
# Can also be set via env var: WEED_S3_TRUSTED_PROXIES_WHITE_LIST
[s3.trusted_proxies]
white_list = "" # comma separated; bare IPs or CIDRs, e.g. "10.10.10.0/24"
# white list. It's checking request ip address.
[guard]
white_list = ""
@@ -0,0 +1,30 @@
# Put this file to one of the location, with descending priority
# ./volume.toml
# $HOME/.seaweedfs/volume.toml
# /etc/seaweedfs/volume.toml
# this file is read by volume servers
[volume.disk.io]
# Disk IO probing is disabled by default. When enabled, a volume server can
# stop advertising a disk after sustained IO errors or latency degradation.
probe = false
timeout = "2s"
interval = "60s"
window = "1m"
min.samples = 10
max.stat.failures = 5
recovery.coef = 0.5
[volume.disk.io.slow]
percent = 20
[volume.disk.io.error]
percent = 10
# slow threshold per disk type, matched against each -dir's -disk tag.
# a disk whose type is not listed here uses the hdd threshold.
[volume.disk.io.slow.latency]
hdd = "500ms"
ssd = "100ms"
nvme = "50ms"
+1 -43
View File
@@ -1,46 +1,4 @@
[filer.options]
recursive_delete = false
# Store standalone filer metadata in the package-managed data directory.
[leveldb2]
enabled = true
dir = "/var/lib/seaweedfs/filer/meta"
[sqlite]
enabled = false
dbFile = "/var/lib/seaweedfs/filer/filer.db"
[mysql]
enabled = false
dsn = "root@tcp(localhost:3306)/seaweedfs?collation=utf8mb4_bin"
enable_tls = false
hostname = "localhost"
port = 3306
username = "root"
password = ""
database = ""
connection_max_idle = 10
connection_max_open = 50
connection_max_lifetime_seconds = 300
interpolateParams = false
enableUpsert = true
[postgres]
enabled = false
hostname = "localhost"
port = 5432
username = "postgres"
password = ""
database = "postgres"
schema = ""
sslmode = "disable"
connection_max_idle = 10
connection_max_open = 50
connection_max_lifetime_seconds = 300
pgbouncer_compatible = false
enableUpsert = true
[redis2]
enabled = false
address = "localhost:6379"
password = ""
database = 0
+1 -25
View File
@@ -1,27 +1,3 @@
# Disable scheduled maintenance until it is explicitly configured.
[master.maintenance]
scripts = ""
sleep_minutes = 17
[master.sequencer]
type = "raft"
sequencer_snowflake_id = 0
[storage.backend.s3.default]
enabled = false
aws_access_key_id = ""
aws_secret_access_key = ""
region = "us-east-2"
bucket = ""
endpoint = ""
storage_class = "STANDARD_IA"
[master.volume_growth]
copy_1 = 7
copy_2 = 6
copy_3 = 3
copy_other = 1
threshold = 0.9
disable = false
[master.replication]
treat_replication_as_minimums = false
@@ -1,42 +0,0 @@
[notification.log]
enabled = false
[notification.kafka]
enabled = false
hosts = ["localhost:9092"]
topic = "seaweedfs_filer"
offsetFile = "/var/lib/seaweedfs/filer/last.offset"
offsetSaveIntervalSeconds = 10
sasl_enabled = false
sasl_mechanism = "PLAIN"
sasl_username = ""
sasl_password = ""
tls_enabled = false
tls_ca_cert = ""
tls_client_cert = ""
tls_client_key = ""
tls_insecure_skip_verify = false
[notification.aws_sqs]
enabled = false
aws_access_key_id = ""
aws_secret_access_key = ""
region = "us-east-2"
sqs_queue_name = ""
[notification.google_pub_sub]
enabled = false
google_application_credentials = ""
project_id = ""
topic = ""
[notification.webhook]
enabled = false
endpoint = ""
bearer_token = ""
timeout_seconds = 10
max_retries = 3
backoff_seconds = 3
max_backoff_seconds = 30
workers = 5
buffer_size = 10000
@@ -1,29 +0,0 @@
[source.filer]
enabled = false
grpcAddress = "localhost:18888"
directory = "/buckets"
excludeDirectories = "/buckets/tmp"
[sink.local]
enabled = false
directory = "/var/lib/seaweedfs/backup"
is_incremental = false
[sink.filer]
enabled = false
grpcAddress = "localhost:18888"
directory = "/backup"
replication = ""
collection = ""
ttlSec = 0
is_incremental = false
[sink.s3]
enabled = false
aws_access_key_id = ""
aws_secret_access_key = ""
region = "us-east-2"
bucket = ""
directory = "/"
endpoint = ""
is_incremental = false
@@ -6,20 +6,26 @@ apk add seaweedfs \
bash-completion \
seaweedfs-master-openrc \
seaweedfs-volume-openrc \
seaweedfs-filer-openrc
seaweedfs-filer-openrc \
seaweedfs-worker-lance-openrc
test -x /usr/bin/weed
test -d /etc/seaweedfs
test -f /etc/seaweedfs/master.toml
test -f /etc/seaweedfs/filer.toml
test -f /etc/seaweedfs/admin.toml
test -f /etc/conf.d/seaweedfs.master
test -f /etc/conf.d/seaweedfs.volume
test -f /etc/conf.d/seaweedfs.filer
test -f /etc/init.d/seaweedfs.master
test -f /etc/init.d/seaweedfs.volume
test -f /etc/init.d/seaweedfs.filer
test -f /etc/init.d/seaweedfs.worker-lance
test -x /usr/bin/weed-worker
/usr/bin/weed-worker --help >/dev/null
test -d /usr/share/doc/seaweedfs/examples
test -f /usr/share/doc/seaweedfs/examples/master.toml
test -f /usr/share/doc/seaweedfs/examples/volume.toml
test -f /usr/share/bash-completion/completions/weed
weed version
@@ -35,3 +41,8 @@ rc-service seaweedfs.filer start
rc-service seaweedfs.master status
rc-service seaweedfs.volume status
rc-service seaweedfs.filer status
# SeaweedFS needs more than OpenRC's default stop timeout to finish its
# graceful volume-server shutdown. Keep the restart path covered.
rc-service seaweedfs.volume restart
rc-service seaweedfs.volume status
@@ -2,38 +2,10 @@
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-seaweedfs}"
alpine_version="${ALPINE_VERSION:-3.24}"
arch="${ALPINE_ARCH:-x86_64}"
# shellcheck source=scripts/apk/test-install-lib.sh
. "${repo_root}/scripts/apk/test-install-lib.sh"
case "${arch}" in
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
apk_test_install_run "${repo_root}" "${PACKAGE_NAME:-seaweedfs}" "${PACKAGE_VERSION:-}" <<'SCRIPT'
set -e
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
@@ -43,18 +15,27 @@ docker run --rm --platform "${platform}" \
apk add seaweedfs \
seaweedfs-master-openrc \
seaweedfs-volume-openrc \
seaweedfs-filer-openrc
seaweedfs-filer-openrc \
seaweedfs-logrotate \
seaweedfs-worker-lance-openrc
test -x /usr/bin/weed
test -d /etc/seaweedfs
test -f /etc/seaweedfs/master.toml
test -f /etc/seaweedfs/filer.toml
test -f /etc/seaweedfs/admin.toml
test -f /etc/conf.d/seaweedfs.master
test -f /etc/conf.d/seaweedfs.volume
test -f /etc/conf.d/seaweedfs.filer
test -f /etc/init.d/seaweedfs.master
test -f /etc/init.d/seaweedfs.volume
test -f /etc/init.d/seaweedfs.filer
test -f /etc/init.d/seaweedfs.worker-lance
test -f /etc/logrotate.d/seaweedfs
apk info -e logrotate
logrotate -d /etc/logrotate.conf
test -x /usr/bin/weed-worker
/usr/bin/weed-worker --help >/dev/null
weed version
@@ -69,5 +50,6 @@ docker run --rm --platform "${platform}" \
apk info -e seaweedfs-bash-completion
test -d /usr/share/doc/seaweedfs/examples
test -f /usr/share/doc/seaweedfs/examples/master.toml
test -f /usr/share/doc/seaweedfs/examples/volume.toml
test -f /usr/share/bash-completion/completions/weed
'
SCRIPT
@@ -1,15 +1,38 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_dir="${PACKAGE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
configs=(credential filer master notification replication security shell)
configs=(admin credential filer master volume notification replication security shell)
pkgver="$(
awk -F= '$1 == "pkgver" { print $2; exit }' "${package_dir}/APKBUILD"
)"
tmpdir="$(mktemp -d)"
repo_root="${REPO_ROOT:-$(cd "${package_dir}/../../../.." && pwd)}"
source_archive="${repo_root}/.cache/apk-distfiles/seaweedfs-${pkgver}-src.tar.gz"
cleanup() {
rm -rf "${tmpdir}"
}
trap cleanup EXIT
if [[ ! -f "${source_archive}" ]]; then
source_archive="${tmpdir}/seaweedfs-${pkgver}-src.tar.gz"
curl -fsSL \
-o "${source_archive}" \
"https://github.com/seaweedfs/seaweedfs/archive/refs/tags/${pkgver}.tar.gz"
fi
tar -xzf "${source_archive}" -C "${tmpdir}"
source_dir="${tmpdir}/seaweedfs-${pkgver}"
(
cd "${source_dir}"
go build -mod=readonly -buildvcs=false -trimpath -o "${tmpdir}/weed" ./weed
)
for config in "${configs[@]}"; do
"${repo_root}/bin/weed" scaffold -config "${config}" 2>/dev/null \
"${tmpdir}/weed" scaffold -config "${config}" 2>/dev/null \
> "${package_dir}/example-${config}.toml"
done
"${repo_root}/bin/weed" autocomplete bash 2>/dev/null \
"${tmpdir}/weed" autocomplete bash 2>/dev/null \
| sed -E 's#complete -C "?[^"]*/weed"? weed#complete -C /usr/bin/weed weed#' \
> "${package_dir}/weed.bash-completion"
@@ -6,6 +6,9 @@ description="SeaweedFS ${service_name} service"
command="/usr/bin/weed"
command_user="${SEAWEEDFS_USER:-seaweedfs}:${SEAWEEDFS_GROUP:-seaweedfs}"
command_background="yes"
# SeaweedFS performs a graceful shutdown, including a 10-second final heartbeat.
# The OpenRC default stop timeout can expire before that work has completed.
retry="TERM/30/KILL/5"
pidfile="/run/seaweedfs/${RC_SVCNAME}.pid"
output_log="${SEAWEEDFS_LOG:-/var/log/seaweedfs/${RC_SVCNAME}.log}"
error_log="${SEAWEEDFS_ERRLOG:-/var/log/seaweedfs/${RC_SVCNAME}.log}"
@@ -46,6 +49,10 @@ build_command_args() {
data_dir="${SEAWEEDFS_DATA_DIR:-/var/lib/seaweedfs/worker}"
command_args="$command_args -admin=${SEAWEEDFS_ADMIN:-localhost:23646} -workingDir=${data_dir}"
;;
worker-lance)
command="/usr/bin/weed-worker"
command_args="--admin ${SEAWEEDFS_ADMIN:-localhost:23646} --namespace ${SEAWEEDFS_LANCE_NAMESPACE:-http://localhost:9101}"
;;
esac
command_args="$command_args ${SEAWEEDFS_OPTS:-}"
@@ -62,7 +69,7 @@ depend() {
s3|webdav|sftp)
after seaweedfs.filer
;;
worker)
worker|worker-lance)
after seaweedfs.admin
;;
esac
@@ -0,0 +1,10 @@
/var/log/seaweedfs/seaweedfs.*.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
copytruncate
su seaweedfs seaweedfs
}
@@ -0,0 +1,4 @@
# Lance maintenance worker. It is optional and requires a Lance namespace.
SEAWEEDFS_ADMIN="localhost:23646"
SEAWEEDFS_LANCE_NAMESPACE="http://localhost:9101"
SEAWEEDFS_OPTS=""
+1 -102
View File
@@ -1,104 +1,3 @@
[cors.allowed_origins]
values = "*"
[jwt.signing]
key = ""
expires_after_seconds = 10
# Do not expose the administrative UI by default.
[access]
ui = false
[filer.expose_directory_metadata]
enabled = true
[jwt.signing.read]
key = ""
expires_after_seconds = 10
[jwt.filer_signing]
key = ""
expires_after_seconds = 10
[jwt.filer_signing.read]
key = ""
expires_after_seconds = 10
[grpc]
ca = ""
allowed_wildcard_domain = ""
[grpc.volume]
cert = ""
key = ""
allowed_commonNames = ""
[grpc.master]
cert = ""
key = ""
allowed_commonNames = ""
[grpc.filer]
cert = ""
key = ""
allowed_commonNames = ""
[grpc.s3]
cert = ""
key = ""
allowed_commonNames = ""
[grpc.admin]
cert = ""
key = ""
allowed_commonNames = ""
[grpc.worker]
cert = ""
key = ""
allowed_commonNames = ""
[grpc.client]
cert = ""
key = ""
[https.client]
enabled = false
cert = ""
key = ""
ca = ""
insecure_skip_verify = false
[https.volume]
cert = ""
key = ""
ca = ""
[https.master]
cert = ""
key = ""
ca = ""
[https.filer]
cert = ""
key = ""
ca = ""
[https.admin]
cert = ""
key = ""
ca = ""
[admin]
user = ""
password = ""
[admin.readonly]
user = ""
password = ""
[s3.sse]
kek = ""
key = ""
[guard]
white_list = ""
@@ -1,8 +0,0 @@
[cluster]
default = "c1"
[cluster.c1]
master = "localhost:9333" # comma-separated master servers
[cluster.c2]
master = ""
@@ -0,0 +1,3 @@
provider=github
repo=seaweedfs/seaweedfs
version_prefix=none
+3
View File
@@ -4,6 +4,9 @@ FROM alpine:${ALPINE_VERSION}
ARG BUILDER_UID=1000
ARG BUILDER_GID=1000
RUN printf '%s\n' 'https://dl-cdn.alpinelinux.org/alpine/edge/community' \
>> /etc/apk/repositories
RUN apk add --no-cache \
abuild-rootbld \
alpine-sdk \
+25 -12
View File
@@ -19,6 +19,8 @@ if [[ "${builder_gid}" == "0" ]]; then
builder_gid=1000
fi
image_name="${ALPINE_APK_BUILDER_IMAGE:-alpine-apk-builder:${alpine_version}-${builder_uid}-${builder_gid}}"
cache_scope_from_remote() {
local remote
local path
@@ -63,7 +65,6 @@ run_for_arch() {
local arch="$1"
local subcommand="$2"
local package_dir="$3"
local image_name
local container_package_dir
local package_name
local cache_scope
@@ -73,19 +74,9 @@ run_for_arch() {
apk_validate_package_dir "${package_dir}"
package_name="$(apk_package_name "${package_dir}")"
container_package_dir="$(apk_container_package_dir "${repo_root}" "${package_dir}")"
image_name="${ALPINE_APK_BUILDER_IMAGE:-alpine-apk-builder:${arch}}"
cache_scope="${ALPINE_APK_CACHE_SCOPE:-$(cache_scope_from_remote)}"
cache_prefix="${ALPINE_APK_CACHE_PREFIX:-alpine-apk}-${cache_scope}-${package_name}-${arch}"
docker build \
--platform "${build_platform}" \
--build-arg "ALPINE_VERSION=${alpine_version}" \
--build-arg "BUILDER_UID=${builder_uid}" \
--build-arg "BUILDER_GID=${builder_gid}" \
-f "${repo_root}/scripts/apk/Dockerfile" \
-t "${image_name}" \
"${repo_root}"
docker_args=(--rm --platform "${build_platform}")
if [[ -t 0 && -t 1 ]]; then
docker_args+=(-it)
@@ -98,7 +89,7 @@ run_for_arch() {
-e "APKBUILD_DIR=${container_package_dir}" \
-e "CARGO_HOME=/home/builder/.cache/cargo" \
-e "CARGO_TARGET_DIR=/home/builder/.cache/cargo-target" \
-e "PACKAGER=${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}" \
-e "PACKAGER=${PACKAGER:-local}" \
-e "RUSTUP_HOME=/home/builder/.cache/rustup" \
-v "${cache_prefix}-cargo:/home/builder/.cache/cargo" \
-v "${cache_prefix}-cargo-target:/home/builder/.cache/cargo-target" \
@@ -111,11 +102,33 @@ run_for_arch() {
"${subcommand}"
}
build_builder_image() {
docker build \
--platform "${build_platform}" \
--build-arg "ALPINE_VERSION=${alpine_version}" \
--build-arg "BUILDER_UID=${builder_uid}" \
--build-arg "BUILDER_GID=${builder_gid}" \
-f "${repo_root}/scripts/apk/Dockerfile" \
-t "${image_name}" \
"${repo_root}"
}
mkdir -p \
"${repo_root}/.cache/abuild" \
"${repo_root}/.cache/apk-distfiles" \
"${repo_root}/packages"
case "${command_name}" in
build-all|build|checksum|lint|shell) ;;
*)
printf 'unknown command: %s\n' "${command_name}" >&2
printf 'usage: %s [build|build-all|checksum|lint|shell] [x86_64|aarch64]\n' "$0" >&2
exit 2
;;
esac
build_builder_image
case "${command_name}" in
build-all)
while IFS= read -r package_dir; do
+43 -6
View File
@@ -2,12 +2,20 @@
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=scripts/apk/package-lib.sh
. "${repo_root}/scripts/apk/package-lib.sh"
repo_name="${ALPINE_REPO_NAME:-local}"
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
packager="${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}"
packager="${PACKAGER:-local}"
selected_packages="${ALPINE_PACKAGE:-${ALPINE_PACKAGES:-}}"
skip_build="${ALPINE_SKIP_BUILD:-0}"
rust_cache_root="${ALPINE_RUST_CACHE_ROOT:-}"
if [[ "${skip_build}" == "1" ]]; then
printf 'Skipping package build: restored package cache is complete\n'
exit 0
fi
if [[ "${1:-}" != "--as-builder" && "$(id -u)" == "0" ]]; then
addgroup -g 1000 builder 2>/dev/null || addgroup builder
@@ -17,13 +25,22 @@ if [[ "${1:-}" != "--as-builder" && "$(id -u)" == "0" ]]; then
printf 'permit nopass :wheel\n' > /etc/doas.d/wheel.conf
printf '%%wheel ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/wheel
chown -R builder:builder "${repo_root}"
exec su builder -c "ALPINE_ARCHES='${arches}' ALPINE_REPO_NAME='${repo_name}' ALPINE_PACKAGES='${selected_packages}' PACKAGER='${packager}' '${BASH_SOURCE[0]}' --as-builder"
exec su builder -c "ALPINE_ARCHES='${arches}' ALPINE_REPO_NAME='${repo_name}' ALPINE_PACKAGES='${selected_packages}' PACKAGER='${packager}' ALPINE_RUST_CACHE_ROOT='${rust_cache_root}' '${BASH_SOURCE[0]}' --as-builder"
fi
export PACKAGER="${packager}"
export REPODEST="${repo_root}/packages"
export SRCDEST="${repo_root}/.cache/apk-distfiles"
install_repo_keys() {
local key
shopt -s nullglob
for key in "${REPODEST}/${repo_name}"/*/*.rsa.pub; do
doas cp "${key}" /etc/apk/keys/
done
shopt -u nullglob
}
git config --global --add safe.directory "${repo_root}"
mkdir -p "${repo_root}/.cache/abuild" "${SRCDEST}" "${REPODEST}" "${HOME}/.abuild"
@@ -33,10 +50,17 @@ if [[ ! -e "${HOME}/.abuild/abuild.conf" && -d "${repo_root}/.cache/abuild" ]];
fi
if ! compgen -G "${HOME}/.abuild/*.rsa" > /dev/null; then
abuild-keygen -a -n
# APK signatures identify their public key by filename. Matrix workers can
# otherwise generate different builder-<timestamp>.rsa keys with the same
# name when they start during the same second, making their artifacts
# impossible to merge. Use the selected package only while generating the
# key so the package metadata retains the configured PACKAGER value.
key_identity="${ALPINE_PACKAGE:-ci}"
PACKAGER="CI key <ci-${key_identity}@local.invalid>" abuild-keygen -a -n
fi
doas cp "${HOME}"/.abuild/*.rsa.pub /etc/apk/keys/
install_repo_keys
doas apk update
while IFS= read -r package_dir; do
@@ -55,10 +79,23 @@ while IFS= read -r package_dir; do
printf 'Building %s for %s\n' "$(basename "${package_dir}")" "${arch}"
(
export ALPINE_ARCH="${arch}"
export CARCH="${arch}"
package_name="$(apk_package_name "${package_dir}")"
if [[ -n "${rust_cache_root}" ]]; then
case "${package_name}" in
greptimedb)
export CARGO_HOME="${rust_cache_root}/greptimedb/cargo"
export RUSTUP_HOME="${rust_cache_root}/greptimedb/rustup"
export CARGO_TARGET_DIR="${rust_cache_root}/greptimedb/target"
;;
seaweedfs)
export CARGO_HOME="${rust_cache_root}/seaweedfs/cargo"
export CARGO_TARGET_DIR="${rust_cache_root}/seaweedfs/target"
unset RUSTUP_HOME
;;
esac
fi
cd "${package_dir}"
abuild -r
ALPINE_ARCH="${arch}" CARCH="${arch}" abuild -r
)
mkdir -p "${REPODEST}/${repo_name}/${arch}"
+158
View File
@@ -0,0 +1,158 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=scripts/apk/package-lib.sh
. "${repo_root}/scripts/apk/package-lib.sh"
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
branch="${ALPINE_REGISTRY_BRANCH:-v${ALPINE_VERSION:-3.24}}"
repository="${ALPINE_REGISTRY_REPOSITORY:-${PACKAGE_NAME:-main}}"
instance_url="${INSTANCE_URL:-}"
owner="${PACKAGE_OWNER:-}"
command_name="${1:-prepare}"
registry_cache="${CI_REGISTRY_CACHE_DIR:-${repo_root}/.cache/ci-registry}"
require_registry_config() {
local name="$1" value="$2"
[[ -n "${value}" ]] && return
printf 'missing required CI registry setting: %s\n' "${name}" >&2
exit 2
}
registry_url() {
printf '%s/api/packages/%s/alpine/%s/%s\n' \
"${instance_url%/}" "${owner}" "${branch}" "${repository}"
}
registry_key_url() {
printf '%s/api/packages/%s/alpine/key\n' "${instance_url%/}" "${owner}"
}
download_registry_metadata() {
local arch url key_dir
require_registry_config INSTANCE_URL "${instance_url}"
require_registry_config PACKAGE_OWNER "${owner}"
mkdir -p "${registry_cache}"
url="$(registry_url)"
for arch in ${arches}; do
curl --fail --silent --show-error --location \
--output "${registry_cache}/${arch}.APKINDEX.tar.gz" \
"${url}/${arch}/APKINDEX.tar.gz"
done
key_dir="${registry_cache}/keys"
mkdir -p "${key_dir}"
find "${key_dir}" -maxdepth 1 -type f -name '*.rsa.pub' -delete
curl --fail --silent --show-error --location \
--remote-name --remote-header-name --output-dir "${key_dir}" \
"$(registry_key_url)"
registry_key_path="$(find "${key_dir}" -maxdepth 1 -type f -name '*.rsa.pub' -print -quit)"
if [[ -z "${registry_key_path}" ]]; then
printf 'registry signing key was not downloaded: %s\n' "$(registry_key_url)" >&2
exit 1
fi
}
load_registry_index() {
local arch package_name package_version registry_key comparison
declare -gA registry_latest_versions=()
for arch in ${arches}; do
while IFS=$'\t' read -r package_name package_version; do
[[ -n "${package_name}" && -n "${package_version}" ]] || continue
registry_key="${arch}|${package_name}"
if [[ -z "${registry_latest_versions[${registry_key}]:-}" ]]; then
registry_latest_versions["${registry_key}"]="${package_version}"
continue
fi
comparison="$(apk version -t "${package_version}" "${registry_latest_versions[${registry_key}]}")"
if [[ "${comparison}" == ">" ]]; then
registry_latest_versions["${registry_key}"]="${package_version}"
fi
done < <(
tar -xOzf "${registry_cache}/${arch}.APKINDEX.tar.gz" APKINDEX | awk '
/^P:/ { package = substr($0, 3); next }
/^V:/ { if (package != "") print package "\t" substr($0, 3); package = "" }
'
)
done
}
registry_upgrade_packages() {
local package_dir package_name arch candidate_spec candidate_version published_version comparison selected
while IFS= read -r package_dir; do
apk_validate_package_dir "${package_dir}"
package_name="$(apk_package_name "${package_dir}")"
selected=0
for arch in ${arches}; do
apk_package_supports_arch "${package_dir}" "${arch}" || continue
IFS= read -r candidate_spec < <(apk_package_versioned_names "${package_dir}" "${arch}")
candidate_version="${candidate_spec#*=}"
published_version="${registry_latest_versions[${arch}|${package_name}]:-}"
if [[ -z "${published_version}" ]]; then
selected=1
printf 'Registry miss: %s (%s, %s)\n' "${package_name}" "${arch}" "${candidate_spec}" >&2
continue
fi
comparison="$(apk version -t "${candidate_version}" "${published_version}")"
if [[ "${comparison}" == ">" ]]; then
selected=1
printf 'Registry upgrade: %s (%s, %s -> %s)\n' \
"${package_name}" "${arch}" "${published_version}" "${candidate_version}" >&2
else
printf 'Registry current: %s (%s, source %s; published %s)\n' \
"${package_name}" "${arch}" "${candidate_version}" "${published_version}" >&2
fi
done
[[ "${selected}" == 1 ]] && printf '%s\n' "${package_name}"
done < <(apk_all_package_dirs "${repo_root}")
}
prepare() {
local selected
declare -A selected_map=()
download_registry_metadata
load_registry_index
while IFS= read -r selected; do
[[ -n "${selected}" ]] && selected_map["${selected}"]=1
done < <(registry_upgrade_packages)
ALPINE_PACKAGES="$(for selected in "${!selected_map[@]}"; do printf '%s\n' "${selected}"; done | sort | xargs)"
if [[ -n "${ALPINE_PACKAGES}" ]]; then
ALPINE_SKIP_BUILD=0
printf 'Selected packages for rebuild: %s\n' "${ALPINE_PACKAGES}"
else
ALPINE_SKIP_BUILD=1
printf 'No packages selected for rebuild: registry has equal or newer package versions\n'
fi
if [[ -n "${GITHUB_ENV:-}" ]]; then
{
printf 'ALPINE_PACKAGES=%s\n' "${ALPINE_PACKAGES}"
printf 'ALPINE_SKIP_BUILD=%s\n' "${ALPINE_SKIP_BUILD}"
printf 'ALPINE_REGISTRY_URL=%s\n' "$(registry_url)"
printf 'ALPINE_REGISTRY_KEY=%s\n' "${registry_key_path}"
} >> "${GITHUB_ENV}"
fi
if [[ -n "${GITHUB_OUTPUT:-}" ]]; then
printf 'selected_packages=%s\n' "${ALPINE_PACKAGES}" >> "${GITHUB_OUTPUT}"
if [[ -n "${ALPINE_PACKAGES}" ]]; then
printf 'packages_selected=true\n' >> "${GITHUB_OUTPUT}"
else
printf 'packages_selected=false\n' >> "${GITHUB_OUTPUT}"
fi
if [[ " ${ALPINE_PACKAGES} " == *" greptimedb "* ]]; then
printf 'greptimedb_selected=true\n' >> "${GITHUB_OUTPUT}"
else
printf 'greptimedb_selected=false\n' >> "${GITHUB_OUTPUT}"
fi
fi
}
case "${command_name}" in
prepare) prepare ;;
*) printf 'usage: %s prepare\n' "$0" >&2; exit 2 ;;
esac
+40 -5
View File
@@ -2,19 +2,49 @@
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=scripts/apk/package-lib.sh
. "${repo_root}/scripts/apk/package-lib.sh"
repo_name="${ALPINE_REPO_NAME:-local}"
arch="${ALPINE_ARCH:-$(apk --print-arch)}"
packages="${SMOKE_PACKAGES:-seaweedfs seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc greptimedb lavinmq lavinmq-openrc gitea gitea-openrc}"
packages="${SMOKE_PACKAGES:-seaweedfs seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc greptimedb lavinmq lavinmq-openrc gitea gitea-openrc rclone-openrc}"
repo_dir="${repo_root}/packages/${repo_name}/${arch}"
registry_url="${ALPINE_REGISTRY_URL:-}"
registry_key="${ALPINE_REGISTRY_KEY:-}"
read -r -a package_list <<< "${packages}"
declare -A source_packages=()
if [[ ! -d "${repo_dir}" ]]; then
printf 'missing local repository: packages/%s/%s\n' "${repo_name}" "${arch}" >&2
while IFS= read -r package_dir; do
while IFS= read -r spec; do
source_packages["${spec%%=*}"]=1
done < <(apk_package_versioned_names "${package_dir}" "${arch}")
done < <(apk_all_package_dirs "${repo_root}")
for package in "${package_list[@]}"; do
if [[ -z "${source_packages[${package}]:-}" ]]; then
printf 'smoke package is not defined by a source APKBUILD: %s\n' "${package}" >&2
exit 2
fi
done
if [[ -d "${repo_dir}" ]]; then
cp "${repo_dir}"/*.rsa.pub /etc/apk/keys/
echo "${repo_root}/packages/${repo_name}" >> /etc/apk/repositories
fi
if [[ -n "${registry_url}" ]]; then
if [[ ! -f "${registry_key}" ]]; then
printf 'missing Alpine registry signing key: %s\n' "${registry_key:-<unset>}" >&2
exit 1
fi
cp "${registry_key}" /etc/apk/keys/
echo "${registry_url}" >> /etc/apk/repositories
fi
if [[ ! -d "${repo_dir}" && -z "${registry_url}" ]]; then
printf 'missing local repository and no registry fallback: packages/%s/%s\n' "${repo_name}" "${arch}" >&2
exit 1
fi
cp "${repo_dir}"/*.rsa.pub /etc/apk/keys/
echo "${repo_root}/packages/${repo_name}" >> /etc/apk/repositories
apk update
apk add "${package_list[@]}"
if command -v weed >/dev/null 2>&1; then
@@ -34,6 +64,11 @@ if command -v gitea >/dev/null 2>&1; then
test -f /etc/gitea/app.ini
test -d /var/lib/gitea
fi
if command -v rclone >/dev/null 2>&1; then
rclone version
test -f /etc/conf.d/rclone
test -f /etc/init.d/rclone
fi
if ls /etc/init.d/seaweedfs.* >/dev/null 2>&1; then
find /etc/init.d -maxdepth 1 -name 'seaweedfs.*' -print | sort
fi
+11 -1
View File
@@ -7,7 +7,7 @@ repo_name="${ALPINE_REPO_NAME:-local}"
arch="${ALPINE_ARCH:-x86_64}"
export CARCH="${CARCH:-$arch}"
export PACKAGER="${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}"
export PACKAGER="${PACKAGER:-local}"
if [[ -n "${PACKAGER_PRIVKEY:-}" ]]; then
export PACKAGER_PRIVKEY
fi
@@ -15,6 +15,15 @@ fi
git config --global --add safe.directory /work
mkdir -p /home/builder/.abuild /home/builder/packages "${package_dir}"
install_repo_keys() {
local key
shopt -s nullglob
for key in "/home/builder/packages/${repo_name}"/*/*.rsa.pub; do
doas cp "${key}" /etc/apk/keys/
done
shopt -u nullglob
}
if [[ -n "${PACKAGER_PRIVKEY:-}" && ! -f "${PACKAGER_PRIVKEY}" ]]; then
abuild-keygen -a -n
elif ! compgen -G "/home/builder/.abuild/*.rsa" > /dev/null; then
@@ -34,6 +43,7 @@ if [[ -n "${PACKAGER_PRIVKEY:-}" && -f "${PACKAGER_PRIVKEY}.pub" ]]; then
elif compgen -G "/home/builder/.abuild/*.rsa.pub" > /dev/null; then
doas cp /home/builder/.abuild/*.rsa.pub /etc/apk/keys/
fi
install_repo_keys
case "${command_name}" in
build)
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
shellcheck \
"${repo_root}"/scripts/apk/*.sh \
"${repo_root}"/packaging/alpine/local/*/scripts/*.sh
+22
View File
@@ -2,7 +2,25 @@
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=scripts/apk/package-lib.sh
. "${repo_root}/scripts/apk/package-lib.sh"
repo_dir="${repo_root}/packages/local"
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
declare -A expected_apks=()
while IFS= read -r package_source_dir; do
apk_validate_package_dir "${package_source_dir}"
for arch in ${arches}; do
if ! apk_package_supports_arch "${package_source_dir}" "${arch}"; then
continue
fi
while IFS= read -r apk_name; do
expected_apks["${repo_dir}/${arch}/${apk_name}"]=1
done < <(apk_package_apk_names "${package_source_dir}" "${arch}")
done
done < <(apk_all_package_dirs "${repo_root}")
if [[ -n "${ALPINE_ARCH:-}" ]]; then
package_dirs=("${repo_dir}/${ALPINE_ARCH}")
@@ -29,6 +47,10 @@ for package_dir in "${package_dirs[@]}"; do
printf '## %s\n' "$(basename "${package_dir}")"
for apk in "${apks[@]}"; do
if [[ -z "${expected_apks[${apk}]:-}" ]]; then
printf 'Skipping stale local APK: %s\n' "${apk#"${repo_root}/"}"
continue
fi
printf '### %s\n' "$(basename "${apk}")"
tar -xOf "${apk}" .PKGINFO 2>/dev/null \
| sed -n '/^pkgname =/p;/^pkgver =/p;/^arch =/p;/^depend =/p;/^provides =/p;/^install_if =/p'
+103
View File
@@ -0,0 +1,103 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
repo_name="${ALPINE_REPO_NAME:-local}"
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
artifact_root="${APK_CI_ARTIFACTS_DIR:-${repo_root}/packages/worker-artifacts}"
package_root="${APK_CI_PACKAGE_ROOT:-${repo_root}/packages/${repo_name}}"
keys_root="$(mktemp -d)"
cleanup() {
rm -rf "${keys_root}"
}
trap cleanup EXIT
require_command() {
command -v "$1" >/dev/null 2>&1 || {
printf 'missing required command: %s\n' "$1" >&2
exit 2
}
}
copy_key() {
local key="$1"
local destination="$2"
local key_name
key_name="$(basename "${key}")"
if [[ -e "${destination}/${key_name}" ]]; then
if cmp -s "${key}" "${destination}/${key_name}"; then
return
fi
printf 'conflicting public keys named %s\n' "${key_name}" >&2
exit 1
fi
cp "${key}" "${destination}/${key_name}"
}
require_command abuild-keygen
require_command abuild-sign
require_command apk
if [[ ! -d "${artifact_root}" ]]; then
printf 'missing worker artifacts directory: %s\n' "${artifact_root}" >&2
exit 1
fi
rm -rf "${package_root}"
mkdir -p "${package_root}" "${HOME}/.abuild"
if ! compgen -G "${HOME}/.abuild/*.rsa" > /dev/null; then
abuild-keygen -a -n
fi
shopt -s nullglob
merge_private_keys=("${HOME}"/.abuild/*.rsa)
merge_public_keys=("${HOME}"/.abuild/*.rsa.pub)
shopt -u nullglob
if [[ "${#merge_private_keys[@]}" -ne 1 || "${#merge_public_keys[@]}" -ne 1 ]]; then
printf 'expected exactly one merge signing key in %s/.abuild\n' "${HOME}" >&2
exit 1
fi
for arch in ${arches}; do
destination="${package_root}/${arch}"
keys_dir="${keys_root}/${arch}"
mkdir -p "${destination}"
while IFS= read -r -d '' apk; do
cp "${apk}" "${destination}/"
done < <(find "${artifact_root}" -type f -path "*/${arch}/*.apk" -print0)
shopt -s nullglob
apks=("${destination}"/*.apk)
shopt -u nullglob
if [[ "${#apks[@]}" -eq 0 ]]; then
rmdir "${destination}"
continue
fi
while IFS= read -r -d '' key; do
copy_key "${key}" "${destination}"
mkdir -p "${keys_dir}"
copy_key "${key}" "${keys_dir}"
done < <(find "${artifact_root}" -type f -path "*/${arch}/*.rsa.pub" -print0)
if ! compgen -G "${keys_dir}/*.rsa.pub" > /dev/null; then
printf 'missing worker signing key for %s artifacts\n' "${arch}" >&2
exit 1
fi
copy_key "${merge_public_keys[0]}" "${destination}"
(
cd "${destination}"
apk --keys-dir "${keys_dir}" index --rewrite-arch "${arch}" -o APKINDEX.tar.gz ./*.apk
abuild-sign -k "${merge_private_keys[0]}" APKINDEX.tar.gz
)
done
if ! compgen -G "${package_root}"/*/*.apk > /dev/null; then
printf 'no APK files found in worker artifacts: %s\n' "${artifact_root}" >&2
exit 1
fi
+225
View File
@@ -0,0 +1,225 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=scripts/apk/package-lib.sh
source "${repo_root}/scripts/apk/package-lib.sh"
mode="${APK_UPDATE_CHECK_MODE:-warn}"
if [[ "${mode}" != "warn" && "${mode}" != "fail" ]]; then
printf 'APK_UPDATE_CHECK_MODE must be warn or fail\n' >&2
exit 2
fi
github_latest_release() {
local repo="$1"
local response
response="$(curl -fsSL \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
"https://api.github.com/repos/${repo}/releases/latest" 2>/dev/null)" || return 1
printf '%s\n' "${response}" | jq -er '.tag_name'
}
github_release_rows() {
local repo="$1"
local current_tag="$2"
local page=1
local response
local release_count
while :; do
response="$(curl -fsSL \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
"https://api.github.com/repos/${repo}/releases?per_page=100&page=${page}" 2>/dev/null)" || return 1
release_count="$(printf '%s\n' "${response}" | jq -er 'if type == "array" then length else error("expected release array") end')" || return 1
[[ "${release_count}" -gt 0 ]] || return 0
printf '%s\n' "${response}" | jq -r '
.[]
| select(.draft | not)
| select(.prerelease | not)
| [
.tag_name,
(.published_at // "-"),
(.name // .tag_name),
.html_url,
(
(.body // "")
| gsub("[\\r\\n\\t]+"; " ")
| gsub("[`*_>#]"; "")
| gsub(" +"; " ")
| gsub("^ +"; "")
| gsub(" +$"; "")
| if length > 240 then .[0:237] + "..." else . end
)
]
| @tsv
'
if printf '%s\n' "${response}" | jq -e --arg tag "${current_tag}" '
any(.[]; .tag_name == $tag and (.draft | not) and (.prerelease | not))
' >/dev/null; then
return 0
fi
page=$((page + 1))
done
}
apkbuild_value() {
local package_dir="$1"
local key="$2"
awk -F= -v key="${key}" '
$1 == key {
value = $2
gsub(/["'\'']/, "", value)
gsub(/^[ \t]+|[ \t]+$/, "", value)
print value
exit
}
' "${package_dir}/APKBUILD"
}
load_update_metadata() {
local package_dir="$1"
local metadata="${package_dir}/update-check.conf"
provider=""
repo=""
version_prefix="v"
if [[ ! -f "${metadata}" ]]; then
return 1
fi
# shellcheck source=/dev/null
source "${metadata}"
if [[ "${provider}" != "github" || -z "${repo}" ]]; then
return 1
fi
}
normalize_version() {
local version="$1"
local prefix="$2"
case "${prefix}" in
none|"")
printf '%s\n' "${version}"
;;
*)
printf '%s\n' "${version#"${prefix}"}"
;;
esac
}
version_is_newer() {
local latest="$1"
local current="$2"
local apk_result
local sorted
if [[ "${latest}" == "${current}" ]]; then
return 1
fi
if command -v apk >/dev/null 2>&1; then
apk_result="$(apk version -t "${latest}-r0" "${current}-r0" 2>/dev/null || true)"
[[ "${apk_result}" == ">" ]]
return
fi
if sort -V </dev/null >/dev/null 2>&1; then
sorted="$(printf '%s\n%s\n' "${current}" "${latest}" | sort -V | tail -n 1)"
[[ "${sorted}" == "${latest}" && "${latest}" != "${current}" ]]
return
fi
return 0
}
printf '%-14s %-14s %-14s %-18s %s\n' "PACKAGE" "CURRENT" "LATEST" "STATUS" "UPSTREAM"
has_update=0
has_unknown=0
release_details=""
while IFS= read -r package_dir; do
apk_validate_package_dir "${package_dir}"
package_name="$(apk_package_name "${package_dir}")"
current_version="$(apkbuild_value "${package_dir}" "pkgver")"
status="unknown"
latest_version="-"
upstream_url="-"
if load_update_metadata "${package_dir}"; then
upstream_url="https://github.com/${repo}/releases"
if latest_tag="$(github_latest_release "${repo}")" && [[ -n "${latest_tag}" ]]; then
latest_version="$(normalize_version "${latest_tag}" "${version_prefix}")"
if version_is_newer "${latest_version}" "${current_version}"; then
status="update-available"
has_update=1
package_details="${package_name}: ${current_version} -> ${latest_version}"
case "${version_prefix}" in
none|"") current_tag="${current_version}" ;;
*) current_tag="${version_prefix}${current_version}" ;;
esac
if release_rows="$(github_release_rows "${repo}" "${current_tag}")" && [[ -n "${release_rows}" ]]; then
current_tag_found=0
while IFS=$'\t' read -r release_tag published_at release_name release_url release_excerpt; do
[[ -n "${release_tag}" ]] || continue
release_version="$(normalize_version "${release_tag}" "${version_prefix}")"
if [[ "${release_tag}" == "${current_tag}" ]]; then
current_tag_found=1
fi
if version_is_newer "${release_version}" "${current_version}"; then
package_details+=$'\n'
package_details+=" ${release_version} (${published_at}) — ${release_name}"
package_details+=$'\n'
package_details+=" ${release_url}"
if [[ -n "${release_excerpt}" ]]; then
package_details+=$'\n'
package_details+=" ${release_excerpt}"
fi
fi
done <<< "${release_rows}"
if [[ "${current_tag_found}" == 0 ]]; then
package_details+=$'\n'
package_details+=" Note: current release tag ${current_tag} was not found; listed releases compare newer than ${current_version}."
fi
else
package_details+=$'\n'
package_details+=" Note: release details could not be fetched."
fi
release_details+=$'\n'
release_details+="${package_details}"
else
status="current"
fi
else
has_unknown=1
fi
else
has_unknown=1
fi
printf '%-14s %-14s %-14s %-18s %s\n' \
"${package_name}" \
"${current_version:-"-"}" \
"${latest_version}" \
"${status}" \
"${upstream_url}"
done < <(apk_package_dirs "${repo_root}")
if [[ -n "${release_details}" ]]; then
printf '\nRelease details:%s\n' "${release_details}"
fi
if [[ "${mode}" == "fail" && ( "${has_update}" -ne 0 || "${has_unknown}" -ne 0 ) ]]; then
exit 1
fi
+58
View File
@@ -37,6 +37,14 @@ apk_package_dirs() {
return
fi
apk_all_package_dirs "${repo_root}"
}
apk_all_package_dirs() {
local repo_root="$1"
local package_root
package_root="$(apk_package_root "${repo_root}")"
find "${package_root}" -mindepth 2 -maxdepth 2 -name APKBUILD -print \
| sed 's#/APKBUILD$##' \
| sort
@@ -87,6 +95,56 @@ apk_package_supports_arch() {
return 1
}
apk_package_apk_names() {
local package_dir="$1"
local arch="$2"
(
set +u
local pkgname
local pkgver
local pkgrel
local subpackage
local subpackages
# shellcheck disable=SC2034 # APKBUILD reads CARCH while sourced below.
local CARCH="${arch}"
cd "${package_dir}" || exit 1
# shellcheck source=/dev/null
. ./APKBUILD
printf '%s-%s-r%s.apk\n' "${pkgname}" "${pkgver}" "${pkgrel}"
for subpackage in ${subpackages:-}; do
subpackage="${subpackage%%:*}"
printf '%s-%s-r%s.apk\n' "${subpackage}" "${pkgver}" "${pkgrel}"
done
)
}
apk_package_versioned_names() {
local package_dir="$1"
local arch="$2"
(
set +u
local pkgname
local pkgver
local pkgrel
local subpackage
local subpackages
# shellcheck disable=SC2034 # APKBUILD reads CARCH while sourced below.
local CARCH="${arch}"
cd "${package_dir}" || exit 1
# shellcheck source=/dev/null
. ./APKBUILD
printf '%s=%s-r%s\n' "${pkgname}" "${pkgver}" "${pkgrel}"
for subpackage in ${subpackages:-}; do
subpackage="${subpackage%%:*}"
printf '%s=%s-r%s\n' "${subpackage}" "${pkgver}" "${pkgrel}"
done
)
}
apk_container_package_dir() {
local repo_root="$1"
local package_dir="$2"
+3
View File
@@ -4,7 +4,10 @@ set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "${repo_root}"
mise run apk:outdated
mise run apk:lint
mise run apk:lint-shell
mise run apk:build-all
mise run apk:packages
mise run apk:smoke
mise run apk:security-report
+33 -10
View File
@@ -2,8 +2,12 @@
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=scripts/apk/package-lib.sh
. "${repo_root}/scripts/apk/package-lib.sh"
repo_name="${ALPINE_REPO_NAME:-local}"
alpine_version="${ALPINE_VERSION:-3.24}"
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
branch="${ALPINE_REGISTRY_BRANCH:-v${alpine_version}}"
repository="${ALPINE_REGISTRY_REPOSITORY:-${PACKAGE_NAME:-main}}"
instance_url="${INSTANCE_URL:-}"
@@ -46,23 +50,42 @@ if [[ "${#apks[@]}" -eq 0 ]]; then
exit 1
fi
declare -A published_filenames=()
unique_apks=()
declare -A expected_apks=()
while IFS= read -r package_dir; do
apk_validate_package_dir "${package_dir}"
for arch in ${arches}; do
if ! apk_package_supports_arch "${package_dir}" "${arch}"; then
continue
fi
while IFS= read -r apk_name; do
expected_apks["${package_root}/${arch}/${apk_name}"]=1
done < <(apk_package_apk_names "${package_dir}" "${arch}")
done
done < <(apk_all_package_dirs "${repo_root}")
current_apks=()
stale_count=0
for apk in "${apks[@]}"; do
filename="$(basename "${apk}")"
if [[ -n "${published_filenames[${filename}]:-}" ]]; then
if [[ -z "${expected_apks[${apk}]:-}" ]]; then
printf 'Skipping stale local APK: %s\n' "${apk#"${repo_root}/"}"
stale_count=$((stale_count + 1))
continue
fi
published_filenames["${filename}"]=1
unique_apks+=("${apk}")
current_apks+=("${apk}")
done
printf 'Publishing %d APK files to %s\n' "${#unique_apks[@]}" "${upload_url}"
if [[ "${#unique_apks[@]}" -ne "${#apks[@]}" ]]; then
printf 'Skipping %d duplicate local APK filename(s)\n' "$((${#apks[@]} - ${#unique_apks[@]}))"
if [[ "${#current_apks[@]}" -eq 0 ]]; then
printf 'no current APK files found under %s\n' "${package_root}" >&2
exit 1
fi
for apk in "${unique_apks[@]}"; do
printf 'Publishing %d APK files to %s\n' "${#current_apks[@]}" "${upload_url}"
if [[ "${stale_count}" -ne 0 ]]; then
printf 'Skipping %d stale local APK file(s)\n' "${stale_count}"
fi
for apk in "${current_apks[@]}"; do
filename="$(basename "${apk}")"
status="$(
curl --silent --show-error --location \
+4
View File
@@ -0,0 +1,4 @@
ARG ALPINE_VERSION=3.24
FROM alpine:${ALPINE_VERSION}
RUN apk add --no-cache bash openrc
+13 -2
View File
@@ -10,6 +10,7 @@ arch="${ALPINE_ARCH:-x86_64}"
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
repo_dir="${repo_root}/packages/${repo_name}/${arch}"
runtime_mode="${ALPINE_RUNTIME_TEST_MODE:-auto}"
runtime_image="${ALPINE_RUNTIME_TEST_IMAGE:-alpine-apk-runtime-test:${alpine_version}}"
validate_repo() {
if [[ ! -d "${repo_dir}" ]]; then
@@ -66,10 +67,9 @@ run_hook_docker() {
-e "PACKAGE_NAME=${package_name}" \
-v "${repo_root}:/work:ro" \
-v "${repo_root}/packages/${repo_name}:/repo:ro" \
"alpine:${alpine_version}" \
"${runtime_image}" \
sh -lc '
set -e
apk add --no-cache bash openrc >/dev/null
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories
apk update
@@ -79,6 +79,15 @@ run_hook_docker() {
'
}
build_runtime_image() {
docker build \
--platform "${platform}" \
--build-arg "ALPINE_VERSION=${alpine_version}" \
-f "${repo_root}/scripts/apk/runtime-test.Dockerfile" \
-t "${runtime_image}" \
"${repo_root}"
}
validate_repo
case "${runtime_mode}" in
@@ -99,6 +108,8 @@ esac
if [[ "${runtime_mode}" == "direct" ]]; then
prepare_direct_runtime
else
build_runtime_image
fi
while IFS= read -r package_dir; do
+183
View File
@@ -0,0 +1,183 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=scripts/apk/package-lib.sh
. "${repo_root}/scripts/apk/package-lib.sh"
repo_name="${ALPINE_REPO_NAME:-local}"
alpine_version="${ALPINE_VERSION:-3.24}"
arches="${ALPINE_SECURITY_ARCHES:-${ALPINE_ARCHES:-x86_64}}"
reports_dir="${APK_SECURITY_REPORTS_DIR:-${repo_root}/packages/security-reports}"
trivy_bin="${TRIVY_BIN:-trivy}"
# The GCR pull-through mirror can serve a manifest whose layer has already
# expired, returning 404 rather than letting Trivy continue to its fallback.
# Use the publisher's registry directly; callers may still select an internal
# mirror by setting TRIVY_DB_REPOSITORY.
trivy_db_repository="${TRIVY_DB_REPOSITORY:-ghcr.io/aquasecurity/trivy-db:2}"
require_command() {
command -v "$1" >/dev/null 2>&1 || {
printf 'missing required command: %s\n' "$1" >&2
exit 2
}
}
platform_for_arch() {
case "$1" in
x86_64) printf '%s\n' 'linux/amd64' ;;
aarch64) printf '%s\n' 'linux/arm64' ;;
*) printf 'unsupported Alpine architecture: %s\n' "$1" >&2; return 2 ;;
esac
}
install_rootfs() {
local rootfs="$1"
local arch="$2"
shift 2
local -a specs=("$@")
local -a apk_args=(--root "${rootfs}/installed" --initdb --no-scripts --arch "${arch}")
local key_dir repo_file native_arch
key_dir="${rootfs}/keys"
repo_file="${rootfs}/repositories"
mkdir -p "${key_dir}"
cp /etc/apk/keys/*.pub "${key_dir}/"
cp "${repo_root}/packages/${repo_name}/${arch}"/*.rsa.pub "${key_dir}/"
{
printf 'https://dl-cdn.alpinelinux.org/alpine/v%s/main\n' "${alpine_version}"
printf 'https://dl-cdn.alpinelinux.org/alpine/v%s/community\n' "${alpine_version}"
printf 'file://%s/packages/%s\n' "${repo_root}" "${repo_name}"
} > "${repo_file}"
if [[ "$(id -u)" != 0 ]]; then
apk_args+=(--usermode)
fi
native_arch="$(apk --print-arch)"
if [[ "${arch}" != "${native_arch}" ]]; then
# A native Alpine image does not necessarily carry the current signing keys
# for another architecture. Bootstrap that architecture's alpine-keys over
# HTTPS, then use the refreshed key set for the actual dependency install.
apk "${apk_args[@]}" --keys-dir "${key_dir}" --repositories-file "${repo_file}" \
--allow-untrusted add --no-cache alpine-keys
cp "${rootfs}/installed/etc/apk/keys/"*.pub "${key_dir}/"
fi
apk "${apk_args[@]}" --keys-dir "${key_dir}" --repositories-file "${repo_file}" \
add --no-cache "${specs[@]}"
}
install_rootfs_docker() {
local rootfs="$1"
local arch="$2"
shift 2
local platform
platform="$(platform_for_arch "${arch}")"
docker run --rm --platform "${platform}" \
--user "$(id -u):$(id -g)" \
-e REPO_NAME="${repo_name}" \
-e ALPINE_ARCH="${arch}" \
-e ALPINE_VERSION="${alpine_version}" \
-v "${repo_root}:/work:ro" \
-v "${rootfs}:/scan" \
"alpine:${alpine_version}" \
sh -ec '
mkdir -p /scan/keys
cp /etc/apk/keys/*.pub /scan/keys/
cp /work/packages/"$REPO_NAME"/"$ALPINE_ARCH"/*.rsa.pub /scan/keys/
{
printf "https://dl-cdn.alpinelinux.org/alpine/v%s/main\\n" "$ALPINE_VERSION"
printf "https://dl-cdn.alpinelinux.org/alpine/v%s/community\\n" "$ALPINE_VERSION"
printf "file:///work/packages/%s\\n" "$REPO_NAME"
} > /scan/repositories
apk --root /scan/installed --usermode --initdb --no-scripts --arch "$ALPINE_ARCH" \
--keys-dir /scan/keys --repositories-file /scan/repositories \
add --no-cache "$@"
' security-report "$@"
}
write_summary() {
local report="$1"
local summary="$2"
local package_name="$3"
local arch="$4"
local total
total="$(jq '[.Results[]?.Vulnerabilities[]?] | length' "${report}")"
{
printf '# %s (%s) security report\n\n' "${package_name}" "${arch}"
printf 'Installed APK rootfs scanned with Trivy. Findings are advisory.\n\n'
printf '| Severity | Count |\n| --- | ---: |\n'
for severity in CRITICAL HIGH MEDIUM LOW UNKNOWN; do
printf '| %s | %s |\n' "${severity}" \
"$(jq --arg severity "${severity}" '[.Results[]?.Vulnerabilities[]? | select(.Severity == $severity)] | length' "${report}")"
done
printf '\nTotal vulnerabilities: %s\n' "${total}"
} > "${summary}"
}
print_report() {
local report_dir="$1"
local package_name="$2"
local arch="$3"
printf '\nSecurity reports for %s (%s):\n' "${package_name}" "${arch}"
printf ' Trivy: file://%s/trivy.json\n' "${report_dir}"
printf ' SBOM: file://%s/sbom.cdx.json\n' "${report_dir}"
printf ' Summary: file://%s/summary.md\n' "${report_dir}"
cat "${report_dir}/summary.md"
printf '\n'
}
require_command "${trivy_bin}"
require_command jq
if ! command -v apk >/dev/null 2>&1; then
require_command docker
fi
tmpdir="$(mktemp -d)"
cleanup() {
rm -rf "${tmpdir}"
}
trap cleanup EXIT
while IFS= read -r package_dir; do
apk_validate_package_dir "${package_dir}"
package_name="$(apk_package_name "${package_dir}")"
for arch in ${arches}; do
apk_package_supports_arch "${package_dir}" "${arch}" || continue
repo_dir="${repo_root}/packages/${repo_name}/${arch}"
if [[ ! -f "${repo_dir}/APKINDEX.tar.gz" ]] || ! compgen -G "${repo_dir}/*.rsa.pub" >/dev/null; then
printf 'missing signed local repository for %s: %s\n' "${package_name}" "${repo_dir}" >&2
exit 1
fi
mapfile -t specs < <(
apk_package_versioned_names "${package_dir}" "${arch}" | sed 's/=.*//'
)
specs=(alpine-baselayout "${specs[@]}")
report_dir="${reports_dir}/${package_name}/${arch}"
rootfs="${tmpdir}/${package_name}-${arch}"
mkdir -p "${report_dir}" "${rootfs}"
printf 'Generating security reports for %s (%s)\n' "${package_name}" "${arch}"
if command -v apk >/dev/null 2>&1; then
install_rootfs "${rootfs}" "${arch}" "${specs[@]}"
else
install_rootfs_docker "${rootfs}" "${arch}" "${specs[@]}"
fi
"${trivy_bin}" filesystem --db-repository "${trivy_db_repository}" --distro "alpine/${alpine_version}" --scanners vuln --format json --no-progress \
--output "${report_dir}/trivy.json" "${rootfs}/installed"
"${trivy_bin}" filesystem --db-repository "${trivy_db_repository}" --distro "alpine/${alpine_version}" --scanners vuln --format cyclonedx --no-progress \
--output "${report_dir}/sbom.cdx.json" "${rootfs}/installed"
jq -e 'type == "object" and has("ArtifactName")' "${report_dir}/trivy.json" >/dev/null
jq -e '.bomFormat == "CycloneDX"' "${report_dir}/sbom.cdx.json" >/dev/null
write_summary "${report_dir}/trivy.json" "${report_dir}/summary.md" "${package_name}" "${arch}"
print_report "${report_dir}" "${package_name}" "${arch}"
done
done < <(apk_package_dirs "${repo_root}")
+6 -1
View File
@@ -5,7 +5,7 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
alpine_version="${ALPINE_VERSION:-3.24}"
platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
arch="${ALPINE_ARCH:-x86_64}"
packages="${SMOKE_PACKAGES:-seaweedfs seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc greptimedb lavinmq lavinmq-openrc gitea gitea-openrc}"
packages="${SMOKE_PACKAGES:-seaweedfs seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc greptimedb lavinmq lavinmq-openrc gitea gitea-openrc rclone-openrc}"
if [[ ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
@@ -39,6 +39,11 @@ docker run --rm --platform "${platform}" \
test -f /etc/gitea/app.ini
test -d /var/lib/gitea
fi
if command -v rclone >/dev/null 2>&1; then
rclone version
test -f /etc/conf.d/rclone
test -f /etc/init.d/rclone
fi
if ls /etc/init.d/seaweedfs.* >/dev/null 2>&1; then
ls -1 /etc/init.d/seaweedfs.* | sort
fi
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
apk_test_install_run() {
local repo_root="$1"
local package_name="$2"
local package_version="$3"
local alpine_version="${ALPINE_VERSION:-3.24}"
local arch="${ALPINE_ARCH:-x86_64}"
local repository_url="${ALPINE_REPOSITORY_URL:-}"
local repository_key_url="${ALPINE_REPOSITORY_KEY_URL:-}"
local platform
local test_command
case "${arch}" in
x86_64) platform="${ALPINE_TEST_PLATFORM:-linux/amd64}" ;;
aarch64) platform="${ALPINE_TEST_PLATFORM:-linux/arm64}" ;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
return 2
;;
esac
if [[ -z "${repository_url}" && "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ -z "${repository_url}" && ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
return 1
fi
test_command="$(cat)"
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-e "PACKAGE_VERSION=${package_version}" \
-e "ALPINE_REPOSITORY_URL=${repository_url}" \
-e "ALPINE_REPOSITORY_KEY_URL=${repository_key_url}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc "${test_command}"
}
+38 -29
View File
@@ -5,8 +5,8 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
alpine_version="${ALPINE_VERSION:-3.24}"
platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
arch="${ALPINE_ARCH:-x86_64}"
packages="${TEST_SHELL_PACKAGES:-seaweedfs seaweedfs-doc bash-completion seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc greptimedb lavinmq lavinmq-doc lavinmq-openrc gitea gitea-doc gitea-openrc}"
shell="${TEST_SHELL:-/bin/bash}"
packages="${TEST_SHELL_PACKAGES:-}"
shell="${TEST_SHELL:-/bin/sh}"
timeout_seconds="${TEST_SHELL_TIMEOUT:-120}"
case "${arch}" in
@@ -24,9 +24,23 @@ if [[ ! -d "${repo_root}/packages/local/${arch}" ]]; then
exit 1
fi
docker_args=(--rm --platform "${platform}")
shopt -s nullglob
repo_keys=("${repo_root}/packages/local/${arch}"/*.rsa.pub)
repo_indexes=("${repo_root}/packages/local/${arch}"/APKINDEX.tar.gz)
shopt -u nullglob
if [[ "${#repo_keys[@]}" -eq 0 ]]; then
printf 'missing repository key: packages/local/%s/*.rsa.pub\n' "${arch}" >&2
exit 1
fi
if [[ "${#repo_indexes[@]}" -eq 0 ]]; then
printf 'missing repository index: packages/local/%s/APKINDEX.tar.gz\n' "${arch}" >&2
exit 1
fi
docker_args=(--rm -i --platform "${platform}")
if [[ -t 0 && -t 1 ]]; then
docker_args+=(-it)
docker_args+=(-t)
fi
docker run "${docker_args[@]}" \
@@ -46,31 +60,26 @@ docker run "${docker_args[@]}" \
printf "Refreshing apk indexes...\n"
timeout "${TEST_SHELL_TIMEOUT}" apk update
printf "Installing test packages: %s\n" "${PACKAGE_LIST}"
timeout "${TEST_SHELL_TIMEOUT}" apk add ${PACKAGE_LIST}
if [ -n "${PACKAGE_LIST}" ]; then
printf "Installing requested test packages: %s\n" "${PACKAGE_LIST}"
timeout "${TEST_SHELL_TIMEOUT}" apk add ${PACKAGE_LIST}
fi
printf "\nInstalled default test packages:\n"
apk info -e seaweedfs seaweedfs-doc seaweedfs-bash-completion \
seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc \
greptimedb lavinmq lavinmq-doc lavinmq-openrc \
gitea gitea-doc gitea-openrc \
| sort
if command -v weed >/dev/null 2>&1; then
printf "\nSeaweedFS version:\n"
weed version
fi
if command -v greptime >/dev/null 2>&1; then
printf "\nGreptimeDB version:\n"
greptime --version
fi
if command -v lavinmq >/dev/null 2>&1; then
printf "\nLavinMQ version:\n"
lavinmq -v
fi
if command -v gitea >/dev/null 2>&1; then
printf "\nGitea version:\n"
gitea --version
fi
printf "\nEntering %s. Repository mounted read-only at /work.\n\n" "${TEST_SHELL}"
cat <<EOF
Local APK repository is ready.
Repository: /repo
Workspace: /work
Examples:
apk add seaweedfs seaweedfs-master-openrc
apk add greptimedb greptimedb-docs greptimedb-standalone-openrc
apk add lavinmq lavinmq-openrc
apk add gitea gitea-openrc
apk add rclone-openrc
Entering ${TEST_SHELL}.
EOF
exec "${TEST_SHELL}"
'