Private
Public Access
1
0

docs: add detailed Arch, RPM, Alpine installation instructions

- README: comprehensive per-platform install/build/verify/remove instructions
- README: prerequisites, post-install notes, Alpine OpenRC differences
- BUILD_PACKAGES: add Arch and Alpine build sections with troubleshooting
- BUILD_PACKAGES: fix Service Account table (runs as root, not system user)
- BUILD_PACKAGES: add Arch/Alpine supported distributions tables
This commit is contained in:
2026-05-20 02:06:52 +00:00
parent 63b0bfce34
commit aa721963b3
2 changed files with 384 additions and 26 deletions

View File

@ -1,6 +1,6 @@
# Linux Patch API - Package Build Guide
This document provides comprehensive instructions for building production-ready Debian (.deb) and RPM (.rpm) packages for the Linux Patch API.
This document provides comprehensive instructions for building production-ready packages for the Linux Patch API across all supported platforms: Debian/Ubuntu (.deb), RHEL/CentOS/Fedora (.rpm), Arch Linux (.pkg.tar.zst), and Alpine Linux (.apk).
## Prerequisites
@ -173,6 +173,152 @@ rpm -ql linux-patch-api
rpm -e linux-patch-api
```
## Building Arch Package (.pkg.tar.zst)
### Quick Build
```bash
cd /path/to/linux_patch_api
# Build release binary
cargo build --release
# Build Arch package
chmod +x build-arch.sh
SKIP_CARGO_BUILD=1 ./build-arch.sh
# Package will be created in releases/
ls -la releases/*.pkg.tar.zst
```
### Detailed Build Process
```bash
# 1. Install build dependencies (Arch Linux)
sudo pacman -Syu --noconfirm rust cargo systemd git base-devel gcc
# 2. Build release binary
cargo build --release
# 3. Run build script
chmod +x build-arch.sh
./build-arch.sh
# 4. Verify package contents
bsdtar -tf releases/linux-patch-api-*.pkg.tar.zst
# 5. Verify package info
pacman -Qi releases/linux-patch-api-*.pkg.tar.zst
```
### Install Script Hooks
The Arch package includes an `.install` file (`configs/linux-patch-api.install`) that runs automatically on install:
- **post_install**: Creates directories, copies example configs, enables systemd service
- **post_upgrade**: Reloads systemd daemon
- **pre_remove**: Stops and disables service
- **post_remove**: Cleans up empty directories
### Installation Test
```bash
# Install the package
sudo pacman -U ./releases/linux-patch-api-*.pkg.tar.zst
# Verify installation
systemctl status linux-patch-api
linux-patch-api --version
# Check installed files
pacman -Ql linux-patch-api
# Verify config files exist
ls -la /etc/linux_patch_api/
# Remove package
sudo pacman -R linux-patch-api
```
**Note:** The build script creates a `builduser` for `makepkg` when running as root (typical in CI environments). The `.install` hook handles directory creation, config copying, and service enablement.
## Building Alpine Package (.apk)
### Quick Build
```bash
cd /path/to/linux_patch_api
# Build release binary (MUSL target for Alpine)
cargo build --release --target x86_64-unknown-linux-musl
# Build Alpine package
chmod +x build-alpine.sh
SKIP_CARGO_BUILD=1 ./build-alpine.sh
# Package will be created in releases/
ls -la releases/*.apk
```
### Detailed Build Process
```bash
# 1. Install build dependencies (Alpine Linux)
apk add --no-cache alpine-sdk rust cargo openssl openssl-dev elogind-dev musl-dev abuild gcc
# 2. Add Rust MUSL target
rustup target add x86_64-unknown-linux-musl
# 3. Build release binary
cargo build --release --target x86_64-unknown-linux-musl
# 4. Run build script
chmod +x build-alpine.sh
./build-alpine.sh
# 5. Verify package contents
apk verify releases/*.apk
# 6. List package contents
tar -tzf releases/*.apk
```
### Install Script Hooks
The Alpine package includes an install script (`configs/linux-patch-api.apk-install`) that runs automatically on install:
- **pre_install**: Creates directories, sets ownership and permissions
- **post_install**: Copies example configs, adds service to default runlevel
- **pre_deinstall**: Stops and removes service from runlevel
- **post_deinstall**: Cleans up empty directories
### Installation Test
```bash
# Install the package
sudo apk add --allow-unstable ./releases/linux-patch-api-*.apk
# Verify installation
rc-service linux-patch-api status
linux-patch-api --version
# Check installed files
apk info -L linux-patch-api
# Verify config files exist
ls -la /etc/linux_patch_api/
# Remove package
sudo apk del linux-patch-api
```
**Important:** Alpine uses **OpenRC** instead of systemd. Key differences:
- Start service: `rc-service linux-patch-api start`
- Stop service: `rc-service linux-patch-api stop`
- Check status: `rc-service linux-patch-api status`
- Service init script: `/etc/init.d/linux-patch-api`
- The `abuild` tool generates signing keys automatically for CI builds
## Using the Interactive Installer
For manual deployment without package managers:
@ -209,15 +355,17 @@ The installer will:
| `/var/lib/linux_patch_api/` | Data directory | 755 |
| `/var/log/linux_patch_api/` | Log directory | 755 |
### System User/Group
### Service Account
| Property | Value |
|----------|-------|
| User | linux-patch-api |
| Group | linux-patch-api |
| User | root |
| Group | root |
| Home | /var/lib/linux_patch_api |
| Shell | /usr/sbin/nologin |
| Type | System account |
| Shell | N/A (systemd service) |
| Type | Runs as root (required for package management) |
**Note:** The service runs as root because package management operations (apt, dnf, apk, pacman) require root privileges. Security is provided by mTLS + IP whitelist, not process isolation.
## Supported Distributions
@ -240,6 +388,19 @@ The installer will:
| AlmaLinux | 8, 9 | ✅ Supported |
| Rocky Linux | 8, 9 | ✅ Supported |
### Arch Package (.pkg.tar.zst)
| Distribution | Versions | Status |
|--------------|----------|--------|
| Arch Linux | Rolling | ✅ Supported |
| Manjaro | Rolling | ✅ Supported |
### Alpine Package (.apk)
| Distribution | Versions | Status |
|--------------|----------|--------|
| Alpine Linux | 3.18+ | ✅ Supported |
## Troubleshooting
### Debian Package Issues
@ -276,9 +437,62 @@ cat ~/rpmbuild/BUILDROOT/*/var/log/rpmbuild.log
dnf install -y systemd-devel pkgconfig
```
### Arch Package Issues
**Error: `makepkg: cannot run as root`**
```bash
# The build script handles this automatically by creating builduser
# If running manually:
useradd -m builduser
su - builduser -c "cd /path/to/repo && makepkg -f --noconfirm"
```
**Error: `install script not found`**
```bash
# Ensure linux-patch-api.install is in the same directory as PKGBUILD
ls -la configs/linux-patch-api.install
# The build script copies it automatically
```
**Error: `Permission denied` on config files**
```bash
# Verify ownership is root:root
ls -la /etc/linux_patch_api/
# Fix if needed:
sudo chown -R root:root /etc/linux_patch_api/
sudo chmod 750 /etc/linux_patch_api /etc/linux_patch_api/certs
```
### Alpine Package Issues
**Error: `abuild: UNTRUSTED signature`**
```bash
# The build script handles key generation automatically
# If running manually:
abuild-keygen -a -n
cp /root/.abuild/*.rsa.pub /etc/apk/keys/
```
**Error: `apk add: ERROR: failed to create directory`**
```bash
# Verify the install script ran correctly
ls -la /etc/linux_patch_api/
ls -la /var/lib/linux_patch_api/
# Manually create if needed:
sudo mkdir -p /etc/linux_patch_api/certs /var/lib/linux_patch_api /var/log/linux_patch_api
```
**Error: `rc-service: service not found`**
```bash
# Verify the init script exists
ls -la /etc/init.d/linux-patch-api
# Re-add to default runlevel
sudo rc-update add linux-patch-api default
```
### Service Issues
**Service fails to start:**
**Service fails to start (systemd):**
```bash
# Check service status
systemctl status linux-patch-api
@ -293,6 +507,22 @@ linux-patch-api --config /etc/linux_patch_api/config.yaml --check
ls -la /etc/linux_patch_api/certs/
```
**Service fails to start (OpenRC/Alpine):**
```bash
# Check service status
rc-service linux-patch-api status
# View logs
cat /var/log/linux_patch_api/linux-patch-api.log
cat /var/log/linux_patch_api/linux-patch-api.err
# Check configuration
linux-patch-api --config /etc/linux_patch_api/config.yaml --check
# Verify certificates
ls -la /etc/linux_patch_api/certs/
```
## CI/CD Integration
### GitHub Actions Example
@ -383,7 +613,7 @@ jobs:
- Packages are signed with maintainer GPG key for production deployments
- All maintainer scripts run with `set -e` for fail-fast behavior
- Configuration files are marked as conffiles to preserve user modifications
- System user has minimal privileges (nologin shell, no home directory)
- Service runs as root (required for package management operations)
- Directory permissions follow principle of least privilege
- TLS certificates should be replaced with CA-signed certs in production

164
README.md
View File

@ -185,6 +185,13 @@ For detailed enrollment procedures, see [DEPLOYMENT_GUIDE.md - Self-Enrollment D
### Package Installation
All platform packages produce identical installation results:
- Creates `/etc/linux_patch_api/`, `/etc/linux_patch_api/certs/`, `/var/lib/linux_patch_api/`, `/var/log/linux_patch_api/`
- Copies example configs to live configs if not already present
- Enables the service (does not start automatically)
- Sets correct permissions (750 on config dirs, 755 on data/log dirs)
- Ownership: root:root (service runs as root)
#### Debian/Ubuntu (.deb)
```bash
@ -197,52 +204,173 @@ apt-get install -f -y
# Verify installation
systemctl status linux-patch-api
linux-patch-api --version
# Check installed files
dpkg -L linux-patch-api
# Remove package (keeping configs)
dpkg -r linux-patch-api
# Purge package (removing all configs)
dpkg -P linux-patch-api
```
**Prerequisites:** `systemd`, `libsystemd0`
**Post-install:** The package automatically copies example configs, enables the service, and prints next steps. Configure `/etc/linux_patch_api/config.yaml` and place TLS certificates in `/etc/linux_patch_api/certs/` before starting.
#### RHEL/CentOS/Fedora (.rpm)
```bash
# Install the package
rpm -ivh linux-patch-api-1.0.0-1.x86_64.rpm
# Install the package (recommended - resolves dependencies automatically)
dnf install -y ./linux-patch-api-1.0.0-1.el9.x86_64.rpm
# Or with yum
yum install -y ./linux-patch-api-1.0.0-1.el9.x86_64.rpm
# Or with rpm (does NOT resolve dependencies)
rpm -ivh linux-patch-api-1.0.0-1.el9.x86_64.rpm
# Verify installation
systemctl status linux-patch-api
linux-patch-api --version
# Check installed files
rpm -ql linux-patch-api
# Remove package
rpm -e linux-patch-api
```
**Prerequisites (auto-resolved with dnf/yum):** `systemd`, `libsystemd`, `openssl-libs`, `ca-certificates`
**Post-install:** The package automatically creates directories, copies example configs, enables the service, and prints next steps. Configure `/etc/linux_patch_api/config.yaml` and place TLS certificates in `/etc/linux_patch_api/certs/` before starting.
**Note:** Use `dnf install` or `yum install` instead of `rpm -ivh` to automatically resolve dependencies. The `rpm -ivh` command will fail if required packages are not already installed.
#### Arch Linux (.pkg.tar.zst)
```bash
# Install the package
sudo pacman -U ./linux-patch-api-1.0.0-1-x86_64.pkg.tar.zst
# Verify installation
systemctl status linux-patch-api
linux-patch-api --version
# Check installed files
pacman -Ql linux-patch-api
# Remove package
sudo pacman -R linux-patch-api
```
**Prerequisites:** `systemd` (included by default on Arch)
**Post-install:** The package automatically creates directories, copies example configs, enables the service, and prints next steps. Configure `/etc/linux_patch_api/config.yaml` and place TLS certificates in `/etc/linux_patch_api/certs/` before starting.
**Note:** Arch uses systemd by default. The install hook runs `systemctl enable` but does not start the service. You must configure before starting.
#### Alpine Linux (.apk)
```bash
# Install the package
sudo apk add --allow-unstable ./linux-patch-api-1.0.0-r0.apk
# Verify installation
rc-service linux-patch-api status
linux-patch-api --version
# Check installed files
apk info -L linux-patch-api
# Remove package
sudo apk del linux-patch-api
```
**Prerequisites:** `openrc` (included by default on Alpine)
**Post-install:** The package automatically creates directories, copies example configs, adds the service to the default runlevel, and prints next steps. Configure `/etc/linux_patch_api/config.yaml` and place TLS certificates in `/etc/linux_patch_api/certs/` before starting.
**Important differences from systemd-based systems:**
- Alpine uses **OpenRC** instead of systemd. Use `rc-service` commands instead of `systemctl`
- Start service: `rc-service linux-patch-api start`
- Stop service: `rc-service linux-patch-api stop`
- Check status: `rc-service linux-patch-api status`
- The service is added to the `default` runlevel automatically on install
- Service init script: `/etc/init.d/linux-patch-api`
### Manual Installation
For systems without package manager support:
```bash
# Run interactive installer (requires root)
./install.sh
sudo ./install.sh
```
The installer will:
- Detect operating system
- Create system user and group
- Set up directory structure
- Install binary and configuration files
- Create directory structure (`/etc/linux_patch_api/`, `/var/lib/linux_patch_api/`, `/var/log/linux_patch_api/`)
- Install binary to `/usr/bin/linux-patch-api`
- Install example configs
- Configure systemd service
- Set correct permissions
### Building from Source
#### Prerequisites (all platforms)
- Rust toolchain (stable channel, 1.75+)
- OpenSSL development headers
- systemd development headers
- C compiler (gcc)
#### Build Debian Package (.deb)
```bash
# Clone repository
git clone https://gitea.internal/linux-patch-api.git
cd linux-patch-api
# Build release binary
cargo build --release --target x86_64-unknown-linux-gnu
# Build Debian package
dpkg-buildpackage -us -uc -b
# Or build RPM package
rpmbuild -ba linux-patch-api.spec
# On Debian/Ubuntu
apt-get install -y build-essential debhelper pkg-config libsystemd-dev libssl-dev cargo rustc
cargo build --release
sudo dpkg-buildpackage -us -uc -b
```
#### Build RPM Package (.rpm)
```bash
# On Fedora/RHEL/CentOS
dnf install -y rpm-build cargo rust gcc openssl-devel systemd-devel pkgconfig
cargo build --release --target x86_64-unknown-linux-gnu
chmod +x build-rpm.sh
./build-rpm.sh
```
**Note:** The RPM spec includes `BuildRequires` for native RPM build environments. When building in CI containers (where deps are pre-installed via apt-get), these are informational only.
#### Build Arch Package (.pkg.tar.zst)
```bash
# On Arch Linux/Manjaro
pacman -Syu --noconfirm rust cargo systemd git base-devel gcc
cargo build --release
chmod +x build-arch.sh
SKIP_CARGO_BUILD=1 ./build-arch.sh
```
**Note:** The build script creates a `builduser` for `makepkg` when running as root (typical in CI). The `.install` hook handles directory creation, config copying, and service enablement.
#### Build Alpine Package (.apk)
```bash
# On Alpine Linux 3.18+
apk add --no-cache alpine-sdk rust cargo openssl openssl-dev elogind-dev musl-dev abuild gcc
cargo build --release --target x86_64-unknown-linux-musl
chmod +x build-alpine.sh
SKIP_CARGO_BUILD=1 ./build-alpine.sh
```
**Important:** Alpine requires the `x86_64-unknown-linux-musl` target for static linking. The build script handles `abuild` key generation and runs as a `builduser` when executed as root.
See [BUILD_PACKAGES.md](./BUILD_PACKAGES.md) for detailed build instructions.
---