Compare commits

33 Commits
Author SHA1 Message Date
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
fspjo de967b8d36 Merge pull request 'Add Gitea 1.26.4' (#3) from add-gitea-1.26.4 into main
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 29m44s
2026-07-08 18:19:27 +02:00
Joachim Schlöffel a3c4d09e65 Add Gitea 1.26.4 Alpine package
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Successful in 29m45s
2026-07-08 18:18:04 +02:00
fspjo dfd92c522b Merge pull request 'Add LavinMQ Alpine Package' (#2) from add-lavinmq-alpine-package into main
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 29m14s
2026-07-08 15:26:22 +02:00
Joachim Schlöffel 2c3107feb4 Add LavinMQ Alpine package
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Successful in 29m11s
2026-07-08 14:54:16 +02:00
fspjo 08e516475f Merge pull request 'Update GreptimeDB to 1.1.2' (#1) from update-greptimedb-1.1.2 into main
Build Alpine Packages / build-and-publish (v3.23, 3.23) (push) Successful in 27m16s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 27m13s
2026-07-06 14:54:07 +02:00
Joachim Schlöffel 9462c9a304 greptimedb version bump to 1.1.2
Build Alpine Packages / build-and-publish (v3.23, 3.23) (pull_request) Successful in 25m18s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (pull_request) Successful in 25m24s
2026-07-06 10:19:56 +02:00
Joachim Schlöffel 47c398a6ae Add Alpine package runtime tests
Build Alpine Packages / build-and-publish (v3.23, 3.23) (push) Successful in 25m39s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 26m14s
2026-07-06 09:37:18 +02:00
Joachim Schlöffel e076b3249a tighten docs 2026-07-05 23:21:24 +02:00
Joachim Schlöffel 1c4b598b5c Add Alpine v3.24 package target
Build Alpine Packages / build-and-publish (v3.23, 3.23) (push) Successful in 26m38s
Build Alpine Packages / build-and-publish (v3.24, 3.24) (push) Successful in 38m1s
2026-07-05 23:18:35 +02:00
Joachim Schlöffel 4efe12f250 shorter docs
Build Alpine Packages / build-and-publish (v3.23, 3.23) (push) Successful in 25m36s
2026-06-09 21:48:32 +02:00
Joachim Schlöffel b329cd0ccc Document preserving Gitea Alpine key filename
Build Alpine Packages / build-and-publish (v3.23, 3.23) (push) Successful in 25m2s
2026-06-09 14:25:09 +02:00
Joachim Schlöffel ca64a3e993 Skip duplicate APK filenames when publishing 2026-06-09 13:43:50 +02:00
Joachim Schlöffel 3049d872e0 Add GreptimeDB dashboard assets source
Build Alpine Packages / build-and-publish (v3.23, 3.23) (push) Successful in 24m50s
2026-06-09 13:33:10 +02:00
Joachim Schlöffel bef07e3e22 Add GreptimeDB docs package and trim CI matrix
Build Alpine Packages / build-and-publish (v3.23, 3.23) (push) Failing after 3m44s
2026-06-09 13:23:51 +02:00
Joachim Schlöffel 05188cc390 Add SeaweedFS package README links
Build Alpine Packages / build-and-publish (edge, edge) (push) Successful in 35m36s
Build Alpine Packages / build-and-publish (v3.23, 3.23) (push) Successful in 35m33s
2026-06-09 11:04:52 +02:00
Joachim Schlöffel 74207600cc Build Alpine packages for stable and edge 2026-06-09 11:00:42 +02:00
54 changed files with 1885 additions and 399 deletions
+5
View File
@@ -0,0 +1,5 @@
.git
.cache
packages
packaging/**/pkg
packaging/**/src
+58 -13
View File
@@ -1,6 +1,8 @@
name: Build Alpine Packages
on:
schedule:
- cron: "17 5 * * 1"
push:
branches:
- master
@@ -13,48 +15,91 @@ on:
jobs:
build-and-publish:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- alpine_version: "3.24"
alpine_registry_branch: "v3.24"
container:
image: alpine:3.23
image: "alpine:${{ matrix.alpine_version }}"
env:
ALPINE_VERSION: "3.23"
ALPINE_VERSION: "${{ matrix.alpine_version }}"
ALPINE_ARCHES: "x86_64 aarch64"
ALPINE_REGISTRY_BRANCH: "v3.23"
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/greptimedb/cargo"
RUSTUP_HOME: "/cache/public-alpine-packages/greptimedb/rustup"
CARGO_TARGET_DIR: "/cache/public-alpine-packages/greptimedb/target"
PACKAGER: "${{ gitea.repository_owner }}"
ALPINE_APK_REPO_CACHE: "/cache/public-alpine-packages/${{ matrix.alpine_registry_branch }}/apk-repo"
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"
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/greptimedb "$CARGO_HOME" "$RUSTUP_HOME" "$CARGO_TARGET_DIR"
apk add --no-cache --update abuild-rootbld alpine-sdk atools-apkbuild-lint bash ca-certificates curl doas git nodejs rsync shellcheck sudo tar
mkdir -p "$ALPINE_APK_REPO_CACHE" "$CARGO_HOME" "$RUSTUP_HOME" "$CARGO_TARGET_DIR"
chown -R 1000:1000 /cache/public-alpine-packages/${{ matrix.alpine_registry_branch }}
- 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
if: github.event_name != 'schedule'
run: |
scripts/apk/ci-package-cache.sh prepare
- name: Build packages
if: github.event_name != 'schedule'
run: |
scripts/apk/ci-build.sh
scripts/apk/ci-package-cache.sh sync
scripts/apk/export-ci-assets.sh
scripts/apk/list-packages.sh
- name: Check artifact upload support
if: github.event_name != 'schedule'
id: artifact-upload
run: |
if [ -n "${ACTIONS_RUNTIME_TOKEN:-}" ]; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "available=false" >> "$GITHUB_OUTPUT"
fi
- name: Upload generated CI assets
if: github.event_name != 'schedule' && steps.artifact-upload.outputs.available == 'true'
uses: actions/upload-artifact@v3
with:
name: greptimedb-musl-binaries
name: greptimedb-musl-binaries-${{ matrix.alpine_registry_branch }}
path: packages/ci-assets/
- name: Smoke test
if: github.event_name != 'schedule'
run: scripts/apk/ci-smoke.sh
- name: Runtime test
if: github.event_name != 'schedule'
run: scripts/apk/runtime-test.sh
- name: Publish Alpine packages
if: github.event_name != 'pull_request'
if: github.event_name != 'pull_request' && github.event_name != 'schedule'
run: scripts/apk/publish-gitea.sh
+114 -220
View File
@@ -1,171 +1,57 @@
# Alpine Packages
Alpine 3.23 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.
This repository builds signed `x86_64` and `aarch64` APKs and publishes them to
the Gitea Alpine package registry under:
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.23/alpine-packages
https://code.factoring.digital/api/packages/public/alpine/v3.24/alpine-packages
```
## Available Packages
| Package | APK Name | Package Version | Package Type | Purpose |
|-----------------------------------------------------------|--------------|-----------------|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
| [SeaweedFS](packaging/alpine/local/seaweedfs/README.md) | `seaweedfs` | `4.40` | 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.1.4` | 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.9.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` | `1.27.0` | Binary repackaging of official upstream release binaries | Ships current Gitea releases with the expected Alpine runtime layout and OpenRC service. |
## Use In Production
### Add The Package Repository
Install the registry signing key on each Alpine node:
Install the registry key:
```sh
curl -fsSLo /etc/apk/keys/public-alpine.rsa.pub \
https://code.factoring.digital/api/packages/public/alpine/key
cd /etc/apk/keys
curl -fsSLOJ https://code.factoring.digital/api/packages/public/alpine/key
```
Add the package repository:
Add the repository for the node's Alpine branch:
```sh
printf '%s\n' \
'https://code.factoring.digital/api/packages/public/alpine/v3.23/alpine-packages' \
'https://code.factoring.digital/api/packages/public/alpine/v3.24/alpine-packages' \
>> /etc/apk/repositories
apk update
```
If a forked or future registry is private, include a Gitea user and package token in the
repository URL:
Private registry URL format:
```text
https://<user>:<token>@code.factoring.digital/api/packages/public/alpine/v3.23/alpine-packages
https://<user>:<token>@code.factoring.digital/api/packages/public/alpine/v3.24/alpine-packages
```
### Install SeaweedFS Node Roles
Install the base package plus only the OpenRC role packages needed on that node.
For a single-node test or a compact small deployment:
```sh
apk add seaweedfs \
seaweedfs-master-openrc \
seaweedfs-volume-openrc \
seaweedfs-filer-openrc
```
For separated production nodes, install only the role running there:
```sh
apk add seaweedfs seaweedfs-master-openrc
apk add seaweedfs seaweedfs-volume-openrc
apk add seaweedfs seaweedfs-filer-openrc
```
Available OpenRC role packages:
```text
seaweedfs-master-openrc -> /etc/init.d/seaweedfs.master
seaweedfs-volume-openrc -> /etc/init.d/seaweedfs.volume
seaweedfs-filer-openrc -> /etc/init.d/seaweedfs.filer
seaweedfs-s3-openrc -> /etc/init.d/seaweedfs.s3
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
```
The package name is `seaweedfs`, matching Alpine aports. If a node already has
Alpine's old generic OpenRC package installed, remove it before installing a
role-specific split:
```sh
apk del seaweedfs-openrc
apk add seaweedfs seaweedfs-master-openrc
```
### Configure Services
Runtime files are installed in the usual Alpine locations:
```text
/usr/bin/weed
/etc/seaweedfs/*.toml
/etc/conf.d/seaweedfs.*
/etc/init.d/seaweedfs.*
```
Edit `/etc/conf.d/seaweedfs.<role>` for command-line flags and
`/etc/seaweedfs/*.toml` for SeaweedFS config. The packaged defaults are short
and production-neutral; full upstream example configs are in:
```text
/usr/share/doc/seaweedfs/examples/
```
Enable and start only the services needed on the node:
```sh
rc-update add seaweedfs.master default
rc-service seaweedfs.master start
rc-update add seaweedfs.volume default
rc-service seaweedfs.volume start
rc-update add seaweedfs.filer default
rc-service seaweedfs.filer start
```
Check the installed binary and service state:
```sh
weed version
rc-service seaweedfs.master status
```
### Optional Packages
Install docs and generated examples:
```sh
apk add seaweedfs-doc
```
Install bash completion:
```sh
apk add bash-completion seaweedfs-bash-completion
```
`seaweedfs-bash-completion` is also selected automatically when `seaweedfs` and
`bash-completion` are installed together.
### Upgrade Or Pin
Use normal Alpine package operations:
```sh
apk upgrade seaweedfs
rc-service seaweedfs.master restart
```
Pin a specific package build when needed:
```sh
apk add seaweedfs=4.31-r3
```
### Install GreptimeDB
Install GreptimeDB:
```sh
apk add greptimedb
```
Check the installed binary:
```sh
greptime --version
```
## Background And Contribution
## Contribution
### Package Layout
@@ -175,24 +61,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.0.2 built from source for x86_64
```
### SeaweedFS Package
The APKBUILD repackages the official SeaweedFS Linux release tarballs. It does
not build SeaweedFS from source. The package installs:
- `weed` as `/usr/bin/weed`
- minimal active config under `/etc/seaweedfs/`
- role-specific OpenRC subpackages
- upstream example configs under `/usr/share/doc/seaweedfs/examples/`
- generated bash completion as a separate subpackage
Local build output is written under:
```text
@@ -209,28 +77,39 @@ Signing keys and distfiles are cached under:
### Build Commands
```sh
mise run apk:lint
mise run apk:build
mise run apk:build-all
mise run apk:packages
mise run apk:smoke
mise run apk:test-install
mise run apk:test-shell
mise run apk:publish-check
$ mise tasks
Name Description
apk:build Build the Alpine package in Docker for the default architecture
apk:build-aarch64 Build the Alpine package in Docker for aarch64
apk:build-all Build the Alpine package in Docker for all configured architectures
apk:build-x86_64 Build the Alpine package in Docker for x86_64
apk:checksum Refresh APKBUILD checksums in Docker
apk:ci-build Build all configured Alpine packages directly in the current Alpine...
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 against latest GitHub releases
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 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
```
`apk:build` targets `x86_64` by default. Multi-arch builds target `x86_64` and
`aarch64`; override with `ALPINE_ARCHES` when needed:
`aarch64`:
```sh
ALPINE_ARCHES="x86_64 aarch64" mise run apk:build-all
```
Unqualified build and install-test tasks discover all packages. GreptimeDB is a
source build and can take close to an hour; it is limited to `x86_64` during
production evaluation. Target fast package work explicitly:
Build or test a subset of packages with `ALPINE_PACKAGE` or `ALPINE_PACKAGES`:
Limit package selection with `ALPINE_PACKAGE` or `ALPINE_PACKAGES`:
```sh
ALPINE_PACKAGE=seaweedfs mise run apk:build
@@ -239,78 +118,96 @@ ALPINE_PACKAGE=seaweedfs mise run apk:test-install
ALPINE_PACKAGE=greptimedb mise run apk:checksum
ALPINE_PACKAGE=greptimedb mise run apk:build
ALPINE_PACKAGE=greptimedb SKIP_BUILD=1 mise run apk:test-install
ALPINE_PACKAGE=lavinmq mise run apk:build
ALPINE_PACKAGE=lavinmq SKIP_BUILD=1 mise run apk:test-install
ALPINE_PACKAGE=gitea mise run apk:build
ALPINE_PACKAGE=gitea SKIP_BUILD=1 mise run apk:test-install
```
Docker-backed build tasks keep Cargo registry, Rustup, and Cargo target caches in named Docker volumes. The default volume scope is derived from the Git remote owner/repository and is split by package and architecture. Override it when needed:
Override Docker cache scope:
```sh
ALPINE_APK_CACHE_SCOPE=public-alpine-packages ALPINE_PACKAGE=greptimedb mise run apk:build
ALPINE_APK_CACHE_PREFIX=alpine-apk-ci ALPINE_PACKAGE=greptimedb mise run apk:build
```
Use the test shell to inspect the package in Alpine with the current build
installed:
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
```
Use the install test to validate the production instructions against the local
package repository in a fresh Alpine container:
Run the install test:
```sh
mise run apk:test-install
```
Use `SKIP_BUILD=1` to reuse existing local packages:
Reuse existing local packages:
```sh
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
```
Run package-local runtime tests:
```sh
mise run apk:runtime-test
ALPINE_PACKAGE=seaweedfs mise run apk:runtime-test
ALPINE_VERSION=3.24 mise run apk:runtime-test
```
### Adding Packages
Each package lives under:
Package path:
```text
packaging/alpine/local/<pkgname>/
```
The only required file is `APKBUILD`. Package-specific helpers can be added as
hooks:
Optional package hooks:
```text
packaging/alpine/local/<pkgname>/scripts/test-install.sh
packaging/alpine/local/<pkgname>/scripts/update-generated-sources.sh
packaging/alpine/local/<pkgname>/scripts/runtime-test.sh
```
Repo-level tasks discover all `packaging/alpine/local/*/APKBUILD` files. Hook
tasks skip packages that do not provide the requested hook.
Start new packages from the blueprint:
Start from the blueprint:
```text
packaging/alpine/blueprint/
```
For compiled software, declare build tools in `makedepends` and use normal
Alpine `build()`, `check()`, and `package()` functions in the package's
`APKBUILD`.
### Generated Package Sources
Generated files should live next to the package's `APKBUILD` so
`abuild checksum` can track them as ordinary package sources. For SeaweedFS,
that includes:
Generated package sources live next to the package `APKBUILD`:
```text
packaging/alpine/local/seaweedfs/example-*.toml
packaging/alpine/local/seaweedfs/weed.bash-completion
```
Refresh generated sources through package-local hooks:
Refresh generated sources:
```sh
mise run apk:update-generated
@@ -318,13 +215,26 @@ ALPINE_PACKAGE=seaweedfs mise run apk:update-generated
mise run apk:checksum
```
Run `apk:checksum` after changing any file listed in `source=`.
### 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
```
### Gitea Workflow
The workflow at `.gitea/workflows/build.yml` builds in an `alpine:3.23`
container and publishes on push or tag. It skips publishing for pull request
events.
`.gitea/workflows/build.yml` builds and publishes `v3.24`. Pull requests
build only.
Repository variables:
@@ -341,13 +251,13 @@ PACKAGE_USER=<gitea package publisher>
PACKAGE_TOKEN=<token with package write access>
```
Pre-check the workflow locally with `act`:
Check the workflow locally:
```sh
mise run gitea-workflow-build
```
Publish already-built local packages manually:
Publish local packages:
```sh
INSTANCE_URL=https://code.factoring.digital \
@@ -358,25 +268,7 @@ PACKAGE_TOKEN=... \
mise run apk:publish-gitea
```
### Alpine Package Rules
Do:
- Keep local package sources next to the `APKBUILD`.
- Put full upstream scaffolds in `/usr/share/doc/seaweedfs/examples/`, not active `/etc`.
- Install only the OpenRC role packages needed on each node.
- Keep `/etc/conf.d` defaults short and production-neutral.
- Increment `pkgrel` for package-only changes; reset it when `pkgver` changes.
- Run `mise run apk:publish-check` before opening a PR.
Don't:
- Edit generated `src/`, `pkg/`, or `packages/` output.
- Hand-edit checksum lines when `abuild checksum` can update them.
- Install all OpenRC roles by default.
- Put long upstream examples into active `/etc` defaults.
### Practical PR Checklist
### Checklist
Before opening a PR, run:
@@ -384,12 +276,14 @@ Before opening a PR, run:
mise run apk:publish-check
mise run gitea-workflow-build
mise run apk:test-install
mise run apk:runtime-test
```
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
+14 -2
View File
@@ -1,6 +1,5 @@
[tools]
act = "latest"
codex = "latest"
docker-cli = "latest"
shellcheck = "latest"
@@ -36,6 +35,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,17 +48,26 @@ 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"]
description = "Test README installation instructions in a fresh Alpine container"
run = "scripts/apk/test-install.sh"
[tasks."apk:runtime-test"]
description = "Run package-local Docker runtime tests against the local Alpine repository"
run = "scripts/apk/runtime-test.sh"
env = { ALPINE_ARCH = "x86_64", ALPINE_REPO_NAME = "local", ALPINE_VERSION = "3.24" }
[tasks."apk:packages"]
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:publish-check"]
description = "Run lint, multi-arch build, package listing, and smoke test"
run = "scripts/apk/publish-check.sh"
+3
View File
@@ -12,6 +12,8 @@ Optional package-local hooks:
- `scripts/test-install.sh` validates README-style installation instructions.
- `scripts/update-generated-sources.sh` refreshes generated files that are
listed in `source=`.
- `scripts/runtime-test.sh` validates an installed package in the shared Docker
runtime test.
Repo-level tasks discover packages from `packaging/alpine/local/*/APKBUILD`.
Limit a task to one or more packages with:
@@ -20,6 +22,7 @@ Limit a task to one or more packages with:
ALPINE_PACKAGE=<pkgname> mise run apk:build
ALPINE_PACKAGES="<pkg-a> <pkg-b>" mise run apk:build-all
ALPINE_PACKAGE=<pkgname> mise run apk:test-install
ALPINE_PACKAGE=<pkgname> mise run apk:runtime-test
```
For compiled software, put normal Alpine build logic in `build()`, `check()`,
@@ -3,7 +3,7 @@ set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)")}"
alpine_version="${ALPINE_VERSION:-3.23}"
alpine_version="${ALPINE_VERSION:-3.24}"
arch="${ALPINE_ARCH:-x86_64}"
case "${arch}" in
+77
View File
@@ -0,0 +1,77 @@
# Maintainer: Joachim Schlöffel <joachim.schloeffel@financial-service-plus.de>
pkgname=gitea
pkgver=1.27.1
pkgrel=2
pkgdesc="Self-hosted Git service written in Go"
url="https://about.gitea.com/"
arch="x86_64 aarch64"
license="MIT"
depends="git git-lfs gnupg"
makedepends="tar xz"
provides="cmd:gitea=$pkgver-r$pkgrel"
install="$pkgname.pre-install"
pkgusers="gitea"
pkggroups="www-data"
subpackages="
$pkgname-doc
$pkgname-openrc:_openrc:noarch
"
options="!check !strip !tracedeps"
case "$CARCH" in
x86_64)
_archive="$pkgname-$pkgver-linux-amd64.xz"
;;
aarch64)
_archive="$pkgname-$pkgver-linux-arm64.xz"
;;
esac
source="
$pkgname-$pkgver-linux-amd64.xz::https://github.com/go-gitea/gitea/releases/download/v$pkgver/gitea-$pkgver-linux-amd64.xz
$pkgname-$pkgver-linux-arm64.xz::https://github.com/go-gitea/gitea/releases/download/v$pkgver/gitea-$pkgver-linux-arm64.xz
$pkgname-src-$pkgver.tar.gz::https://github.com/go-gitea/gitea/releases/download/v$pkgver/gitea-src-$pkgver.tar.gz
gitea.ini
gitea.initd
"
builddir="$srcdir/gitea-src-$pkgver"
prepare() {
default_prepare
xz -dc "$srcdir/$_archive" > "$srcdir"/gitea
chmod 0755 "$srcdir"/gitea
}
package() {
local _dir
for _dir in gitea gitea/git gitea/data gitea/db gitea/custom; do
install -d -m 0750 -o gitea -g www-data \
"$pkgdir"/var/lib/$_dir
done
install -d -m 0755 -o gitea -g www-data "$pkgdir"/var/log/gitea
install -Dm755 "$srcdir"/gitea "$pkgdir"/usr/bin/gitea
install -Dm644 -o gitea -g www-data "$srcdir"/gitea.ini \
"$pkgdir"/etc/gitea/app.ini
chown gitea:www-data "$pkgdir"/etc/gitea
install -d -m 0755 "$pkgdir"/usr/share/webapps/gitea
cp -r "$builddir"/options "$builddir"/public "$builddir"/templates \
"$pkgdir"/usr/share/webapps/gitea/
install -Dm644 "$builddir"/LICENSE -t "$pkgdir"/usr/share/licenses/gitea/
}
_openrc() {
pkgdesc="$pkgdesc (OpenRC service)"
depends="$pkgname=$pkgver-r$pkgrel openrc"
install -Dm755 "$srcdir"/gitea.initd "$subpkgdir"/etc/init.d/gitea
}
sha512sums="
103a3af76a84d9a093aaed09f03519ae1f698609f3374d64bc0c3aaed00296e5bea8382e8b5a0115c56875d64b8dd8e69dea43093ecebcd87fd5298e533b6fa2 gitea-1.27.1-linux-amd64.xz
ffb9d13be03ada20a8b8d59c6e7885b4ba57a27f3f487920a61b2491e56c06eb8d4f21ff6fb32ea598535b3af66bb15347ed3e07df4eaf532ed4c63909e4caee gitea-1.27.1-linux-arm64.xz
19e9893a2e15de188ad4fb17f52c49c87884ff5c14d2fadf59213887f262f7200ae0a86af4d3c9488d1cded54864e08423b5058e60c694fbb235e8693736436d gitea-src-1.27.1.tar.gz
431184faffa8996873d92d7b0d16bc4b1a0178d264cd2928d1f49b13ad3e6470d9ede7a18c12112deeeb38f0647ccc0b012e98bcbd96e7b8496a3dc18f5b1fb7 gitea.ini
9474d707df8b049c93ec4642f71195adff699e1e812f315cac4295b3ab29eeb9ba8b83bf3307c50b04e072a4a9dc4c4f84ac490ee22291bd50015009795c1598 gitea.initd
"
+38
View File
@@ -0,0 +1,38 @@
# Gitea Alpine Package
Repackages upstream Gitea 1.27.0 Linux release binaries for `x86_64` and
`aarch64`.
The package follows Alpine's Gitea runtime layout:
- `/usr/bin/gitea`
- `/etc/gitea/app.ini`
- `/var/lib/gitea`
- `/var/log/gitea`
- `/usr/share/webapps/gitea`
Install the OpenRC service with:
```sh
apk add gitea gitea-openrc
rc-update add gitea default
rc-service gitea start
```
Refresh checksums:
```sh
ALPINE_PACKAGE=gitea mise run apk:checksum
```
Build:
```sh
ALPINE_PACKAGE=gitea mise run apk:build
```
Install-test local build:
```sh
ALPINE_PACKAGE=gitea SKIP_BUILD=1 mise run apk:test-install
```
+26
View File
@@ -0,0 +1,26 @@
# Configuration cheat sheet: https://docs.gitea.io/en-us/config-cheat-sheet/
RUN_USER = gitea
RUN_MODE = prod
[repository]
ROOT = /var/lib/gitea/git
SCRIPT_TYPE = sh
[server]
STATIC_ROOT_PATH = /usr/share/webapps/gitea
APP_DATA_PATH = /var/lib/gitea/data
LFS_START_SERVER = true
[database]
DB_TYPE = sqlite3
PATH = /var/lib/gitea/db/gitea.db
SSL_MODE = disable
[session]
PROVIDER = file
[log]
ROOT_PATH = /var/log/gitea
MODE = file
LEVEL = Info
+30
View File
@@ -0,0 +1,30 @@
#!/sbin/openrc-run
supervisor=supervise-daemon
name=gitea
command="/usr/bin/gitea"
command_user="${GITEA_USER:-gitea}"
command_args="web --config '${GITEA_CONF:-/etc/gitea/app.ini}'"
supervise_daemon_args="--env GITEA_WORK_DIR='${GITEA_WORK_DIR:-/var/lib/gitea}' --chdir '${GITEA_WORK_DIR:-/var/lib/gitea}' --stdout '${GITEA_LOG_FILE:-/var/log/gitea/http.log}' --stderr '${GITEA_LOG_FILE:-/var/log/gitea/http.log}'"
pidfile="/run/gitea.pid"
extra_started_commands="reopen_log"
capabilities="^cap_net_bind_service"
depend() {
use logger dns
need net
after firewall mysql postgresql
}
# https://github.com/go-gitea/gitea/issues/17976
# reload() {
# ebegin "Reloading ${RC_SVCNAME}"
# ${supervisor} ${RC_SVCNAME} --signal HUP --pidfile "${pidfile}"
# eend $?
# }
reopen_log() {
ebegin "Reopening logfile for ${RC_SVCNAME}"
${supervisor} ${RC_SVCNAME} --signal USR1 --pidfile "${pidfile}"
eend $?
}
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
addgroup -S www-data 2>/dev/null
adduser -S -D -H -h /var/lib/gitea -s /sbin/nologin \
-G www-data -g gitea gitea 2>/dev/null
exit 0
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
apk add gitea gitea-doc gitea-openrc
test -x /usr/bin/gitea
test -f /etc/gitea/app.ini
test -d /var/lib/gitea
test -d /var/lib/gitea/git
test -d /var/lib/gitea/data
test -d /var/lib/gitea/db
test -d /var/log/gitea
test -d /usr/share/webapps/gitea/options
test -d /usr/share/webapps/gitea/public
test -d /usr/share/webapps/gitea/templates
test -f /etc/init.d/gitea
gitea --version
rc-update add gitea default || true
test -L /etc/runlevels/default/gitea
+53
View File
@@ -0,0 +1,53 @@
#!/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:-gitea}" "${PACKAGE_VERSION:-1.27.0-r1}" <<'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
apk update
apk add "${PACKAGE_NAME}"
installed_before="$(apk list -I "${PACKAGE_NAME}" | awk "{print \$1}")"
printf "Installed repository package before local upgrade: %s\n" "${installed_before}"
if [ "${installed_before}" = "${PACKAGE_NAME}-${PACKAGE_VERSION}" ]; then
printf "default repository already has %s; upgrade path was not exercised\n" "${PACKAGE_VERSION}" >&2
exit 1
fi
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories
fi
apk update
apk add --upgrade "${PACKAGE_NAME}" "${PACKAGE_NAME}-doc" "${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}"
test -x /usr/bin/gitea
test -f /etc/gitea/app.ini
test -d /var/lib/gitea
test -d /var/lib/gitea/git
test -d /var/lib/gitea/data
test -d /var/lib/gitea/db
test -d /var/log/gitea
test -d /usr/share/webapps/gitea/options
test -d /usr/share/webapps/gitea/public
test -d /usr/share/webapps/gitea/templates
test -f /etc/init.d/gitea
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
+20 -4
View File
@@ -1,7 +1,7 @@
# Maintainer: Joachim Schlöffel <me@joachim-schloeffel.com>
# Maintainer: Joachim Schlöffel <mjoachim.schloeffel@financial-service-plus.de>
pkgname=greptimedb
pkgver=1.0.2
pkgrel=1
pkgver=1.1.4
pkgrel=0
pkgdesc="Cloud-native observability database for metrics, logs, and traces"
url="https://github.com/GreptimeTeam/greptimedb"
arch="x86_64"
@@ -31,14 +31,17 @@ makedepends="
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-metasrv-openrc:_openrc_metasrv:noarch
$pkgname-standalone-openrc:_openrc_standalone:noarch
"
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
datanode.toml
flownode.toml
frontend.toml
@@ -65,6 +68,10 @@ export LIBRARY_PATH="/usr/lib"
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 \
@@ -111,8 +118,17 @@ _openrc_frontend() { _openrc_service frontend; }
_openrc_metasrv() { _openrc_service metasrv; }
_openrc_standalone() { _openrc_service standalone; }
_docs() {
pkgdesc="$pkgdesc (configuration examples and reference)"
depends=""
mkdir -p "$subpkgdir"/usr/share/doc/$pkgname
cp -a "$builddir"/config "$subpkgdir"/usr/share/doc/$pkgname/
}
sha512sums="
7f4ac722b84a26816030e65d504b37a53edfca15de669a4f6ee7a903f1a29c8358dcc2376a0a6cfd9ded13b0c5d7550a6856b9b10dc8cd080c6b12970553a0ea greptimedb-1.0.2.tar.gz
d60080a82a1dba52ab28d33ba1d9109bd047a6e598dbad17a3d92c82c6aad20b7fffd35cc20571829d8869360040af61195eeb97a14e08d8289e70663ee08664 greptimedb-1.1.4.tar.gz
4260acae5bed00a693dceffe9f53d0f8b25fd677b15638e951cf973dc29681f4bacde352c661a12bd78af7be9181a3740812f814fc3c4c8c87ea4eee6ee07e2d dashboard-v0.12.0.tar.gz
29cc3376753487b216748e3f85e12639830e1ac4a763e94f330f87c3651a8ef9de35732958311c0049e1b7cbb4e90a9e602b3aff43297fe088c5ce795a110a79 datanode.toml
52790808cb4f5cf0220ac2ab169b623fe76b6318d27d7f003e1197e850373cb915bfd40556098bcb7650f293d751039cb3bccbf9107bb160b8284887794ba975 flownode.toml
e3e19ab3c7a345ecf8cf0a507f7fc95dd3b036a4a797385cf77fcf1999f2e4f053042c7bbda8de73ed43ff72e87aad81e4ac6d4a34d01773bbc1f6d0d967d9f7 frontend.toml
+62 -9
View File
@@ -1,42 +1,95 @@
# GreptimeDB Alpine Package
This package builds `greptime` from the upstream GreptimeDB source release and packages OpenRC service subpackages plus default `/etc/greptimedb` configuration.
Builds `greptime` from the upstream source release and packages OpenRC service
subpackages plus `/etc/greptimedb` defaults.
The APKBUILD builds the release directly:
Build command:
```sh
cargo build --profile nightly --locked --bin greptime --features servers/dashboard
```
## Runtime Layout
Installs `/usr/bin/greptime` and component OpenRC packages:
- `greptimedb-docs`: upstream configuration examples and reference files from
`config/`
- `greptimedb-standalone-openrc`: `greptime standalone start`
- `greptimedb-metasrv-openrc`: `greptime metasrv start`
- `greptimedb-datanode-openrc`: `greptime datanode start`
- `greptimedb-flownode-openrc`: `greptime flownode start`
- `greptimedb-frontend-openrc`: `greptime frontend start`
Default TOML files are installed in `/etc/greptimedb`. Standalone ports:
- `127.0.0.1:4000`: HTTP API and dashboard
- `127.0.0.1:4001`: gRPC
- `127.0.0.1:4002`: MySQL
- `127.0.0.1:4003`: PostgreSQL
Configs bind to localhost by default. Upstream config examples are in
`/usr/share/doc/greptimedb/config`.
## OpenRC Usage
Standalone:
```sh
apk add greptimedb greptimedb-docs greptimedb-standalone-openrc
rc-update add greptimedb.standalone default
rc-service greptimedb.standalone start
```
Distributed components:
```sh
apk add \
greptimedb \
greptimedb-metasrv-openrc \
greptimedb-datanode-openrc \
greptimedb-flownode-openrc \
greptimedb-frontend-openrc
```
Wrapper settings in `/etc/conf.d/greptimedb.<component>`:
- `GREPTIMEDB_CONFIG`: config file path passed with `-c`
- `GREPTIMEDB_LOG_DIR`: component log directory passed with `--log-dir`
- `GREPTIMEDB_DATA_HOME`: data directory passed with `--data-home` where the
component supports it
- `GREPTIMEDB_WAL_DIR`: datanode WAL directory passed with `--wal-dir`
- `GREPTIMEDB_OPTS`: extra component arguments appended after package defaults
- `GREPTIMEDB_GLOBAL_OPTS`: arguments inserted before the component command
## Package Commands
Refresh the source checksum after changing `pkgver`:
Refresh checksums:
```sh
ALPINE_PACKAGE=greptimedb mise run apk:checksum
```
Build only this package:
Build:
```sh
ALPINE_PACKAGE=greptimedb mise run apk:build
```
Install-test an existing local build without recompiling:
Install-test local build:
```sh
ALPINE_PACKAGE=greptimedb SKIP_BUILD=1 mise run apk:test-install
```
Install-test from a published Gitea Alpine repository:
Install-test published repository:
```sh
ALPINE_PACKAGE=greptimedb \
SKIP_BUILD=1 \
ALPINE_REPOSITORY_URL=https://code.factoring.digital/api/packages/public/alpine/v3.23/alpine-packages \
ALPINE_REPOSITORY_URL=https://code.factoring.digital/api/packages/public/alpine/v3.24/alpine-packages \
ALPINE_REPOSITORY_KEY_URL=https://code.factoring.digital/api/packages/public/alpine/key \
mise run apk:test-install
```
The full build can take close to an hour. Do not run it as part of lightweight
metadata or script checks.
Full builds take close to an hour.
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail
apk add greptimedb \
greptimedb-datanode-openrc \
greptimedb-docs \
greptimedb-flownode-openrc \
greptimedb-frontend-openrc \
greptimedb-metasrv-openrc \
greptimedb-standalone-openrc
test -x /usr/bin/greptime
test -d /etc/greptimedb
test -f /etc/greptimedb/standalone.toml
test -f /etc/conf.d/greptimedb.standalone
test -f /etc/init.d/greptimedb.standalone
test -f /usr/share/doc/greptimedb/config/config.md
test -f /usr/share/doc/greptimedb/config/standalone.example.toml
greptime --version
rc-update add greptimedb.standalone default || true
test -L /etc/runlevels/default/greptimedb.standalone
@@ -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.23}"
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
@@ -56,6 +23,7 @@ docker run --rm --platform "${platform}" \
apk add \
"${PACKAGE_NAME}" \
"${PACKAGE_NAME}-datanode-openrc" \
"${PACKAGE_NAME}-docs" \
"${PACKAGE_NAME}-flownode-openrc" \
"${PACKAGE_NAME}-frontend-openrc" \
"${PACKAGE_NAME}-metasrv-openrc" \
@@ -64,5 +32,7 @@ docker run --rm --platform "${platform}" \
test -x /usr/bin/greptime
greptime --version
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"
find /etc/init.d -maxdepth 1 -name "greptimedb.*" -print | sort
'
SCRIPT
@@ -0,0 +1,3 @@
provider=github
repo=GreptimeTeam/greptimedb
version_prefix=v
+74
View File
@@ -0,0 +1,74 @@
# Maintainer: Joachim Schlöffel <joachim.schloeffel@financial-service-plus.de>
pkgname=lavinmq
pkgver=2.9.1
pkgrel=2
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
gc-dev
help2man
libevent-dev
lz4-dev
make
openssl
openssl-dev
pcre2-dev
shards
tar
yaml-dev
"
install="$pkgname.pre-install"
pkgusers="lavinmq"
pkggroups="lavinmq"
subpackages="
$pkgname-doc
$pkgname-openrc:_openrc:noarch
"
options="net"
source="
$pkgname-$pkgver.tar.gz::https://github.com/cloudamqp/lavinmq/archive/refs/tags/v$pkgver.tar.gz
lavinmq.confd
lavinmq.initd
"
export CRYSTAL_CACHE_DIR="${CRYSTAL_CACHE_DIR:-$srcdir/crystal-cache}"
export SHARDS_CACHE_PATH="${SHARDS_CACHE_PATH:-$srcdir/shards-cache}"
build() {
make
make man
}
check() {
bin/lavinmq -v
bin/lavinmqctl --version
bin/lavinmqperf --version
}
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() {
pkgdesc="$pkgdesc (OpenRC service)"
depends="$pkgname=$pkgver-r$pkgrel openrc"
install -Dm755 "$srcdir"/lavinmq.initd \
"$subpkgdir"/etc/init.d/lavinmq
install -Dm644 "$srcdir"/lavinmq.confd \
"$subpkgdir"/etc/conf.d/lavinmq
}
sha512sums="
5f88de7a1e093b1f6e2ead5c340140bd489a99ca8adfa9f40052148490d0bdf8ff1e2dad67727e9799ad1f942755df01525e63d24b0901684a743f43c42110b9 lavinmq-2.9.1.tar.gz
62a609d50f28db960098c4c84ce4f1dad78413366a9a9aca18fe321114d687be3bf7b71924d4ace69bd74383c5ac40d2ee09ae0eef9c1bfe653b97448e42e110 lavinmq.confd
1853196e70297b5c4a2207fde50df735620cf6d99c4994644fd676bffaf863d67300ad7ae771c4bbb86fce1a0485c2a7968cf912c5f5bb878e08b15e5a28ba1b lavinmq.initd
"
+72
View File
@@ -0,0 +1,72 @@
# LavinMQ Alpine Package
Builds LavinMQ from the upstream source release for `x86_64` and packages the
OpenRC service plus `/etc/lavinmq` defaults.
Build command:
```sh
make
```
LavinMQ 2.9.1 requires Crystal 1.20.1 or newer, so build with Alpine 3.24 or
newer.
## Runtime Layout
Installs:
- `lavinmq`
- `lavinmqctl`
- `lavinmqperf`
- `/etc/lavinmq/lavinmq.ini`
- `/var/lib/lavinmq`
Default ports:
- `5672`: AMQP
- `15672`: management UI
## OpenRC Usage
```sh
apk add lavinmq lavinmq-doc lavinmq-openrc
rc-update add lavinmq default
rc-service lavinmq start
```
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
## Package Commands
Refresh checksums:
```sh
ALPINE_PACKAGE=lavinmq mise run apk:checksum
```
Build:
```sh
ALPINE_PACKAGE=lavinmq mise run apk:build
```
Install-test local build:
```sh
ALPINE_PACKAGE=lavinmq SKIP_BUILD=1 mise run apk:test-install
```
Install-test published repository:
```sh
ALPINE_PACKAGE=lavinmq \
SKIP_BUILD=1 \
ALPINE_REPOSITORY_URL=https://code.factoring.digital/api/packages/public/alpine/v3.24/alpine-packages \
ALPINE_REPOSITORY_KEY_URL=https://code.factoring.digital/api/packages/public/alpine/key \
mise run apk:test-install
```
@@ -0,0 +1,4 @@
# Defaults for LavinMQ.
LAVINMQ_CONFIG="/etc/lavinmq/lavinmq.ini"
LAVINMQ_DATA_DIR="/var/lib/lavinmq"
LAVINMQ_OPTS=""
+28
View File
@@ -0,0 +1,28 @@
#!/sbin/openrc-run
description="LavinMQ message queue service"
command="/usr/bin/lavinmq"
command_user="${LAVINMQ_USER:-lavinmq}:${LAVINMQ_GROUP:-lavinmq}"
command_background="yes"
pidfile="/run/lavinmq/lavinmq.pid"
output_log="${LAVINMQ_LOG:-/var/log/lavinmq/lavinmq.log}"
error_log="${LAVINMQ_ERRLOG:-/var/log/lavinmq/lavinmq.log}"
config_file="${LAVINMQ_CONFIG:-/etc/lavinmq/lavinmq.ini}"
data_dir="${LAVINMQ_DATA_DIR:-/var/lib/lavinmq}"
command_args="-D ${data_dir} --config ${config_file} ${LAVINMQ_OPTS:-}"
depend() {
need net
}
start_pre() {
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 "$service_owner" "$data_dir"
checkpath -f -m 0640 -o "$service_owner" "$data_dir"/.lock
}
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
addgroup -S lavinmq 2>/dev/null
adduser -S -D -H -h /var/lib/lavinmq -s /sbin/nologin \
-G lavinmq -g lavinmq lavinmq 2>/dev/null
exit 0
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
apk add lavinmq lavinmq-doc lavinmq-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 /usr/share/doc/lavinmq/README.md
lavinmq -v
lavinmqctl --version
lavinmqperf --version
rc-update add lavinmq default || true
test -L /etc/runlevels/default/lavinmq
+42
View File
@@ -0,0 +1,42 @@
#!/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:-lavinmq}" "${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}" "${PACKAGE_NAME}-doc" "${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 /usr/share/doc/lavinmq/README.md
test -f /usr/share/doc/lavinmq/changelog
lavinmq -v
lavinmqctl --version
lavinmqperf --version
rc-update add lavinmq default
test -L /etc/runlevels/default/lavinmq
SCRIPT
@@ -0,0 +1,3 @@
provider=github
repo=cloudamqp/lavinmq
version_prefix=v
+7 -7
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=seaweedfs
pkgver=4.31
pkgrel=3
pkgver=4.41
pkgrel=0
pkgdesc="Distributed storage system for object storage, file systems, and Iceberg tables"
url="https://github.com/seaweedfs/seaweedfs"
arch="x86_64 aarch64"
@@ -109,15 +109,15 @@ _bashcomp() {
}
sha512sums="
60c758d6d565d0cbc533e4e5677186a4700d48be12ebbd2bd1c6b4bcf38f687d0ab1f66e0953c8a27c663549cdbae73e5fd7eda74bb422c20e10e0d0850b5ead seaweedfs-4.31-linux-amd64.tar.gz
93c7539fe15a0aa6192d26ac2360003961f0643e302d910179d02341b10a7243df776294fb1b0134ec2a2a9596b1abc3ce9ab701f9bc3d78f2b965ea464a4b18 seaweedfs-4.31-linux-arm64.tar.gz
51810779863e7b5578ef1a236af137f2ef79e44b7d8f10b5b36f6d45fa002ae8c6ad92f18e7fefdff8f7a4ec5c29acea13d757faf74e26f0a2e3914680a03092 seaweedfs-4.41-linux-amd64.tar.gz
20b7504c2efcfaab86e92ad336715f80e3653dc833e20c56f7cde545b57488374648d5155e47b4faaa95df92311a0675d368baa01e75a717c788a304655b29c7 seaweedfs-4.41-linux-arm64.tar.gz
b6ce09d6d83dd70e2797a185171eea3587436fb024a99b4998f714b713244d6f768ef59f67c9b7251650d4f19d414eea231eab92099763d85cd92e41cb2bdc3f credential.toml
7105de7053654b8c0502521ce58585915fc831c3152801e1db02b1c5214dc3c3ed31f4fc18000665d8338c7a10ffbf0d248368bef2ef3a6d37d46cd856398366 example-credential.toml
6213e9cff227d66a7a04237d15e2f77904f1bcdf5709fd985c1e12fe4aca0d0327db6997d567303eff47dabec3650db2a6d874b03adda41b239e04ee0c3557ee example-filer.toml
9e6401387698832cb4aae0876ef3e237c9b70af17db7563ed641ba40c81af99f1d6c22281bafa64fff7ee8d2c89f16ccac1322ea31c9a02b545faa4e09f08549 example-filer.toml
e5753bd0bcc60dc84428c40ba556c08acae61dec083a5b76640125f637532e7c5759a72cdfd95114222a7a0901a916ec3c4d12f306853cfca0fe9a0b1857893e example-master.toml
2c200c28172a5d0b1c80ab28e849287e7af8d103355638fd3183b8614d3e2b1b3482132522663f7c6d844e10e13b8c6e23fb5fba0dec2cc83de45c2f17b33477 example-notification.toml
4b507540d57799e42ec0ee84073c6fa32c577a2f4a98bf66ee7302355080c63c65d70709115185debdee3c957e9294e79a8e461347d7148af7fdd368dc548af6 example-replication.toml
a0f307bc73b1aa03653c42c22a1fc704640cbd86957a417f947fe33356e03734c33782777cb1d6cb17360fc6b3930ffbe1386f89123e9dc3c21468210418aae2 example-security.toml
6951e1110d458238b0ef1905c4c6bb874d06f1c18b83dd8e1742534806b8db68b4410a664bf53085781e5d4d35e87941279d9c7398529ee707bb99def5055591 example-security.toml
70069f97edf261a2cd0669dd60adad80533609a25d7429254e0c3322d7e80337f5ff69a5581bc39e6a15442098d14d610ce5f0cb14f02c461c8d3dd440b22c56 example-shell.toml
be5771a5e1bf626c53f9dffbfa2a400d9b8f9626d55a7b61dcd853753561989427ba872a2638a5e6343f44dea6790678483bd29101d6495dbbfcd3029947b9a7 filer.toml
2cd6c73a5e23e0395b6f099dcc3acf9280cbb3e13f54408571e91741c4e6b0dad85f6d4e5a92f23ad541bad57ce295c28bb8450fe11da35acbd4da25848f61e5 master.toml
+131
View File
@@ -0,0 +1,131 @@
# SeaweedFS Alpine Package
Repackages official SeaweedFS 4.39 Linux release tarballs for `x86_64` and
`aarch64`.
## Package Commands
Refresh generated sources:
```sh
ALPINE_PACKAGE=seaweedfs mise run apk:update-generated
ALPINE_PACKAGE=seaweedfs mise run apk:checksum
```
Build:
```sh
ALPINE_PACKAGE=seaweedfs mise run apk:build
```
Install-test local build:
```sh
ALPINE_PACKAGE=seaweedfs SKIP_BUILD=1 mise run apk:test-install
```
## Install Node Roles
Single-node install:
```sh
apk add seaweedfs \
seaweedfs-master-openrc \
seaweedfs-volume-openrc \
seaweedfs-filer-openrc
```
Role-specific installs:
```sh
apk add seaweedfs seaweedfs-master-openrc
apk add seaweedfs seaweedfs-volume-openrc
apk add seaweedfs seaweedfs-filer-openrc
```
Available OpenRC role packages:
```text
seaweedfs-master-openrc -> /etc/init.d/seaweedfs.master
seaweedfs-volume-openrc -> /etc/init.d/seaweedfs.volume
seaweedfs-filer-openrc -> /etc/init.d/seaweedfs.filer
seaweedfs-s3-openrc -> /etc/init.d/seaweedfs.s3
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
```
Replace Alpine's old generic OpenRC package before installing a role split:
```sh
apk del seaweedfs-openrc
apk add seaweedfs seaweedfs-master-openrc
```
## Configure Services
Runtime paths:
```text
/usr/bin/weed
/etc/seaweedfs/*.toml
/etc/conf.d/seaweedfs.*
/etc/init.d/seaweedfs.*
```
Edit `/etc/conf.d/seaweedfs.<role>` for flags and `/etc/seaweedfs/*.toml` for
SeaweedFS config. Upstream examples:
```text
/usr/share/doc/seaweedfs/examples/
```
Enable services:
```sh
rc-update add seaweedfs.master default
rc-service seaweedfs.master start
rc-update add seaweedfs.volume default
rc-service seaweedfs.volume start
rc-update add seaweedfs.filer default
rc-service seaweedfs.filer start
```
Check status:
```sh
weed version
rc-service seaweedfs.master status
```
## Optional Packages
Docs and examples:
```sh
apk add seaweedfs-doc
```
Bash completion:
```sh
apk add bash-completion seaweedfs-bash-completion
```
## Upgrade Or Pin
Upgrade:
```sh
apk upgrade seaweedfs
rc-service seaweedfs.master restart
```
Pin:
```sh
apk add seaweedfs=4.39-r0
```
@@ -366,6 +366,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
@@ -4,7 +4,16 @@
# /etc/seaweedfs/security.toml
# this file is read by master, volume server, filer, and worker
# comma separated origins allowed to make requests to the filer and s3 gateway.
# 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]
values = "*"
+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail
apk add seaweedfs \
seaweedfs-doc \
bash-completion \
seaweedfs-master-openrc \
seaweedfs-volume-openrc \
seaweedfs-filer-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/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 -d /usr/share/doc/seaweedfs/examples
test -f /usr/share/doc/seaweedfs/examples/master.toml
test -f /usr/share/bash-completion/completions/weed
weed version
rc-update add seaweedfs.master default || true
rc-update add seaweedfs.volume default || true
rc-update add seaweedfs.filer default || true
rc-service seaweedfs.master start
rc-service seaweedfs.volume start
rc-service seaweedfs.filer start
rc-service seaweedfs.master status
rc-service seaweedfs.volume status
rc-service seaweedfs.filer 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.23}"
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/
@@ -70,4 +42,4 @@ docker run --rm --platform "${platform}" \
test -d /usr/share/doc/seaweedfs/examples
test -f /usr/share/doc/seaweedfs/examples/master.toml
test -f /usr/share/bash-completion/completions/weed
'
SCRIPT
@@ -1,15 +1,41 @@
#!/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)
pkgver="$(
awk -F= '$1 == "pkgver" { print $2; exit }' "${package_dir}/APKBUILD"
)"
tmpdir="$(mktemp -d)"
cleanup() {
rm -rf "${tmpdir}"
}
trap cleanup EXIT
case "$(uname -m)" in
x86_64)
archive="linux_amd64.tar.gz"
;;
aarch64|arm64)
archive="linux_arm64.tar.gz"
;;
*)
printf 'unsupported host architecture for SeaweedFS generated sources: %s\n' "$(uname -m)" >&2
exit 2
;;
esac
curl -fsSL \
-o "${tmpdir}/${archive}" \
"https://github.com/seaweedfs/seaweedfs/releases/download/${pkgver}/${archive}"
tar -xzf "${tmpdir}/${archive}" -C "${tmpdir}" 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"
@@ -0,0 +1,3 @@
provider=github
repo=seaweedfs/seaweedfs
version_prefix=none
+1 -1
View File
@@ -1,4 +1,4 @@
ARG ALPINE_VERSION=3.23
ARG ALPINE_VERSION=3.24
FROM alpine:${ALPINE_VERSION}
ARG BUILDER_UID=1000
+26 -13
View File
@@ -6,7 +6,7 @@ requested_arch="${2:-${ALPINE_ARCH:-x86_64}}"
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
. "${repo_root}/scripts/apk/package-lib.sh"
alpine_version="${ALPINE_VERSION:-3.23}"
alpine_version="${ALPINE_VERSION:-3.24}"
repo_name="${ALPINE_REPO_NAME:-local}"
build_platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
builder_uid="$(id -u)"
@@ -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
+19 -4
View File
@@ -2,12 +2,19 @@
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}"
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
@@ -24,6 +31,15 @@ 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"
@@ -37,6 +53,7 @@ if ! compgen -G "${HOME}/.abuild/*.rsa" > /dev/null; then
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 +72,8 @@ while IFS= read -r package_dir; do
printf 'Building %s for %s\n' "$(basename "${package_dir}")" "${arch}"
(
export ALPINE_ARCH="${arch}"
export CARCH="${arch}"
cd "${package_dir}"
abuild -r
ALPINE_ARCH="${arch}" CARCH="${arch}" abuild -r
)
mkdir -p "${REPODEST}/${repo_name}/${arch}"
+249
View File
@@ -0,0 +1,249 @@
#!/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}"
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
cache_root="${ALPINE_APK_REPO_CACHE:-/cache/public-alpine-packages/${ALPINE_REGISTRY_BRANCH:-local}/apk-repo}"
repo_dest="${repo_root}/packages/${repo_name}"
command_name="${1:-prepare}"
all_packages() {
while IFS= read -r package_dir; do
apk_package_name "${package_dir}"
done < <(apk_all_package_dirs "${repo_root}")
}
mark_all_packages() {
local reason="$1"
printf 'Rebuilding all packages: %s\n' "${reason}" >&2
all_packages
}
diff_base() {
local before="${GITHUB_EVENT_BEFORE:-${CI_COMMIT_BEFORE_SHA:-}}"
local base_ref="${GITHUB_BASE_REF:-}"
if [[ -n "${base_ref}" ]] && git rev-parse --verify "origin/${base_ref}" >/dev/null 2>&1; then
printf '%s...HEAD\n' "origin/${base_ref}"
return
fi
if [[ -n "${before}" && ! "${before}" =~ ^0+$ ]] && git rev-parse --verify "${before}^{commit}" >/dev/null 2>&1; then
printf '%s..HEAD\n' "${before}"
return
fi
if git rev-parse --verify "HEAD^" >/dev/null 2>&1; then
printf 'HEAD^..HEAD\n'
return
fi
return 1
}
changed_packages() {
local base
local changed_paths
local changed_path
local package
declare -A selected=()
if ! base="$(diff_base)"; then
mark_all_packages "no usable git diff base"
return
fi
if ! changed_paths="$(git diff --name-only "${base}")"; then
mark_all_packages "git diff failed for ${base}"
return
fi
while IFS= read -r changed_path; do
[[ -n "${changed_path}" ]] || continue
case "${changed_path}" in
scripts/apk/*|.gitea/workflows/build.yml|mise.toml)
mark_all_packages "shared build logic changed"
return
;;
packaging/alpine/local/*)
package="${changed_path#packaging/alpine/local/}"
package="${package%%/*}"
selected["${package}"]=1
;;
esac
done <<< "${changed_paths}"
for package in "${!selected[@]}"; do
printf '%s\n' "${package}"
done | sort
}
restore_cache() {
if [[ -d "${cache_root}" ]]; then
mkdir -p "${repo_dest}"
cp -a "${cache_root}/." "${repo_dest}/"
printf 'Restored Alpine package repository cache from %s\n' "${cache_root}"
else
printf 'No Alpine package repository cache found at %s\n' "${cache_root}"
fi
}
package_apk_names() {
local package_dir="$1"
local arch="$2"
apk_package_apk_names "${package_dir}" "${arch}"
}
package_cache_complete() {
local package_dir="$1"
local package_name
local arch
local apk_name
package_name="$(apk_package_name "${package_dir}")"
for arch in ${arches}; do
case "${arch}" in
x86_64|aarch64) ;;
*) printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2; exit 2 ;;
esac
if ! apk_package_supports_arch "${package_dir}" "${arch}"; then
continue
fi
while IFS= read -r apk_name; do
if [[ ! -f "${repo_dest}/${arch}/${apk_name}" ]]; then
printf 'Cache miss for %s: missing %s/%s\n' "${package_name}" "${arch}" "${apk_name}" >&2
return 1
fi
done < <(package_apk_names "${package_dir}" "${arch}")
done
return 0
}
select_missing_packages() {
local package_dir
local package_name
while IFS= read -r package_dir; do
apk_validate_package_dir "${package_dir}"
package_name="$(apk_package_name "${package_dir}")"
if ! package_cache_complete "${package_dir}"; then
printf '%s\n' "${package_name}"
fi
done < <(apk_all_package_dirs "${repo_root}")
}
prune_stale_apks() {
local package_dir
local arch
local apk_name
local current_apk
declare -A expected_apks=()
if [[ ! -d "${repo_dest}" ]]; then
return
fi
while IFS= read -r package_dir; do
apk_validate_package_dir "${package_dir}"
for arch in ${arches}; do
case "${arch}" in
x86_64|aarch64) ;;
*) printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2; exit 2 ;;
esac
if ! apk_package_supports_arch "${package_dir}" "${arch}"; then
continue
fi
while IFS= read -r apk_name; do
expected_apks["${repo_dest}/${arch}/${apk_name}"]=1
done < <(package_apk_names "${package_dir}" "${arch}")
done
done < <(apk_all_package_dirs "${repo_root}")
shopt -s nullglob
for current_apk in "${repo_dest}"/*/*.apk; do
if [[ -z "${expected_apks[${current_apk}]:-}" ]]; then
rm -f "${current_apk}"
printf 'Pruned stale cached APK: %s\n' "${current_apk#"${repo_root}/"}"
fi
done
shopt -u nullglob
}
prepare() {
local selected_packages
local selected
declare -A selected_map=()
restore_cache
prune_stale_apks
while IFS= read -r selected; do
[[ -n "${selected}" ]] || continue
selected_map["${selected}"]=1
done < <(changed_packages)
while IFS= read -r selected; do
[[ -n "${selected}" ]] || continue
selected_map["${selected}"]=1
done < <(select_missing_packages)
selected_packages="$(
for selected in "${!selected_map[@]}"; do
printf '%s\n' "${selected}"
done | sort | xargs
)"
if [[ -n "${selected_packages}" ]]; then
printf 'Selected packages for rebuild: %s\n' "${selected_packages}"
export ALPINE_PACKAGES="${selected_packages}"
export ALPINE_SKIP_BUILD=0
else
printf 'No packages selected for rebuild\n'
export ALPINE_PACKAGES=""
export ALPINE_SKIP_BUILD=1
fi
if [[ -n "${GITHUB_ENV:-}" ]]; then
{
printf 'ALPINE_PACKAGES=%s\n' "${ALPINE_PACKAGES}"
printf 'ALPINE_SKIP_BUILD=%s\n' "${ALPINE_SKIP_BUILD}"
} >> "${GITHUB_ENV}"
fi
}
sync_cache() {
if [[ ! -d "${repo_dest}" ]]; then
printf 'missing package repository: %s\n' "${repo_dest}" >&2
exit 1
fi
prune_stale_apks
mkdir -p "${cache_root}"
rsync -a --delete "${repo_dest}/" "${cache_root}/"
printf 'Updated Alpine package repository cache at %s\n' "${cache_root}"
}
case "${command_name}" in
prepare)
prepare
;;
sync)
sync_cache
;;
*)
printf 'usage: %s [prepare|sync]\n' "$0" >&2
exit 2
;;
esac
+21 -3
View File
@@ -4,7 +4,7 @@ set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
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}"
packages="${SMOKE_PACKAGES:-seaweedfs seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc greptimedb lavinmq lavinmq-openrc gitea gitea-openrc}"
repo_dir="${repo_root}/packages/${repo_name}/${arch}"
read -r -a package_list <<< "${packages}"
@@ -17,11 +17,29 @@ cp "${repo_dir}"/*.rsa.pub /etc/apk/keys/
echo "${repo_root}/packages/${repo_name}" >> /etc/apk/repositories
apk update
apk add "${package_list[@]}"
weed version
if command -v weed >/dev/null 2>&1; then
weed version
ls -1 /etc/seaweedfs
fi
if command -v greptime >/dev/null 2>&1; then
greptime --version
fi
ls -1 /etc/seaweedfs
if command -v lavinmq >/dev/null 2>&1; then
lavinmq -v
lavinmqctl --version
lavinmqperf --version
fi
if command -v gitea >/dev/null 2>&1; then
gitea --version
test -f /etc/gitea/app.ini
test -d /var/lib/gitea
fi
if ls /etc/init.d/seaweedfs.* >/dev/null 2>&1; then
find /etc/init.d -maxdepth 1 -name 'seaweedfs.*' -print | sort
fi
if [[ -f /etc/init.d/lavinmq ]]; then
printf '%s\n' /etc/init.d/lavinmq
fi
if [[ -f /etc/init.d/gitea ]]; then
printf '%s\n' /etc/init.d/gitea
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'
+144
View File
@@ -0,0 +1,144 @@
#!/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 api_url="https://api.github.com/repos/${repo}/releases/latest"
local response
response="$(curl -fsSL \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
"${api_url}" 2>/dev/null)" || return 1
printf '%s\n' "${response}" \
| sed -n 's/^[[:space:]]*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/p' \
| head -n 1
}
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
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
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 [[ "${mode}" == "fail" && ( "${has_update}" -ne 0 || "${has_unknown}" -ne 0 ) ]]; then
exit 1
fi
+32
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,30 @@ 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
export 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_container_package_dir() {
local repo_root="$1"
local package_dir="$2"
+2
View File
@@ -4,7 +4,9 @@ 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
+39 -2
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.23}"
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,9 +50,42 @@ if [[ "${#apks[@]}" -eq 0 ]]; then
exit 1
fi
printf 'Publishing %d APK files to %s\n' "${#apks[@]}" "${upload_url}"
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
if [[ -z "${expected_apks[${apk}]:-}" ]]; then
printf 'Skipping stale local APK: %s\n' "${apk#"${repo_root}/"}"
stale_count=$((stale_count + 1))
continue
fi
current_apks+=("${apk}")
done
if [[ "${#current_apks[@]}" -eq 0 ]]; then
printf 'no current APK files found under %s\n' "${package_root}" >&2
exit 1
fi
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
+149
View File
@@ -0,0 +1,149 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
. "${repo_root}/scripts/apk/package-lib.sh"
alpine_version="${ALPINE_VERSION:-3.24}"
repo_name="${ALPINE_REPO_NAME:-local}"
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
printf 'missing local repository: packages/%s/%s\n' "${repo_name}" "${arch}" >&2
printf 'run: ALPINE_ARCH=%s mise run apk:build\n' "${arch}" >&2
exit 1
fi
shopt -s nullglob
repo_keys=("${repo_dir}"/*.rsa.pub)
repo_indexes=("${repo_dir}"/APKINDEX.tar.gz)
shopt -u nullglob
if [[ "${#repo_keys[@]}" -eq 0 ]]; then
printf 'missing repository key: packages/%s/%s/*.rsa.pub\n' "${repo_name}" "${arch}" >&2
exit 1
fi
if [[ "${#repo_indexes[@]}" -eq 0 ]]; then
printf 'missing repository index: packages/%s/%s/APKINDEX.tar.gz\n' "${repo_name}" "${arch}" >&2
exit 1
fi
}
in_alpine() {
[[ -f /etc/alpine-release ]] && command -v apk >/dev/null 2>&1
}
prepare_direct_runtime() {
apk add --no-cache bash openrc >/dev/null
cp "${repo_dir}"/*.rsa.pub /etc/apk/keys/
printf '%s\n' "${repo_root}/packages/${repo_name}" >> /etc/apk/repositories
apk update
mkdir -p /run/openrc
touch /run/openrc/softlevel
}
run_hook_direct() {
local hook_path="$1"
local package_dir="$2"
local package_name="$3"
PACKAGE_DIR="${package_dir}" \
PACKAGE_NAME="${package_name}" \
"${hook_path}"
}
run_hook_docker() {
local package_dir_rel="$1"
docker run --rm --privileged --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "ALPINE_REPO_NAME=${repo_name}" \
-e "PACKAGE_DIR=/work/${package_dir_rel}" \
-e "PACKAGE_NAME=${package_name}" \
-v "${repo_root}:/work:ro" \
-v "${repo_root}/packages/${repo_name}:/repo:ro" \
"${runtime_image}" \
sh -lc '
set -e
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories
apk update
mkdir -p /run/openrc
touch /run/openrc/softlevel
exec /bin/bash "${PACKAGE_DIR}/scripts/runtime-test.sh"
'
}
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
auto)
if in_alpine; then
runtime_mode="direct"
else
runtime_mode="docker"
fi
;;
direct|docker) ;;
*)
printf 'unsupported ALPINE_RUNTIME_TEST_MODE: %s\n' "${runtime_mode}" >&2
printf 'expected: auto, direct, or docker\n' >&2
exit 2
;;
esac
if [[ "${runtime_mode}" == "direct" ]]; then
prepare_direct_runtime
else
build_runtime_image
fi
while IFS= read -r package_dir; do
apk_validate_package_dir "${package_dir}"
package_name="$(apk_package_name "${package_dir}")"
hook_path="${package_dir}/scripts/runtime-test.sh"
if [[ ! -e "${hook_path}" ]]; then
printf 'Skipping %s: no runtime-test hook\n' "${package_name}"
continue
fi
if [[ ! -x "${hook_path}" ]]; then
printf 'package hook is not executable: %s\n' "${hook_path}" >&2
exit 1
fi
if ! apk_package_supports_arch "${package_dir}" "${arch}"; then
printf 'Skipping %s: unsupported arch %s\n' "${package_name}" "${arch}"
continue
fi
case "${package_dir}" in
"${repo_root}"/*)
package_dir_rel="${package_dir#"${repo_root}/"}"
;;
*)
printf 'package directory must be inside repository: %s\n' "${package_dir}" >&2
exit 1
;;
esac
printf 'Running runtime-test hook for %s\n' "${package_name}"
if [[ "${runtime_mode}" == "direct" ]]; then
run_hook_direct "${hook_path}" "${package_dir}" "${package_name}"
else
run_hook_docker "${package_dir_rel}"
fi
done < <(apk_package_dirs "${repo_root}")
+25 -4
View File
@@ -2,10 +2,10 @@
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
alpine_version="${ALPINE_VERSION:-3.23}"
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}"
packages="${SMOKE_PACKAGES:-seaweedfs seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc greptimedb lavinmq lavinmq-openrc gitea gitea-openrc}"
if [[ ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
@@ -22,9 +22,30 @@ docker run --rm --platform "${platform}" \
echo /repo >> /etc/apk/repositories
apk update >/dev/null
apk add ${packages} >/dev/null
weed version
ls -1 /etc/seaweedfs
if command -v weed >/dev/null 2>&1; then
weed version
ls -1 /etc/seaweedfs
fi
if command -v greptime >/dev/null 2>&1; then
greptime --version
fi
if command -v lavinmq >/dev/null 2>&1; then
lavinmq -v
lavinmqctl --version
lavinmqperf --version
fi
if command -v gitea >/dev/null 2>&1; then
gitea --version
test -f /etc/gitea/app.ini
test -d /var/lib/gitea
fi
if ls /etc/init.d/seaweedfs.* >/dev/null 2>&1; then
ls -1 /etc/init.d/seaweedfs.* | sort
fi
if [ -f /etc/init.d/lavinmq ]; then
ls -1 /etc/init.d/lavinmq
fi
if [ -f /etc/init.d/gitea ]; then
ls -1 /etc/init.d/gitea
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 -14
View File
@@ -2,11 +2,11 @@
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
alpine_version="${ALPINE_VERSION:-3.23}"
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}"
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,15 +60,25 @@ 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 SeaweedFS packages:\n"
apk info -e seaweedfs seaweedfs-doc seaweedfs-bash-completion \
seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc \
| sort
printf "\nSeaweedFS version:\n"
weed version
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
Entering ${TEST_SHELL}.
EOF
exec "${TEST_SHELL}"
'