231 lines
7.1 KiB
Markdown
231 lines
7.1 KiB
Markdown
# rustbox-package-builder
|
|
|
|
Linux-only package builder and signed repository publisher for RustBox. It watches the RustBox source repository, builds release binaries, produces distribution-specific packages, signs repository metadata, and serves a small read-only repository dashboard.
|
|
|
|
## Supported Linux families
|
|
|
|
A single RustBox source commit is published for `amd64/x86_64` in three equal Linux families:
|
|
|
|
- Debian / Ubuntu: DEB package and signed APT repository
|
|
- RHEL / AlmaLinux / Rocky Linux: RPM package and signed DNF/YUM repository
|
|
- SUSE / openSUSE: RPM package and signed Zypper repository
|
|
|
|
The dashboard and API use these three families directly. There is no separate generic `Linux` channel.
|
|
|
|
## Repository dashboard
|
|
|
|
The repository UI is English-only and intentionally text-only. It has no logo, favicon, decorative icons, or letter badge. The default public HTTP port is `18965`.
|
|
|
|
The dashboard provides:
|
|
|
|
- latest RustBox package version
|
|
- status for Debian / Ubuntu, RHEL / AlmaLinux / Rocky Linux, and SUSE / openSUSE
|
|
- downloadable package list
|
|
- installation commands for each Linux family
|
|
- repository metadata and build information
|
|
- JSON API at `GET /api/v1/packages`
|
|
|
|
## RustBox source requirement
|
|
|
|
RustBox must support native file logging through `log_dir`. The package configuration uses:
|
|
|
|
```toml
|
|
log_dir = "/var/log/rustbox"
|
|
```
|
|
|
|
The builder rejects RustBox sources that do not contain this setting. Application logs are written to `/var/log/rustbox/rustbox.log` instead of normal systemd stdout logging.
|
|
|
|
## Quick start
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
nano .env
|
|
./start.sh
|
|
```
|
|
|
|
Minimum configuration:
|
|
|
|
```env
|
|
SOURCE_REPO=https://git.example.com/rustbox/RustBox.git
|
|
SOURCE_BRANCH=master
|
|
REPOSITORY_URL=http://127.0.0.1:18965
|
|
HTTP_PORT=18965
|
|
```
|
|
|
|
For a public installation, set `REPOSITORY_URL` to the externally reachable URL. If a reverse proxy terminates HTTPS, it can forward traffic to local port `18965`.
|
|
|
|
`start.sh` creates a persistent GPG signing key in `gpg/`, builds the containers, and starts:
|
|
|
|
- `rustbox-package-builder`: source watcher, build, package and publication process
|
|
- `repository-dashboard`: read-only dashboard and API
|
|
- `repository-http`: Nginx serving the dashboard and package repositories on port `18965` by default
|
|
|
|
Persistent builder state is stored in `data/`.
|
|
|
|
## Default build settings
|
|
|
|
```env
|
|
POLL_INTERVAL=300
|
|
REPO_DISTRIBUTION=stable
|
|
REPO_COMPONENT=main
|
|
PACKAGE_RELEASE=auto
|
|
RUN_LINUX_TESTS=compile
|
|
MAX_GLIBC_VERSION=2.34
|
|
RELEASE_RETENTION=10
|
|
```
|
|
|
|
`RUN_LINUX_TESTS=compile` runs `cargo test --release --locked --no-run`. Use `full` to run the test suite or `0` to skip Rust tests.
|
|
|
|
All three supported Linux package families are built on every successful release. SUSE is not treated as a separate non-Linux target.
|
|
|
|
## Installed RustBox layout
|
|
|
|
The generated packages install:
|
|
|
|
```text
|
|
/usr/local/bin/rustbox
|
|
/usr/lib/systemd/system/rustbox.service
|
|
/etc/rustbox/rustbox.toml
|
|
/etc/logrotate.d/rustbox
|
|
```
|
|
|
|
They create and maintain:
|
|
|
|
```text
|
|
/var/lib/rustbox rustbox:rustbox 0700
|
|
/var/log/rustbox rustbox:rustbox 0750
|
|
/etc/rustbox rustbox:rustbox 0750
|
|
```
|
|
|
|
`/etc/rustbox/rustbox.toml` is owned by `rustbox:rustbox`, mode `0640`, and packaged as a non-replacing configuration file so package upgrades preserve local changes.
|
|
|
|
## systemd
|
|
|
|
The service uses the dedicated `rustbox` user and hardened systemd settings:
|
|
|
|
```ini
|
|
User=rustbox
|
|
Group=rustbox
|
|
Environment=RUSTBOX_CONFIG=/etc/rustbox/rustbox.toml
|
|
WorkingDirectory=/var/lib/rustbox
|
|
ExecStart=/usr/local/bin/rustbox
|
|
StateDirectory=rustbox
|
|
LogsDirectory=rustbox
|
|
ProtectSystem=strict
|
|
ProtectHome=true
|
|
NoNewPrivileges=true
|
|
```
|
|
|
|
RustBox tracing logs are written to `/var/log/rustbox/rustbox.log`. `StandardOutput=null` is used for normal output. `StandardError=journal` remains available for startup failures that happen before the application logger is initialized.
|
|
|
|
## logrotate
|
|
|
|
`/etc/logrotate.d/rustbox` rotates `/var/log/rustbox/rustbox.log` daily, keeps 7 rotations, compresses old files, and recreates the active log with `rustbox:rustbox` ownership.
|
|
|
|
## Default RustBox configuration
|
|
|
|
```toml
|
|
host = "0.0.0.0"
|
|
port = 3001
|
|
environment = "production"
|
|
data_dir = "/var/lib/rustbox"
|
|
log_dir = "/var/log/rustbox"
|
|
session_timeout_hours = 72
|
|
remember_me_enabled = true
|
|
remember_me_days = 30
|
|
imap_host = "localhost"
|
|
imap_port = 993
|
|
smtp_host = "localhost"
|
|
smtp_port = 587
|
|
tls_enabled = true
|
|
tls_verify = false
|
|
max_attachment_size_mb = 50
|
|
max_message_size_mb = 100
|
|
sieve_port = 4190
|
|
sieve_tls_mode = "none"
|
|
sieve_allow_insecure_auth = true
|
|
sieve_timeout_secs = 10
|
|
default_junk_folder = "Spam"
|
|
default_theme = "system"
|
|
default_interface_skin = "apple-mail"
|
|
trusted_proxies = "127.0.0.1,::1"
|
|
outgoing_headers = []
|
|
pgp_wkd_enabled = true
|
|
pgp_hkp_enabled = false
|
|
pgp_hkp_url = "https://keys.openpgp.org"
|
|
pgp_network_timeout_secs = 10
|
|
pgp_max_key_bytes = 1048576
|
|
pgp_allow_private_export = true
|
|
```
|
|
|
|
## Debian / Ubuntu
|
|
|
|
```bash
|
|
curl -fsSL http://repo.example.com:18965/repo-key.gpg \
|
|
| sudo gpg --dearmor -o /usr/share/keyrings/rustbox.gpg
|
|
|
|
echo "deb [signed-by=/usr/share/keyrings/rustbox.gpg] http://repo.example.com:18965/apt stable main" \
|
|
| sudo tee /etc/apt/sources.list.d/rustbox.list
|
|
|
|
sudo apt update
|
|
sudo apt install rustbox
|
|
```
|
|
|
|
## RHEL / AlmaLinux / Rocky Linux
|
|
|
|
```bash
|
|
sudo rpm --import http://repo.example.com:18965/repo-key.gpg
|
|
sudo tee /etc/yum.repos.d/rustbox.repo >/dev/null <<'REPO'
|
|
[rustbox]
|
|
name=RustBox Package Repository
|
|
baseurl=http://repo.example.com:18965/rpm/$basearch
|
|
enabled=1
|
|
gpgcheck=1
|
|
repo_gpgcheck=1
|
|
gpgkey=http://repo.example.com:18965/repo-key.gpg
|
|
REPO
|
|
sudo dnf install rustbox
|
|
```
|
|
|
|
## SUSE / openSUSE
|
|
|
|
```bash
|
|
sudo rpm --import http://repo.example.com:18965/repo-key.gpg
|
|
sudo zypper addrepo --refresh --gpgcheck http://repo.example.com:18965/suse/x86_64/ rustbox
|
|
sudo zypper refresh rustbox
|
|
sudo zypper install rustbox
|
|
```
|
|
|
|
## Repository paths
|
|
|
|
```text
|
|
/apt/ Debian / Ubuntu APT repository
|
|
/rpm/x86_64/ RHEL / AlmaLinux / Rocky Linux RPM repository
|
|
/suse/x86_64/ SUSE / openSUSE RPM repository
|
|
/repo-key.gpg public package signing key
|
|
/DEBIAN-BUILD-INFO.txt Debian / Ubuntu build metadata
|
|
/RHEL-BUILD-INFO.txt RHEL-family build metadata
|
|
/SUSE-BUILD-INFO.txt SUSE-family build metadata
|
|
/api/v1/packages repository JSON API
|
|
```
|
|
|
|
## Builder logs
|
|
|
|
```bash
|
|
docker compose --env-file .env logs -f rustbox-package-builder
|
|
docker compose --env-file .env logs -f repository-http
|
|
docker compose --env-file .env logs -f repository-dashboard
|
|
```
|
|
|
|
## Runtime package dependencies
|
|
|
|
Generated packages declare the system OpenSSL and GnuPG dependencies used by RustBox:
|
|
|
|
- Debian / Ubuntu: `libssl3` or `libssl3t64`, plus `gnupg`
|
|
- RHEL / AlmaLinux / Rocky Linux: `openssl-libs` and `gnupg2`
|
|
- SUSE / openSUSE: `libopenssl3` and `gpg2`
|
|
|
|
## Package license metadata
|
|
|
|
The supplied RustBox source archive does not contain an authoritative `LICENSE` file. The builder therefore keeps package license metadata as `UNKNOWN` instead of guessing. Set the correct license in `scripts/prepare-package.sh` before public redistribution once the upstream license has been confirmed.
|