Add multi-package Alpine packaging
This commit is contained in:
432
README.md
432
README.md
@@ -1,26 +1,222 @@
|
||||
# SeaweedFS Alpine Package
|
||||
# Alpine Packages
|
||||
|
||||
Local Alpine 3.23 packaging for SeaweedFS `4.31`. The workflow runs Alpine tooling
|
||||
inside Docker and writes signed packages under `packages/local/<arch>/`.
|
||||
Alpine 3.23 packaging for internal packages.
|
||||
|
||||
## Commands
|
||||
This repository builds signed `x86_64` and `aarch64` APKs and publishes them to
|
||||
the Gitea Alpine package registry under:
|
||||
|
||||
```text
|
||||
https://code.factoring.digital/api/packages/fsp-ops/alpine/v3.23/seaweedfs-alpine
|
||||
```
|
||||
|
||||
## Use In Production
|
||||
|
||||
### Add The Package Repository
|
||||
|
||||
Install the registry signing key on each Alpine node:
|
||||
|
||||
```sh
|
||||
curl -fsSLo /etc/apk/keys/fsp-ops-alpine.rsa.pub \
|
||||
https://code.factoring.digital/api/packages/fsp-ops/alpine/key
|
||||
```
|
||||
|
||||
Add the package repository:
|
||||
|
||||
```sh
|
||||
printf '%s\n' \
|
||||
'https://code.factoring.digital/api/packages/fsp-ops/alpine/v3.23/seaweedfs-alpine' \
|
||||
>> /etc/apk/repositories
|
||||
|
||||
apk update
|
||||
```
|
||||
|
||||
If the registry is private, include a Gitea user and package token in the
|
||||
repository URL:
|
||||
|
||||
```text
|
||||
https://<user>:<token>@code.factoring.digital/api/packages/fsp-ops/alpine/v3.23/seaweedfs-alpine
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
### Package Layout
|
||||
|
||||
Package sources live under:
|
||||
|
||||
```text
|
||||
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
|
||||
packages/local/<arch>/
|
||||
```
|
||||
|
||||
Signing keys and distfiles are cached under:
|
||||
|
||||
```text
|
||||
.cache/abuild/
|
||||
.cache/apk-distfiles/
|
||||
```
|
||||
|
||||
### Build Commands
|
||||
|
||||
```sh
|
||||
mise run apk:lint
|
||||
mise run apk:build
|
||||
mise run apk:build-all
|
||||
mise run apk:build-x86_64
|
||||
mise run apk:build-aarch64
|
||||
mise run apk:update-generated
|
||||
mise run apk:checksum
|
||||
mise run apk:lint
|
||||
mise run apk:packages
|
||||
mise run apk:smoke
|
||||
mise run apk:test-install
|
||||
mise run apk:test-shell
|
||||
mise run apk:publish-check
|
||||
mise run apk:publish-gitea
|
||||
mise run gitea-workflow-build
|
||||
mise run apk:shell
|
||||
mise run apk:clean
|
||||
```
|
||||
|
||||
`apk:build` targets `x86_64` by default. Multi-arch builds target `x86_64` and
|
||||
@@ -30,116 +226,121 @@ mise run apk:clean
|
||||
ALPINE_ARCHES="x86_64 aarch64" mise run apk:build-all
|
||||
```
|
||||
|
||||
The release binary is also exposed as a mise HTTP tool stub:
|
||||
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`:
|
||||
|
||||
```sh
|
||||
./bin/weed version
|
||||
ALPINE_PACKAGE=seaweedfs mise run apk:build
|
||||
ALPINE_PACKAGES="seaweedfs other-package" mise run apk:build-all
|
||||
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
|
||||
```
|
||||
|
||||
## Package Layout
|
||||
Use the test shell to inspect the package in Alpine with the current build
|
||||
installed:
|
||||
|
||||
```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:
|
||||
|
||||
```sh
|
||||
mise run apk:test-install
|
||||
```
|
||||
|
||||
Use `SKIP_BUILD=1` to reuse existing local packages:
|
||||
|
||||
```sh
|
||||
SKIP_BUILD=1 mise run apk:test-install
|
||||
SKIP_BUILD=1 mise run apk:test-shell
|
||||
```
|
||||
|
||||
### Adding Packages
|
||||
|
||||
Each package lives under:
|
||||
|
||||
```text
|
||||
packaging/alpine/local/<pkgname>/
|
||||
```
|
||||
|
||||
The only required file is `APKBUILD`. Package-specific helpers can be added as
|
||||
hooks:
|
||||
|
||||
```text
|
||||
packaging/alpine/local/<pkgname>/scripts/test-install.sh
|
||||
packaging/alpine/local/<pkgname>/scripts/update-generated-sources.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:
|
||||
|
||||
```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:
|
||||
|
||||
```text
|
||||
packaging/alpine/local/seaweedfs/APKBUILD
|
||||
packaging/alpine/local/seaweedfs/*.toml
|
||||
packaging/alpine/local/seaweedfs/example-*.toml
|
||||
packaging/alpine/local/seaweedfs/weed.bash-completion
|
||||
packaging/alpine/local/seaweedfs/seaweedfs.*.confd
|
||||
packaging/alpine/local/seaweedfs/seaweedfs.initd
|
||||
packages/local/<arch>/
|
||||
```
|
||||
|
||||
The package repackages upstream release tarballs, so builds use
|
||||
`ALPINE_BUILD_PLATFORM=linux/amd64` by default. Signing keys and distfiles are
|
||||
cached in `.cache/abuild/` and `.cache/apk-distfiles/`.
|
||||
|
||||
The Gitea workflow publishes to the Alpine package registry branch `v3.23`.
|
||||
Override `ALPINE_VERSION` and `ALPINE_REGISTRY_BRANCH` if you intentionally
|
||||
build for another Alpine branch, including `edge`.
|
||||
Use `mise run gitea-workflow-build` for a local `pull_request` workflow check
|
||||
through `act`; the publish step is skipped for that event.
|
||||
|
||||
## Test And Publish
|
||||
Refresh generated sources through package-local hooks:
|
||||
|
||||
```sh
|
||||
mise run apk:smoke
|
||||
mise run apk:test-shell
|
||||
mise run apk:publish-check
|
||||
mise run apk:update-generated
|
||||
ALPINE_PACKAGE=seaweedfs mise run apk:update-generated
|
||||
mise run apk:checksum
|
||||
```
|
||||
|
||||
`apk:publish-check` runs APKBUILD linting, rebuilds configured architectures,
|
||||
lists package metadata, and installs the built packages in an Alpine container.
|
||||
`apk:test-shell` builds the selected architecture, installs the local package
|
||||
set in an Alpine container, and opens a shell. Use `SKIP_BUILD=1` to reuse an
|
||||
existing local repository. Set `TEST_SHELL_TIMEOUT` to adjust the timeout for
|
||||
`apk update` and `apk add` inside the test container.
|
||||
Run `apk:checksum` after changing any file listed in `source=`.
|
||||
|
||||
Install from the local repo with the base package plus the role-specific OpenRC
|
||||
subpackage you need:
|
||||
### Gitea Workflow
|
||||
|
||||
```sh
|
||||
apk add seaweedfs seaweedfs-master-openrc
|
||||
```
|
||||
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.
|
||||
|
||||
Optional generated material is split out:
|
||||
|
||||
```sh
|
||||
apk add seaweedfs-doc
|
||||
apk add bash-completion seaweedfs-bash-completion
|
||||
```
|
||||
|
||||
The doc split installs upstream scaffolds under
|
||||
`/usr/share/doc/seaweedfs/examples/`. The bash completion split installs
|
||||
`/usr/share/bash-completion/completions/weed` and is also selected by
|
||||
`install_if` when `seaweedfs` and `bash-completion` are installed together.
|
||||
|
||||
This repository publishes `seaweedfs`, matching Alpine aports. Remove Alpine's
|
||||
old generic OpenRC package before installing a role split:
|
||||
|
||||
```sh
|
||||
apk del seaweedfs-openrc
|
||||
apk add seaweedfs seaweedfs-master-openrc
|
||||
```
|
||||
|
||||
The OpenRC subpackages are:
|
||||
Repository variables:
|
||||
|
||||
```text
|
||||
seaweedfs-master-openrc -> seaweedfs.master
|
||||
seaweedfs-volume-openrc -> seaweedfs.volume
|
||||
seaweedfs-filer-openrc -> seaweedfs.filer
|
||||
seaweedfs-s3-openrc -> seaweedfs.s3
|
||||
seaweedfs-webdav-openrc -> seaweedfs.webdav
|
||||
seaweedfs-sftp-openrc -> seaweedfs.sftp
|
||||
seaweedfs-admin-openrc -> seaweedfs.admin
|
||||
seaweedfs-worker-openrc -> seaweedfs.worker
|
||||
INSTANCE_URL=https://code.factoring.digital
|
||||
PACKAGE_OWNER=fsp-ops
|
||||
PACKAGE_NAME=seaweedfs-alpine
|
||||
```
|
||||
|
||||
Each service has defaults in `/etc/conf.d/seaweedfs.*`. Enable only the roles
|
||||
needed on the node:
|
||||
Repository secrets:
|
||||
|
||||
```text
|
||||
PACKAGE_USER=<gitea package publisher>
|
||||
PACKAGE_TOKEN=<token with package write access>
|
||||
```
|
||||
|
||||
Pre-check the workflow locally with `act`:
|
||||
|
||||
```sh
|
||||
rc-update add seaweedfs.master default
|
||||
rc-service seaweedfs.master start
|
||||
mise run gitea-workflow-build
|
||||
```
|
||||
|
||||
If the repo key is missing on a target system, copy `.cache/abuild/*.rsa.pub`
|
||||
into `/etc/apk/keys/` before `apk update`.
|
||||
|
||||
## Gitea Registry
|
||||
|
||||
The Gitea workflow reads these repository variables and secrets:
|
||||
|
||||
```text
|
||||
Variables: INSTANCE_URL, PACKAGE_OWNER, PACKAGE_NAME
|
||||
Secrets: PACKAGE_USER, PACKAGE_TOKEN
|
||||
```
|
||||
|
||||
It uploads each built `*.apk` with HTTP `PUT` to:
|
||||
|
||||
```text
|
||||
${INSTANCE_URL}/api/packages/${PACKAGE_OWNER}/alpine/v3.23/${PACKAGE_NAME}
|
||||
```
|
||||
|
||||
For local publishing, run:
|
||||
Publish already-built local packages manually:
|
||||
|
||||
```sh
|
||||
INSTANCE_URL=https://code.factoring.digital \
|
||||
@@ -150,21 +351,38 @@ PACKAGE_TOKEN=... \
|
||||
mise run apk:publish-gitea
|
||||
```
|
||||
|
||||
## Alpine Package Dos And Don'ts
|
||||
### Alpine Package Rules
|
||||
|
||||
Do:
|
||||
|
||||
- Keep local `source` files next to the `APKBUILD`.
|
||||
- Keep local package sources next to the `APKBUILD`.
|
||||
- Put full upstream scaffolds in `/usr/share/doc/seaweedfs/examples/`, not active `/etc`.
|
||||
- Run `mise run apk:update-generated` when updating generated examples or completions.
|
||||
- Run `mise run apk:checksum` after changing any package source file.
|
||||
- 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.
|
||||
- Keep installed defaults short and production-neutral.
|
||||
- Run `mise run apk:publish-check` before handing off a repository.
|
||||
- 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 do it.
|
||||
- Bundle long upstream examples as active `/etc` defaults.
|
||||
- Install all OpenRC roles on a node by default.
|
||||
- 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
|
||||
|
||||
Before opening a PR, run:
|
||||
|
||||
```sh
|
||||
mise run apk:publish-check
|
||||
mise run gitea-workflow-build
|
||||
mise run apk:test-install
|
||||
```
|
||||
|
||||
Then test at least one installed role in the package shell:
|
||||
|
||||
```sh
|
||||
mise run apk:test-shell
|
||||
rc-service seaweedfs.master start
|
||||
weed version
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user