Add multi-package Alpine packaging
This commit is contained in:
@@ -36,7 +36,7 @@ jobs:
|
|||||||
- name: Build packages
|
- name: Build packages
|
||||||
run: |
|
run: |
|
||||||
scripts/apk/clean.sh
|
scripts/apk/clean.sh
|
||||||
apkbuild-lint packaging/alpine/local/seaweedfs/APKBUILD
|
find packaging/alpine/local -mindepth 2 -maxdepth 2 -name APKBUILD -exec apkbuild-lint {} +
|
||||||
scripts/apk/ci-build.sh
|
scripts/apk/ci-build.sh
|
||||||
scripts/apk/list-packages.sh
|
scripts/apk/list-packages.sh
|
||||||
|
|
||||||
|
|||||||
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
|
Alpine 3.23 packaging for internal packages.
|
||||||
inside Docker and writes signed packages under `packages/local/<arch>/`.
|
|
||||||
|
|
||||||
## 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
|
```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
|
||||||
mise run apk:build-all
|
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:packages
|
||||||
mise run apk:smoke
|
mise run apk:smoke
|
||||||
|
mise run apk:test-install
|
||||||
mise run apk:test-shell
|
mise run apk:test-shell
|
||||||
mise run apk:publish-check
|
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
|
`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
|
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
|
```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
|
```text
|
||||||
packaging/alpine/local/seaweedfs/APKBUILD
|
|
||||||
packaging/alpine/local/seaweedfs/*.toml
|
|
||||||
packaging/alpine/local/seaweedfs/example-*.toml
|
packaging/alpine/local/seaweedfs/example-*.toml
|
||||||
packaging/alpine/local/seaweedfs/weed.bash-completion
|
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
|
Refresh generated sources through package-local hooks:
|
||||||
`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
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mise run apk:smoke
|
mise run apk:update-generated
|
||||||
mise run apk:test-shell
|
ALPINE_PACKAGE=seaweedfs mise run apk:update-generated
|
||||||
mise run apk:publish-check
|
mise run apk:checksum
|
||||||
```
|
```
|
||||||
|
|
||||||
`apk:publish-check` runs APKBUILD linting, rebuilds configured architectures,
|
Run `apk:checksum` after changing any file listed in `source=`.
|
||||||
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.
|
|
||||||
|
|
||||||
Install from the local repo with the base package plus the role-specific OpenRC
|
### Gitea Workflow
|
||||||
subpackage you need:
|
|
||||||
|
|
||||||
```sh
|
The workflow at `.gitea/workflows/build.yml` builds in an `alpine:3.23`
|
||||||
apk add seaweedfs seaweedfs-master-openrc
|
container and publishes on push or tag. It skips publishing for pull request
|
||||||
```
|
events.
|
||||||
|
|
||||||
Optional generated material is split out:
|
Repository variables:
|
||||||
|
|
||||||
```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:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
seaweedfs-master-openrc -> seaweedfs.master
|
INSTANCE_URL=https://code.factoring.digital
|
||||||
seaweedfs-volume-openrc -> seaweedfs.volume
|
PACKAGE_OWNER=fsp-ops
|
||||||
seaweedfs-filer-openrc -> seaweedfs.filer
|
PACKAGE_NAME=seaweedfs-alpine
|
||||||
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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Each service has defaults in `/etc/conf.d/seaweedfs.*`. Enable only the roles
|
Repository secrets:
|
||||||
needed on the node:
|
|
||||||
|
```text
|
||||||
|
PACKAGE_USER=<gitea package publisher>
|
||||||
|
PACKAGE_TOKEN=<token with package write access>
|
||||||
|
```
|
||||||
|
|
||||||
|
Pre-check the workflow locally with `act`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
rc-update add seaweedfs.master default
|
mise run gitea-workflow-build
|
||||||
rc-service seaweedfs.master start
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If the repo key is missing on a target system, copy `.cache/abuild/*.rsa.pub`
|
Publish already-built local packages manually:
|
||||||
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:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
INSTANCE_URL=https://code.factoring.digital \
|
INSTANCE_URL=https://code.factoring.digital \
|
||||||
@@ -150,21 +351,38 @@ PACKAGE_TOKEN=... \
|
|||||||
mise run apk:publish-gitea
|
mise run apk:publish-gitea
|
||||||
```
|
```
|
||||||
|
|
||||||
## Alpine Package Dos And Don'ts
|
### Alpine Package Rules
|
||||||
|
|
||||||
Do:
|
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`.
|
- 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.
|
- Install only the OpenRC role packages needed on each node.
|
||||||
- Run `mise run apk:checksum` after changing any package source file.
|
- Keep `/etc/conf.d` defaults short and production-neutral.
|
||||||
- Increment `pkgrel` for package-only changes; reset it when `pkgver` changes.
|
- 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 opening a PR.
|
||||||
- Run `mise run apk:publish-check` before handing off a repository.
|
|
||||||
|
|
||||||
Don't:
|
Don't:
|
||||||
|
|
||||||
- Edit generated `src/`, `pkg/`, or `packages/` output.
|
- Edit generated `src/`, `pkg/`, or `packages/` output.
|
||||||
- Hand-edit checksum lines when `abuild checksum` can do it.
|
- Hand-edit checksum lines when `abuild checksum` can update them.
|
||||||
- Bundle long upstream examples as active `/etc` defaults.
|
- Install all OpenRC roles by default.
|
||||||
- Install all OpenRC roles on a node 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
|
||||||
|
```
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ run = "scripts/apk/ci-smoke.sh"
|
|||||||
description = "Open an Alpine shell with the current local package build installed"
|
description = "Open an Alpine shell with the current local package build installed"
|
||||||
run = "scripts/apk/test-shell.sh"
|
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:packages"]
|
[tasks."apk:packages"]
|
||||||
description = "List built Alpine packages and dependencies"
|
description = "List built Alpine packages and dependencies"
|
||||||
run = "scripts/apk/list-packages.sh"
|
run = "scripts/apk/list-packages.sh"
|
||||||
|
|||||||
28
packaging/alpine/blueprint/APKBUILD
Normal file
28
packaging/alpine/blueprint/APKBUILD
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Maintainer: Your Name <you@example.com>
|
||||||
|
pkgname=example-package
|
||||||
|
pkgver=0.1.0
|
||||||
|
pkgrel=0
|
||||||
|
pkgdesc="Short package description"
|
||||||
|
url="https://example.com/example-package"
|
||||||
|
arch="x86_64 aarch64"
|
||||||
|
license="Apache-2.0"
|
||||||
|
depends=""
|
||||||
|
makedepends="build-base"
|
||||||
|
subpackages="$pkgname-doc"
|
||||||
|
source="$pkgname-$pkgver.tar.gz::https://example.com/releases/$pkgver.tar.gz"
|
||||||
|
builddir="$srcdir/$pkgname-$pkgver"
|
||||||
|
|
||||||
|
build() {
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
make check
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
install -Dm755 "$builddir"/example-package "$pkgdir"/usr/bin/example-package
|
||||||
|
}
|
||||||
|
|
||||||
|
sha512sums="
|
||||||
|
"
|
||||||
26
packaging/alpine/blueprint/README.md
Normal file
26
packaging/alpine/blueprint/README.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Alpine Package Blueprint
|
||||||
|
|
||||||
|
Copy this directory to `packaging/alpine/local/<pkgname>/` and replace the
|
||||||
|
placeholder values before building.
|
||||||
|
|
||||||
|
Required:
|
||||||
|
|
||||||
|
- `APKBUILD`
|
||||||
|
|
||||||
|
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=`.
|
||||||
|
|
||||||
|
Repo-level tasks discover packages from `packaging/alpine/local/*/APKBUILD`.
|
||||||
|
Limit a task to one or more packages with:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
For compiled software, put normal Alpine build logic in `build()`, `check()`,
|
||||||
|
and `package()` and declare build tools in `makedepends`.
|
||||||
41
packaging/alpine/blueprint/scripts/test-install.sh
Executable file
41
packaging/alpine/blueprint/scripts/test-install.sh
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
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}"
|
||||||
|
arch="${ALPINE_ARCH:-x86_64}"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
docker run --rm --platform "${platform}" \
|
||||||
|
-e "ALPINE_ARCH=${arch}" \
|
||||||
|
-e "PACKAGE_NAME=${package_name}" \
|
||||||
|
-v "${repo_root}/packages/local:/repo:ro" \
|
||||||
|
"alpine:${alpine_version}" \
|
||||||
|
sh -lc '
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
|
||||||
|
printf "%s\n" /repo >> /etc/apk/repositories
|
||||||
|
apk update
|
||||||
|
apk add "${PACKAGE_NAME}"
|
||||||
|
|
||||||
|
# Replace these with package-specific install assertions.
|
||||||
|
apk info -e "${PACKAGE_NAME}"
|
||||||
|
'
|
||||||
6
packaging/alpine/blueprint/scripts/update-generated-sources.sh
Executable file
6
packaging/alpine/blueprint/scripts/update-generated-sources.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
package_dir="${PACKAGE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
||||||
|
|
||||||
|
printf 'No generated sources for %s\n' "${package_dir}"
|
||||||
57
packaging/alpine/local/greptimedb/APKBUILD
Normal file
57
packaging/alpine/local/greptimedb/APKBUILD
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Maintainer: Joachim Schlöffel <me@joachim-schloeffel.com>
|
||||||
|
pkgname=greptimedb
|
||||||
|
pkgver=1.0.2
|
||||||
|
pkgrel=0
|
||||||
|
pkgdesc="Cloud-native observability database for metrics, logs, and traces"
|
||||||
|
url="https://github.com/GreptimeTeam/greptimedb"
|
||||||
|
arch="x86_64"
|
||||||
|
license="Apache-2.0"
|
||||||
|
depends="ca-certificates"
|
||||||
|
makedepends="
|
||||||
|
binutils
|
||||||
|
cargo
|
||||||
|
clang
|
||||||
|
cmake
|
||||||
|
coreutils
|
||||||
|
lld
|
||||||
|
linux-headers
|
||||||
|
make
|
||||||
|
mold
|
||||||
|
openssl-dev
|
||||||
|
openssl-libs-static
|
||||||
|
perl
|
||||||
|
protobuf
|
||||||
|
protobuf-dev
|
||||||
|
rust
|
||||||
|
zlib-dev
|
||||||
|
zlib-static
|
||||||
|
zstd-dev
|
||||||
|
zstd-static
|
||||||
|
"
|
||||||
|
options="net"
|
||||||
|
source="$pkgname-$pkgver.tar.gz::https://github.com/GreptimeTeam/greptimedb/archive/refs/tags/v$pkgver.tar.gz"
|
||||||
|
|
||||||
|
export CARGO_HOME="$srcdir/cargo"
|
||||||
|
export CARGO_BUILD_JOBS="${CARGO_BUILD_JOBS:-2}"
|
||||||
|
export LIBRARY_PATH="/usr/lib"
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cargo build \
|
||||||
|
--release \
|
||||||
|
--locked \
|
||||||
|
--bin greptime \
|
||||||
|
--features servers/dashboard
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
"$builddir"/target/release/greptime --version
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
install -Dm755 "$builddir"/target/release/greptime \
|
||||||
|
"$pkgdir"/usr/bin/greptime
|
||||||
|
}
|
||||||
|
|
||||||
|
sha512sums="
|
||||||
|
7f4ac722b84a26816030e65d504b37a53edfca15de669a4f6ee7a903f1a29c8358dcc2376a0a6cfd9ded13b0c5d7550a6856b9b10dc8cd080c6b12970553a0ea greptimedb-1.0.2.tar.gz
|
||||||
|
"
|
||||||
77
packaging/alpine/local/greptimedb/Dockerfile
Normal file
77
packaging/alpine/local/greptimedb/Dockerfile
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
# syntax=docker/dockerfile:1.7
|
||||||
|
|
||||||
|
ARG ALPINE_VERSION=3.23
|
||||||
|
ARG RUST_VERSION=1.90.0
|
||||||
|
|
||||||
|
FROM alpine:${ALPINE_VERSION} AS builder
|
||||||
|
|
||||||
|
ARG GREPTIMEDB_REF=main
|
||||||
|
ARG RUST_VERSION
|
||||||
|
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
bash \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
build-base \
|
||||||
|
linux-headers \
|
||||||
|
clang \
|
||||||
|
lld \
|
||||||
|
mold \
|
||||||
|
cmake \
|
||||||
|
make \
|
||||||
|
perl \
|
||||||
|
pkgconf \
|
||||||
|
protobuf \
|
||||||
|
protobuf-dev \
|
||||||
|
zlib-dev \
|
||||||
|
zlib-static \
|
||||||
|
zstd-dev \
|
||||||
|
zstd-static \
|
||||||
|
openssl-dev \
|
||||||
|
openssl-libs-static \
|
||||||
|
binutils \
|
||||||
|
coreutils
|
||||||
|
|
||||||
|
ENV RUSTUP_HOME=/usr/local/rustup
|
||||||
|
ENV CARGO_HOME=/usr/local/cargo
|
||||||
|
ENV PATH=/usr/local/cargo/bin:${PATH}
|
||||||
|
ENV CARGO_BUILD_JOBS=2
|
||||||
|
ENV LIBRARY_PATH=/usr/lib
|
||||||
|
|
||||||
|
RUN curl https://sh.rustup.rs -sSf | sh -s -- \
|
||||||
|
-y \
|
||||||
|
--profile minimal \
|
||||||
|
--default-toolchain ${RUST_VERSION}
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
RUN git clone https://github.com/GreptimeTeam/greptimedb.git . \
|
||||||
|
&& git checkout ${GREPTIMEDB_REF}
|
||||||
|
|
||||||
|
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||||
|
--mount=type=cache,target=/usr/local/cargo/git \
|
||||||
|
cargo build \
|
||||||
|
--release \
|
||||||
|
--locked \
|
||||||
|
--bin greptime \
|
||||||
|
--features servers/dashboard
|
||||||
|
|
||||||
|
RUN mkdir -p /out \
|
||||||
|
&& cp /src/target/release/greptime /out/greptime.debug \
|
||||||
|
&& cp /src/target/release/greptime /out/greptime \
|
||||||
|
&& strip /out/greptime \
|
||||||
|
&& ls -lh /out \
|
||||||
|
&& file /out/greptime \
|
||||||
|
&& ldd /out/greptime || true
|
||||||
|
|
||||||
|
|
||||||
|
FROM scratch AS artifact
|
||||||
|
COPY --from=builder /out/greptime /greptime
|
||||||
|
COPY --from=builder /out/greptime.debug /greptime.debug
|
||||||
|
|
||||||
|
|
||||||
|
FROM alpine:${ALPINE_VERSION} AS runtime
|
||||||
|
RUN apk add --no-cache ca-certificates
|
||||||
|
COPY --from=builder /out/greptime /usr/local/bin/greptime
|
||||||
|
ENTRYPOINT ["/usr/local/bin/greptime"]
|
||||||
53
packaging/alpine/local/greptimedb/Makefile
Normal file
53
packaging/alpine/local/greptimedb/Makefile
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
IMAGE ?= greptime-alpine-builder
|
||||||
|
RUNTIME_IMAGE ?= greptime-alpine
|
||||||
|
GREPTIMEDB_REF ?= main
|
||||||
|
ALPINE_VERSION ?= 3.23
|
||||||
|
RUST_VERSION ?= 1.90.0
|
||||||
|
OUT_DIR ?= dist
|
||||||
|
|
||||||
|
.PHONY: artifact image build inspect run clean
|
||||||
|
|
||||||
|
artifact:
|
||||||
|
mkdir -p $(OUT_DIR)
|
||||||
|
docker build \
|
||||||
|
--target artifact \
|
||||||
|
--build-arg GREPTIMEDB_REF=$(GREPTIMEDB_REF) \
|
||||||
|
--build-arg ALPINE_VERSION=$(ALPINE_VERSION) \
|
||||||
|
--build-arg RUST_VERSION=$(RUST_VERSION) \
|
||||||
|
--output type=local,dest=$(OUT_DIR) .
|
||||||
|
chmod +x $(OUT_DIR)/greptime
|
||||||
|
|
||||||
|
build:
|
||||||
|
docker build \
|
||||||
|
--target builder \
|
||||||
|
--build-arg GREPTIMEDB_REF=$(GREPTIMEDB_REF) \
|
||||||
|
--build-arg ALPINE_VERSION=$(ALPINE_VERSION) \
|
||||||
|
--build-arg RUST_VERSION=$(RUST_VERSION) \
|
||||||
|
-t $(IMAGE):$(GREPTIMEDB_REF) .
|
||||||
|
|
||||||
|
image:
|
||||||
|
docker build \
|
||||||
|
--target runtime \
|
||||||
|
--build-arg GREPTIMEDB_REF=$(GREPTIMEDB_REF) \
|
||||||
|
--build-arg ALPINE_VERSION=$(ALPINE_VERSION) \
|
||||||
|
--build-arg RUST_VERSION=$(RUST_VERSION) \
|
||||||
|
-t $(RUNTIME_IMAGE):$(GREPTIMEDB_REF) .
|
||||||
|
|
||||||
|
inspect: artifact
|
||||||
|
file $(OUT_DIR)/greptime
|
||||||
|
ldd $(OUT_DIR)/greptime || true
|
||||||
|
ls -lh $(OUT_DIR)/greptime $(OUT_DIR)/greptime.debug
|
||||||
|
|
||||||
|
run: image
|
||||||
|
docker run --rm -it \
|
||||||
|
-p 127.0.0.1:4000-4003:4000-4003 \
|
||||||
|
-v "$$(pwd)/greptimedb_data:/greptimedb_data" \
|
||||||
|
$(RUNTIME_IMAGE):$(GREPTIMEDB_REF) \
|
||||||
|
standalone start \
|
||||||
|
--http-addr 0.0.0.0:4000 \
|
||||||
|
--rpc-bind-addr 0.0.0.0:4001 \
|
||||||
|
--mysql-addr 0.0.0.0:4002 \
|
||||||
|
--postgres-addr 0.0.0.0:4003
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(OUT_DIR)
|
||||||
33
packaging/alpine/local/greptimedb/README.md
Normal file
33
packaging/alpine/local/greptimedb/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# GreptimeDB Alpine Package
|
||||||
|
|
||||||
|
This package builds `greptime` from the upstream GreptimeDB source release.
|
||||||
|
|
||||||
|
The old `Dockerfile` and `Makefile` in this directory are reference material for
|
||||||
|
the previous manual build. The APKBUILD uses the same build shape directly:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo build --release --locked --bin greptime --features servers/dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
## Package Commands
|
||||||
|
|
||||||
|
Refresh the source checksum after changing `pkgver`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ALPINE_PACKAGE=greptimedb mise run apk:checksum
|
||||||
|
```
|
||||||
|
|
||||||
|
Build only this package:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ALPINE_PACKAGE=greptimedb mise run apk:build
|
||||||
|
```
|
||||||
|
|
||||||
|
Install-test an existing build without recompiling:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ALPINE_PACKAGE=greptimedb SKIP_BUILD=1 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.
|
||||||
47
packaging/alpine/local/greptimedb/scripts/test-install.sh
Executable file
47
packaging/alpine/local/greptimedb/scripts/test-install.sh
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
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}"
|
||||||
|
|
||||||
|
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}" \
|
||||||
|
-e "PACKAGE_NAME=${package_name}" \
|
||||||
|
-v "${repo_root}/packages/local:/repo:ro" \
|
||||||
|
"alpine:${alpine_version}" \
|
||||||
|
sh -lc '
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
|
||||||
|
printf "%s\n" /repo >> /etc/apk/repositories
|
||||||
|
apk update
|
||||||
|
apk add "${PACKAGE_NAME}"
|
||||||
|
|
||||||
|
test -x /usr/bin/greptime
|
||||||
|
greptime --version
|
||||||
|
'
|
||||||
6
packaging/alpine/local/greptimedb/scripts/update-generated-sources.sh
Executable file
6
packaging/alpine/local/greptimedb/scripts/update-generated-sources.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
package_dir="${PACKAGE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
||||||
|
|
||||||
|
printf 'No generated sources for %s\n' "${package_dir}"
|
||||||
73
packaging/alpine/local/seaweedfs/scripts/test-install.sh
Executable file
73
packaging/alpine/local/seaweedfs/scripts/test-install.sh
Executable file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
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}"
|
||||||
|
|
||||||
|
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 '
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
|
||||||
|
printf "%s\n" /repo >> /etc/apk/repositories
|
||||||
|
apk update
|
||||||
|
|
||||||
|
apk add seaweedfs \
|
||||||
|
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
|
||||||
|
|
||||||
|
weed version
|
||||||
|
|
||||||
|
rc-update add seaweedfs.master default
|
||||||
|
rc-update add seaweedfs.volume default
|
||||||
|
rc-update add seaweedfs.filer default
|
||||||
|
test -L /etc/runlevels/default/seaweedfs.master
|
||||||
|
test -L /etc/runlevels/default/seaweedfs.volume
|
||||||
|
test -L /etc/runlevels/default/seaweedfs.filer
|
||||||
|
|
||||||
|
apk add seaweedfs-doc bash-completion
|
||||||
|
apk info -e seaweedfs-bash-completion
|
||||||
|
test -d /usr/share/doc/seaweedfs/examples
|
||||||
|
test -f /usr/share/doc/seaweedfs/examples/master.toml
|
||||||
|
test -f /usr/share/bash-completion/completions/weed
|
||||||
|
'
|
||||||
15
packaging/alpine/local/seaweedfs/scripts/update-generated-sources.sh
Executable file
15
packaging/alpine/local/seaweedfs/scripts/update-generated-sources.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/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)
|
||||||
|
|
||||||
|
for config in "${configs[@]}"; do
|
||||||
|
"${repo_root}/bin/weed" scaffold -config "${config}" 2>/dev/null \
|
||||||
|
> "${package_dir}/example-${config}.toml"
|
||||||
|
done
|
||||||
|
|
||||||
|
"${repo_root}/bin/weed" autocomplete bash 2>/dev/null \
|
||||||
|
| sed -E 's#complete -C "?[^"]*/weed"? weed#complete -C /usr/bin/weed weed#' \
|
||||||
|
> "${package_dir}/weed.bash-completion"
|
||||||
@@ -4,6 +4,8 @@ set -euo pipefail
|
|||||||
command_name="${1:-build}"
|
command_name="${1:-build}"
|
||||||
requested_arch="${2:-${ALPINE_ARCH:-x86_64}}"
|
requested_arch="${2:-${ALPINE_ARCH:-x86_64}}"
|
||||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
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.23}"
|
||||||
repo_name="${ALPINE_REPO_NAME:-local}"
|
repo_name="${ALPINE_REPO_NAME:-local}"
|
||||||
build_platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
|
build_platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
|
||||||
@@ -27,10 +29,14 @@ validate_arch() {
|
|||||||
run_for_arch() {
|
run_for_arch() {
|
||||||
local arch="$1"
|
local arch="$1"
|
||||||
local subcommand="$2"
|
local subcommand="$2"
|
||||||
|
local package_dir="$3"
|
||||||
local image_name
|
local image_name
|
||||||
|
local container_package_dir
|
||||||
|
|
||||||
validate_arch "${arch}"
|
validate_arch "${arch}"
|
||||||
image_name="${ALPINE_APK_BUILDER_IMAGE:-seaweedfs-apk-builder:${arch}}"
|
apk_validate_package_dir "${package_dir}"
|
||||||
|
container_package_dir="$(apk_container_package_dir "${repo_root}" "${package_dir}")"
|
||||||
|
image_name="${ALPINE_APK_BUILDER_IMAGE:-alpine-apk-builder:${arch}}"
|
||||||
|
|
||||||
docker build \
|
docker build \
|
||||||
--platform "${build_platform}" \
|
--platform "${build_platform}" \
|
||||||
@@ -50,6 +56,7 @@ run_for_arch() {
|
|||||||
-e "ALPINE_ARCH=${arch}" \
|
-e "ALPINE_ARCH=${arch}" \
|
||||||
-e "CARCH=${arch}" \
|
-e "CARCH=${arch}" \
|
||||||
-e "ALPINE_REPO_NAME=${repo_name}" \
|
-e "ALPINE_REPO_NAME=${repo_name}" \
|
||||||
|
-e "APKBUILD_DIR=${container_package_dir}" \
|
||||||
-e "PACKAGER=${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}" \
|
-e "PACKAGER=${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}" \
|
||||||
-v "${repo_root}:/work" \
|
-v "${repo_root}:/work" \
|
||||||
-v "${repo_root}/.cache/abuild:/home/builder/.abuild" \
|
-v "${repo_root}/.cache/abuild:/home/builder/.abuild" \
|
||||||
@@ -66,12 +73,38 @@ mkdir -p \
|
|||||||
|
|
||||||
case "${command_name}" in
|
case "${command_name}" in
|
||||||
build-all)
|
build-all)
|
||||||
for arch in ${ALPINE_ARCHES:-x86_64 aarch64}; do
|
while IFS= read -r package_dir; do
|
||||||
run_for_arch "${arch}" build
|
for arch in ${ALPINE_ARCHES:-x86_64 aarch64}; do
|
||||||
done
|
if ! apk_package_supports_arch "${package_dir}" "${arch}"; then
|
||||||
|
printf 'Skipping %s for unsupported arch %s\n' "$(apk_package_name "${package_dir}")" "${arch}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
run_for_arch "${arch}" build "${package_dir}"
|
||||||
|
done
|
||||||
|
done < <(apk_package_dirs "${repo_root}")
|
||||||
;;
|
;;
|
||||||
build|checksum|lint|shell)
|
build|checksum|lint)
|
||||||
run_for_arch "${requested_arch}" "${command_name}"
|
while IFS= read -r package_dir; do
|
||||||
|
if [[ "${command_name}" == "build" ]] && ! apk_package_supports_arch "${package_dir}" "${requested_arch}"; then
|
||||||
|
printf 'Skipping %s for unsupported arch %s\n' "$(apk_package_name "${package_dir}")" "${requested_arch}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
run_for_arch "${requested_arch}" "${command_name}" "${package_dir}"
|
||||||
|
done < <(apk_package_dirs "${repo_root}")
|
||||||
|
;;
|
||||||
|
shell)
|
||||||
|
package_count=0
|
||||||
|
selected_package_dir=""
|
||||||
|
while IFS= read -r package_dir; do
|
||||||
|
package_count=$((package_count + 1))
|
||||||
|
selected_package_dir="${package_dir}"
|
||||||
|
done < <(apk_package_dirs "${repo_root}")
|
||||||
|
|
||||||
|
if [[ "${package_count}" -ne 1 ]]; then
|
||||||
|
printf 'apk:shell needs exactly one package; set ALPINE_PACKAGE=<name>\n' >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
run_for_arch "${requested_arch}" "${command_name}" "${selected_package_dir}"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
printf 'unknown command: %s\n' "${command_name}" >&2
|
printf 'unknown command: %s\n' "${command_name}" >&2
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
package_dir="${APKBUILD_DIR:-${repo_root}/packaging/alpine/local/seaweedfs}"
|
. "${repo_root}/scripts/apk/package-lib.sh"
|
||||||
|
|
||||||
repo_name="${ALPINE_REPO_NAME:-local}"
|
repo_name="${ALPINE_REPO_NAME:-local}"
|
||||||
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
|
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
|
||||||
packager="${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}"
|
packager="${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}"
|
||||||
|
selected_packages="${ALPINE_PACKAGE:-${ALPINE_PACKAGES:-}}"
|
||||||
|
|
||||||
if [[ "${1:-}" != "--as-builder" && "$(id -u)" == "0" ]]; then
|
if [[ "${1:-}" != "--as-builder" && "$(id -u)" == "0" ]]; then
|
||||||
addgroup -g 1000 builder 2>/dev/null || addgroup builder
|
addgroup -g 1000 builder 2>/dev/null || addgroup builder
|
||||||
@@ -15,7 +17,7 @@ if [[ "${1:-}" != "--as-builder" && "$(id -u)" == "0" ]]; then
|
|||||||
printf 'permit nopass :wheel\n' > /etc/doas.d/wheel.conf
|
printf 'permit nopass :wheel\n' > /etc/doas.d/wheel.conf
|
||||||
printf '%%wheel ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/wheel
|
printf '%%wheel ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/wheel
|
||||||
chown -R builder:builder "${repo_root}"
|
chown -R builder:builder "${repo_root}"
|
||||||
exec su builder -c "ALPINE_ARCHES='${arches}' ALPINE_REPO_NAME='${repo_name}' PACKAGER='${packager}' '${BASH_SOURCE[0]}' --as-builder"
|
exec su builder -c "ALPINE_ARCHES='${arches}' ALPINE_REPO_NAME='${repo_name}' ALPINE_PACKAGES='${selected_packages}' PACKAGER='${packager}' '${BASH_SOURCE[0]}' --as-builder"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export PACKAGER="${packager}"
|
export PACKAGER="${packager}"
|
||||||
@@ -36,20 +38,29 @@ fi
|
|||||||
|
|
||||||
doas cp "${HOME}"/.abuild/*.rsa.pub /etc/apk/keys/
|
doas cp "${HOME}"/.abuild/*.rsa.pub /etc/apk/keys/
|
||||||
|
|
||||||
for arch in ${arches}; do
|
while IFS= read -r package_dir; do
|
||||||
case "${arch}" in
|
apk_validate_package_dir "${package_dir}"
|
||||||
x86_64|aarch64) ;;
|
|
||||||
*) printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2; exit 2 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
printf 'Building %s for %s\n' "$(basename "${package_dir}")" "${arch}"
|
for arch in ${arches}; do
|
||||||
(
|
case "${arch}" in
|
||||||
export ALPINE_ARCH="${arch}"
|
x86_64|aarch64) ;;
|
||||||
export CARCH="${arch}"
|
*) printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2; exit 2 ;;
|
||||||
cd "${package_dir}"
|
esac
|
||||||
abuild -r
|
|
||||||
)
|
|
||||||
|
|
||||||
mkdir -p "${REPODEST}/${repo_name}/${arch}"
|
if ! apk_package_supports_arch "${package_dir}" "${arch}"; then
|
||||||
cp "${HOME}"/.abuild/*.rsa.pub "${REPODEST}/${repo_name}/${arch}/"
|
printf 'Skipping %s for unsupported arch %s\n' "$(basename "${package_dir}")" "${arch}"
|
||||||
done
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'Building %s for %s\n' "$(basename "${package_dir}")" "${arch}"
|
||||||
|
(
|
||||||
|
export ALPINE_ARCH="${arch}"
|
||||||
|
export CARCH="${arch}"
|
||||||
|
cd "${package_dir}"
|
||||||
|
abuild -r
|
||||||
|
)
|
||||||
|
|
||||||
|
mkdir -p "${REPODEST}/${repo_name}/${arch}"
|
||||||
|
cp "${HOME}"/.abuild/*.rsa.pub "${REPODEST}/${repo_name}/${arch}/"
|
||||||
|
done
|
||||||
|
done < <(apk_package_dirs "${repo_root}")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ set -euo pipefail
|
|||||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
repo_name="${ALPINE_REPO_NAME:-local}"
|
repo_name="${ALPINE_REPO_NAME:-local}"
|
||||||
arch="${ALPINE_ARCH:-$(apk --print-arch)}"
|
arch="${ALPINE_ARCH:-$(apk --print-arch)}"
|
||||||
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}"
|
||||||
repo_dir="${repo_root}/packages/${repo_name}/${arch}"
|
repo_dir="${repo_root}/packages/${repo_name}/${arch}"
|
||||||
read -r -a package_list <<< "${packages}"
|
read -r -a package_list <<< "${packages}"
|
||||||
|
|
||||||
@@ -18,6 +18,9 @@ echo "${repo_root}/packages/${repo_name}" >> /etc/apk/repositories
|
|||||||
apk update
|
apk update
|
||||||
apk add "${package_list[@]}"
|
apk add "${package_list[@]}"
|
||||||
weed version
|
weed version
|
||||||
|
if command -v greptime >/dev/null 2>&1; then
|
||||||
|
greptime --version
|
||||||
|
fi
|
||||||
ls -1 /etc/seaweedfs
|
ls -1 /etc/seaweedfs
|
||||||
if ls /etc/init.d/seaweedfs.* >/dev/null 2>&1; then
|
if ls /etc/init.d/seaweedfs.* >/dev/null 2>&1; then
|
||||||
find /etc/init.d -maxdepth 1 -name 'seaweedfs.*' -print | sort
|
find /etc/init.d -maxdepth 1 -name 'seaweedfs.*' -print | sort
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ set -euo pipefail
|
|||||||
|
|
||||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
|
|
||||||
rm -rf \
|
rm -rf "${repo_root}/packages"
|
||||||
"${repo_root}/packages" \
|
find "${repo_root}/packaging/alpine/local" \
|
||||||
"${repo_root}/packaging/alpine/local/seaweedfs/pkg" \
|
\( -type d -name pkg -o -type d -name src \) \
|
||||||
"${repo_root}/packaging/alpine/local/seaweedfs/src"
|
-prune -exec rm -rf {} +
|
||||||
|
|||||||
131
scripts/apk/package-lib.sh
Normal file
131
scripts/apk/package-lib.sh
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
apk_repo_root() {
|
||||||
|
cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_package_root() {
|
||||||
|
local repo_root="$1"
|
||||||
|
printf '%s\n' "${ALPINE_PACKAGE_ROOT:-${repo_root}/packaging/alpine/local}"
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_package_dirs() {
|
||||||
|
local repo_root="$1"
|
||||||
|
local package_root
|
||||||
|
local package
|
||||||
|
local dir
|
||||||
|
|
||||||
|
package_root="$(apk_package_root "${repo_root}")"
|
||||||
|
|
||||||
|
if [[ -n "${APKBUILD_DIR:-}" ]]; then
|
||||||
|
printf '%s\n' "${APKBUILD_DIR}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${ALPINE_PACKAGE:-}" || -n "${ALPINE_PACKAGES:-}" ]]; then
|
||||||
|
for package in ${ALPINE_PACKAGE:-${ALPINE_PACKAGES:-}}; do
|
||||||
|
case "${package}" in
|
||||||
|
/*|.*/*|*/*)
|
||||||
|
dir="${package}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
dir="${package_root}/${package}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
printf '%s\n' "${dir}"
|
||||||
|
done
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
find "${package_root}" -mindepth 2 -maxdepth 2 -name APKBUILD -print \
|
||||||
|
| sed 's#/APKBUILD$##' \
|
||||||
|
| sort
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_validate_package_dir() {
|
||||||
|
local package_dir="$1"
|
||||||
|
|
||||||
|
if [[ ! -f "${package_dir}/APKBUILD" ]]; then
|
||||||
|
printf 'missing APKBUILD: %s\n' "${package_dir}/APKBUILD" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_package_name() {
|
||||||
|
basename "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_package_arches() {
|
||||||
|
local package_dir="$1"
|
||||||
|
|
||||||
|
awk -F= '
|
||||||
|
$1 == "arch" {
|
||||||
|
gsub(/["'\'']/, "", $2)
|
||||||
|
gsub(/^[ \t]+|[ \t]+$/, "", $2)
|
||||||
|
print $2
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
' "${package_dir}/APKBUILD"
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_package_supports_arch() {
|
||||||
|
local package_dir="$1"
|
||||||
|
local arch="$2"
|
||||||
|
local supported_arches
|
||||||
|
local supported_arch
|
||||||
|
|
||||||
|
supported_arches="$(apk_package_arches "${package_dir}")"
|
||||||
|
|
||||||
|
for supported_arch in ${supported_arches}; do
|
||||||
|
case "${supported_arch}" in
|
||||||
|
all|noarch|"${arch}")
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_container_package_dir() {
|
||||||
|
local repo_root="$1"
|
||||||
|
local package_dir="$2"
|
||||||
|
|
||||||
|
case "${package_dir}" in
|
||||||
|
"${repo_root}"/*)
|
||||||
|
printf '/work/%s\n' "${package_dir#"${repo_root}/"}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf 'package directory must be inside repository: %s\n' "${package_dir}" >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_run_package_hook() {
|
||||||
|
local repo_root="$1"
|
||||||
|
local package_dir="$2"
|
||||||
|
local hook_name="$3"
|
||||||
|
shift 3
|
||||||
|
|
||||||
|
local package_name
|
||||||
|
local hook_path
|
||||||
|
|
||||||
|
package_name="$(apk_package_name "${package_dir}")"
|
||||||
|
hook_path="${package_dir}/scripts/${hook_name}.sh"
|
||||||
|
|
||||||
|
if [[ ! -e "${hook_path}" ]]; then
|
||||||
|
printf 'Skipping %s: no %s hook\n' "${package_name}" "${hook_name}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ ! -x "${hook_path}" ]]; then
|
||||||
|
printf 'package hook is not executable: %s\n' "${hook_path}" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'Running %s hook for %s\n' "${hook_name}" "${package_name}"
|
||||||
|
REPO_ROOT="${repo_root}" \
|
||||||
|
PACKAGE_DIR="${package_dir}" \
|
||||||
|
PACKAGE_NAME="${package_name}" \
|
||||||
|
"${hook_path}" "$@"
|
||||||
|
}
|
||||||
10
scripts/apk/test-install.sh
Executable file
10
scripts/apk/test-install.sh
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
|
. "${repo_root}/scripts/apk/package-lib.sh"
|
||||||
|
|
||||||
|
while IFS= read -r package_dir; do
|
||||||
|
apk_validate_package_dir "${package_dir}"
|
||||||
|
apk_run_package_hook "${repo_root}" "${package_dir}" test-install
|
||||||
|
done < <(apk_package_dirs "${repo_root}")
|
||||||
@@ -2,14 +2,9 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
package_dir="${repo_root}/packaging/alpine/local/seaweedfs"
|
. "${repo_root}/scripts/apk/package-lib.sh"
|
||||||
configs=(credential filer master notification replication security shell)
|
|
||||||
|
|
||||||
for config in "${configs[@]}"; do
|
while IFS= read -r package_dir; do
|
||||||
"${repo_root}/bin/weed" scaffold -config "${config}" 2>/dev/null \
|
apk_validate_package_dir "${package_dir}"
|
||||||
> "${package_dir}/example-${config}.toml"
|
apk_run_package_hook "${repo_root}" "${package_dir}" update-generated-sources
|
||||||
done
|
done < <(apk_package_dirs "${repo_root}")
|
||||||
|
|
||||||
"${repo_root}/bin/weed" autocomplete bash 2>/dev/null \
|
|
||||||
| sed -E 's#complete -C "?[^"]*/weed"? weed#complete -C /usr/bin/weed weed#' \
|
|
||||||
> "${package_dir}/weed.bash-completion"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user