Merge develop into master for v1.0.0 release
This commit is contained in:
136
.github/workflows/ci.yml
vendored
136
.github/workflows/ci.yml
vendored
@ -26,70 +26,66 @@ jobs:
|
|||||||
- name: Check formatting
|
- name: Check formatting
|
||||||
run: cargo fmt --all -- --check
|
run: cargo fmt --all -- --check
|
||||||
|
|
||||||
# TEMPORARILY DISABLED - re-enable after build jobs are stable
|
clippy:
|
||||||
# clippy:
|
name: Clippy Lints
|
||||||
# name: Clippy Lints
|
runs-on: linux
|
||||||
# runs-on: linux
|
container: node:18
|
||||||
# container: node:18
|
steps:
|
||||||
# steps:
|
- uses: actions/checkout@v4
|
||||||
# - uses: actions/checkout@v2
|
with:
|
||||||
# with:
|
fetch-depth: 0
|
||||||
# fetch-depth: 0
|
- name: Install system dependencies
|
||||||
# - name: Install system dependencies
|
run: |
|
||||||
# run: |
|
apt-get update
|
||||||
# apt-get update
|
apt-get install -y libsystemd-dev pkg-config
|
||||||
# apt-get install -y libsystemd-dev pkg-config
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
# - uses: dtolnay/rust-toolchain@stable
|
with:
|
||||||
# with:
|
components: clippy
|
||||||
# components: clippy
|
- name: Cache cargo
|
||||||
# - name: Cache cargo
|
uses: Swatinem/rust-cache@v2
|
||||||
# uses: Swatinem/rust-cache@v2
|
- name: Run clippy
|
||||||
# - name: Run clippy
|
run: cargo clippy --all-targets --all-features -- -D warnings
|
||||||
# run: cargo clippy --all-targets --all-features -- -D warnings
|
|
||||||
#
|
test:
|
||||||
# test:
|
name: Unit Tests
|
||||||
# name: Unit Tests
|
runs-on: linux
|
||||||
# runs-on: linux
|
container: node:18
|
||||||
# container: node:18
|
steps:
|
||||||
# steps:
|
- uses: actions/checkout@v4
|
||||||
# - uses: actions/checkout@v2
|
with:
|
||||||
# with:
|
fetch-depth: 0
|
||||||
# fetch-depth: 0
|
- name: Install system dependencies
|
||||||
# - name: Install system dependencies
|
run: |
|
||||||
# run: |
|
apt-get update
|
||||||
# apt-get update
|
apt-get install -y libsystemd-dev pkg-config
|
||||||
# apt-get install -y libsystemd-dev pkg-config
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
# - uses: dtolnay/rust-toolchain@stable
|
- name: Cache cargo
|
||||||
# - name: Cache cargo
|
uses: Swatinem/rust-cache@v2
|
||||||
# uses: Swatinem/rust-cache@v2
|
- name: Run tests
|
||||||
# - name: Run tests
|
run: cargo test --all-features
|
||||||
# run: cargo test --all-features
|
|
||||||
# - name: Upload coverage
|
audit:
|
||||||
# uses: codecov/codecov-action@v4
|
name: Security Audit
|
||||||
# if: always()
|
runs-on: linux
|
||||||
#
|
container: node:18
|
||||||
# audit:
|
steps:
|
||||||
# name: Security Audit
|
- uses: actions/checkout@v4
|
||||||
# runs-on: linux
|
with:
|
||||||
# container: node:18
|
fetch-depth: 0
|
||||||
# steps:
|
- name: Install system dependencies
|
||||||
# - uses: actions/checkout@v2
|
run: |
|
||||||
# with:
|
apt-get update
|
||||||
# fetch-depth: 0
|
apt-get install -y libsystemd-dev pkg-config
|
||||||
# - name: Install system dependencies
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
# run: |
|
- name: Run cargo-audit
|
||||||
# apt-get update
|
run: |
|
||||||
# apt-get install -y libsystemd-dev pkg-config
|
cargo install cargo-audit
|
||||||
# - uses: dtolnay/rust-toolchain@stable
|
cargo audit
|
||||||
# - name: Run cargo-audit
|
|
||||||
# run: |
|
|
||||||
# cargo install cargo-audit
|
|
||||||
# cargo audit
|
|
||||||
# Debian/Ubuntu Package Build
|
|
||||||
build-deb:
|
build-deb:
|
||||||
name: Build Debian Package
|
name: Build Debian Package
|
||||||
runs-on: linux
|
runs-on: linux
|
||||||
container: debian:bookworm
|
container: node:18-bookworm
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -113,7 +109,7 @@ jobs:
|
|||||||
build-rpm:
|
build-rpm:
|
||||||
name: Build RPM Package
|
name: Build RPM Package
|
||||||
runs-on: linux
|
runs-on: linux
|
||||||
container: fedora:latest
|
container: linux-patch-api-rpm:latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -121,7 +117,7 @@ jobs:
|
|||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- name: Install RPM build tools
|
- name: Install RPM build tools
|
||||||
run: |
|
run: |
|
||||||
dnf install -y rpm-build gcc cargo rust libsystemd-devel pkgconfig-pkg-config
|
dnf install -y rpm-build gcc cargo rust systemd-devel pkg-config
|
||||||
- name: Build release binary
|
- name: Build release binary
|
||||||
run: cargo build --release
|
run: cargo build --release
|
||||||
- name: Build RPM package
|
- name: Build RPM package
|
||||||
@ -136,14 +132,22 @@ jobs:
|
|||||||
build-apk:
|
build-apk:
|
||||||
name: Build Alpine Package
|
name: Build Alpine Package
|
||||||
runs-on: linux
|
runs-on: linux
|
||||||
container: alpine:latest
|
container: node:18-alpine
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
- name: Install Rust toolchain (rustup for edition2024 support)
|
||||||
|
run: |
|
||||||
|
apk add --no-cache curl
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
|
||||||
|
source $HOME/.cargo/env
|
||||||
|
rustc --version
|
||||||
|
cargo --version
|
||||||
- name: Install build dependencies
|
- name: Install build dependencies
|
||||||
run: |
|
run: |
|
||||||
apk add --no-cache rust cargo musl-dev openssl-dev systemd-dev git abuild
|
apk add --no-cache musl-dev openssl-dev git abuild gcc elogind-dev
|
||||||
|
# NOTE: abuild-keygen is now done inside build-alpine.sh to ensure keys persist in same shell session
|
||||||
- name: Build APK package
|
- name: Build APK package
|
||||||
run: ./build-alpine.sh
|
run: ./build-alpine.sh
|
||||||
- name: Upload to releases (on tag)
|
- name: Upload to releases (on tag)
|
||||||
@ -156,7 +160,7 @@ jobs:
|
|||||||
build-arch:
|
build-arch:
|
||||||
name: Build Arch Package
|
name: Build Arch Package
|
||||||
runs-on: linux
|
runs-on: linux
|
||||||
container: archlinux:latest
|
container: linux-patch-api-arch:latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## System Overview
|
## System Overview
|
||||||
|
|
||||||
The Linux_Patch_API is a secure, single-host API service that enables remote package and patch management on Linux systems. Each instance runs as a systemd service on the managed host, providing a REST API over mTLS with strict IP whitelist enforcement.
|
The Linux_Patch_API is a secure, single-host API service that enables remote package and patch management on Linux systems. Each instance runs as a system service on the managed host (systemd on most distributions, OpenRC on Alpine), providing a REST API over mTLS with strict IP whitelist enforcement.
|
||||||
|
|
||||||
**Architecture Type:** Agent Per Host (Option B)
|
**Architecture Type:** Agent Per Host (Option B)
|
||||||
**Deployment:** One instance per managed Linux host
|
**Deployment:** One instance per managed Linux host
|
||||||
@ -45,8 +45,9 @@ The Linux_Patch_API is a secure, single-host API service that enables remote pac
|
|||||||
- Distribution detection and adapter selection
|
- Distribution detection and adapter selection
|
||||||
|
|
||||||
6. **Audit Logger**
|
6. **Audit Logger**
|
||||||
- systemd journal integration (primary)
|
- System logging integration (primary)
|
||||||
- Optional remote syslog server
|
- systemd journal on systemd-based systems
|
||||||
|
- syslog/local files on OpenRC-based systems
|
||||||
- Local file fallback (`/var/log/linux_patch_api/`)
|
- Local file fallback (`/var/log/linux_patch_api/`)
|
||||||
- 30-day retention with daily rotation and gzip compression
|
- 30-day retention with daily rotation and gzip compression
|
||||||
|
|
||||||
@ -59,9 +60,10 @@ The Linux_Patch_API is a secure, single-host API service that enables remote pac
|
|||||||
### External Integrations
|
### External Integrations
|
||||||
|
|
||||||
- **Package Managers:** apt, dnf, yum, apk, pacman (via system commands)
|
- **Package Managers:** apt, dnf, yum, apk, pacman (via system commands)
|
||||||
- **systemd:** Service management and journal logging
|
- **Init System:** Service management and logging
|
||||||
|
- systemd (Debian, Ubuntu, RHEL, CentOS, Fedora)
|
||||||
|
- OpenRC (Alpine Linux)
|
||||||
- **Internal CA:** Certificate validation against self-hosted CA
|
- **Internal CA:** Certificate validation against self-hosted CA
|
||||||
- **Remote Syslog:** Optional external log aggregation
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -74,14 +76,17 @@ The Linux_Patch_API is a secure, single-host API service that enables remote pac
|
|||||||
- **mTLS:** Rust TLS library (rustls or native-tls)
|
- **mTLS:** Rust TLS library (rustls or native-tls)
|
||||||
|
|
||||||
### Infrastructure
|
### Infrastructure
|
||||||
- **Service Manager:** systemd
|
- **Service Manager:** Distribution-dependent
|
||||||
|
- systemd (most distributions)
|
||||||
|
- OpenRC (Alpine Linux)
|
||||||
- **Configuration:** YAML
|
- **Configuration:** YAML
|
||||||
- **Logging:** systemd journal + optional syslog
|
|
||||||
|
|
||||||
### Deployment
|
### Deployment
|
||||||
- **Package Format:** Native Linux packages (deb, rpm, apk, pkg.tar.zst)
|
- **Package Format:** Native Linux packages (deb, rpm, apk, pkg.tar.zst)
|
||||||
- **Distribution:** Via target system package manager (apt, dnf, apk, pacman)
|
- **Distribution:** Via target system package manager (apt, dnf, apk, pacman)
|
||||||
- **Installation:** Package installs binary, systemd service, and default config structure
|
- **Installation:** Package installs binary, init script/service, and default config structure
|
||||||
|
- systemd unit file for systemd distributions
|
||||||
|
- OpenRC init script for Alpine
|
||||||
- **Updates:** Handled through system package manager
|
- **Updates:** Handled through system package manager
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -99,16 +104,21 @@ The Linux_Patch_API is a secure, single-host API service that enables remote pac
|
|||||||
- No granular permissions (binary access: allowed or denied)
|
- No granular permissions (binary access: allowed or denied)
|
||||||
- Whitelisted IP + valid cert = full API access
|
- Whitelisted IP + valid cert = full API access
|
||||||
|
|
||||||
### Process Security (systemd Hardening)
|
### Process Security (Init System Hardening)
|
||||||
- **User:** root (required for package management)
|
- **User:** root (required for package management)
|
||||||
- **NoNewPrivileges:** true (prevent privilege escalation)
|
|
||||||
- **ProtectSystem:** strict (read-only filesystem except allowed paths)
|
|
||||||
- **ProtectHome:** true (no access to /home, /root, /run/user)
|
|
||||||
- **PrivateTmp:** true (isolated /tmp)
|
|
||||||
- **SystemCallFilter:** Restrict to required syscalls only (application whitelist)
|
|
||||||
- **RestrictAddressFamilies:** AF_INET, AF_INET6, AF_UNIX (network restrictions)
|
|
||||||
- **CapabilityBoundingSet:** CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN (minimal capabilities)
|
|
||||||
|
|
||||||
|
**systemd Hardening Options:**
|
||||||
|
- NoNewPrivileges: true (prevent privilege escalation)
|
||||||
|
- ProtectSystem: strict (read-only filesystem except allowed paths)
|
||||||
|
- ProtectHome: true (no access to /home, /root, /run/user)
|
||||||
|
- PrivateTmp: true (isolated /tmp)
|
||||||
|
- SystemCallFilter: Restrict to required syscalls only (application whitelist)
|
||||||
|
|
||||||
|
**OpenRC Hardening Options:**
|
||||||
|
- Run as dedicated service user
|
||||||
|
- File permission restrictions
|
||||||
|
- chroot isolation (optional)
|
||||||
|
- Equivalent security via rc.conf and init script options
|
||||||
### Data Security
|
### Data Security
|
||||||
- All communications encrypted via TLS
|
- All communications encrypted via TLS
|
||||||
- Certificates stored securely with restricted permissions
|
- Certificates stored securely with restricted permissions
|
||||||
@ -149,7 +159,9 @@ The Linux_Patch_API is a secure, single-host API service that enables remote pac
|
|||||||
└── audit.log # Local audit log fallback
|
└── audit.log # Local audit log fallback
|
||||||
|
|
||||||
/usr/bin/linux-patch-api # Binary location
|
/usr/bin/linux-patch-api # Binary location
|
||||||
/etc/systemd/system/linux-patch-api.service # Systemd service
|
Init scripts (distribution-dependent):
|
||||||
|
- /etc/systemd/system/linux-patch-api.service # systemd
|
||||||
|
- /etc/init.d/linux-patch-api # OpenRC (Alpine)
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
13
Dockerfile.arch
Normal file
13
Dockerfile.arch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Arch Linux container with Node.js for GitHub Actions support
|
||||||
|
# Used for Arch package builds in CI/CD
|
||||||
|
FROM archlinux:latest
|
||||||
|
|
||||||
|
# Update system and install Node.js (required for GitHub Actions JavaScript-based actions)
|
||||||
|
RUN pacman -Syu --noconfirm nodejs npm && \
|
||||||
|
pacman -Scc --noconfirm
|
||||||
|
|
||||||
|
# Verify node is available
|
||||||
|
RUN node --version
|
||||||
|
|
||||||
|
# Default command (not used in CI, but good for testing)
|
||||||
|
CMD ["/bin/bash"]
|
||||||
14
Dockerfile.rpm
Normal file
14
Dockerfile.rpm
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Fedora container with Node.js for GitHub Actions support
|
||||||
|
# Used for RPM package builds in CI/CD
|
||||||
|
FROM fedora:latest
|
||||||
|
|
||||||
|
# Install Node.js (required for GitHub Actions JavaScript-based actions)
|
||||||
|
# Also install dnf-plugins-core for potential multiarch support
|
||||||
|
RUN dnf install -y nodejs dnf-plugins-core && \
|
||||||
|
dnf clean all
|
||||||
|
|
||||||
|
# Verify node is available
|
||||||
|
RUN node --version
|
||||||
|
|
||||||
|
# Default command (not used in CI, but good for testing)
|
||||||
|
CMD ["/bin/bash"]
|
||||||
18
SPEC.md
18
SPEC.md
@ -41,7 +41,9 @@
|
|||||||
**Primary Objective:** Provide secure API for remote patch/package management on individual Linux hosts
|
**Primary Objective:** Provide secure API for remote patch/package management on individual Linux hosts
|
||||||
|
|
||||||
**Key Goals:**
|
**Key Goals:**
|
||||||
- Run as systemd service on each managed machine (Option B: Agent Per Host)
|
- Run as a system service on each managed machine (Option B: Agent Per Host)
|
||||||
|
- systemd for Debian/Ubuntu, RHEL/CentOS/Fedora
|
||||||
|
- OpenRC for Alpine Linux
|
||||||
- Internal network access only (no internet exposure)
|
- Internal network access only (no internet exposure)
|
||||||
- Support Debian/Ubuntu first, then expand to other distributions
|
- Support Debian/Ubuntu first, then expand to other distributions
|
||||||
- Maintain audit trail of all operations
|
- Maintain audit trail of all operations
|
||||||
@ -55,7 +57,9 @@
|
|||||||
- One API instance per host
|
- One API instance per host
|
||||||
- Internal network only (LAN/private network)
|
- Internal network only (LAN/private network)
|
||||||
- No public internet exposure
|
- No public internet exposure
|
||||||
- Must run as systemd service
|
- Must run as a system service (init system determined by distribution)
|
||||||
|
- systemd: Debian, Ubuntu, RHEL, CentOS, Fedora
|
||||||
|
- OpenRC: Alpine Linux
|
||||||
|
|
||||||
**Technical:**
|
**Technical:**
|
||||||
- Must run with elevated privileges for package management (root/sudo)
|
- Must run with elevated privileges for package management (root/sudo)
|
||||||
@ -119,7 +123,9 @@
|
|||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
- Linux OS with package manager support
|
- Linux OS with package manager support
|
||||||
- systemd for service management
|
- Init system for service management (distribution-dependent)
|
||||||
|
- systemd (most distributions)
|
||||||
|
- OpenRC (Alpine Linux)
|
||||||
- Network access for API communication
|
- Network access for API communication
|
||||||
- mTLS certificate infrastructure (CA, client certs)
|
- mTLS certificate infrastructure (CA, client certs)
|
||||||
- IP whitelist configuration
|
- IP whitelist configuration
|
||||||
@ -147,8 +153,10 @@
|
|||||||
- Configuration changes (whitelist updates, cert renewals)
|
- Configuration changes (whitelist updates, cert renewals)
|
||||||
|
|
||||||
- **Log Storage:**
|
- **Log Storage:**
|
||||||
- Primary: systemd journal (`journalctl`)
|
- Primary: Distribution-appropriate logging
|
||||||
- Secondary: Optional remote syslog server
|
- systemd journal (journalctl) on systemd systems
|
||||||
|
- syslog/local files on OpenRC systems
|
||||||
|
- Secondary: Optional remote syslog server (universal)
|
||||||
- Local file logs as fallback (`/var/log/linux_patch_api/`)
|
- Local file logs as fallback (`/var/log/linux_patch_api/`)
|
||||||
|
|
||||||
- **Log Retention:**
|
- **Log Retention:**
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
# Build Alpine Package (.apk)
|
# Build Alpine Package (.apk)
|
||||||
# Run on: Alpine Linux 3.18+
|
# Run on: Alpine Linux 3.18+
|
||||||
# Or in Docker: docker run -v $(pwd):/build alpine:latest /build/build-alpine.sh
|
# Or in Docker: docker run -v $(pwd):/build alpine:latest /build/build-alpine.sh
|
||||||
@ -8,12 +8,34 @@ set -e
|
|||||||
echo "=== Linux Patch API - Alpine Build Script ==="
|
echo "=== Linux Patch API - Alpine Build Script ==="
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# Source cargo environment (for rustup-installed toolchain in CI)
|
||||||
|
if [ -f "$HOME/.cargo/env" ]; then
|
||||||
|
. "$HOME/.cargo/env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if running on Alpine
|
||||||
|
|
||||||
|
# Check if running on Alpine
|
||||||
# Check if running on Alpine
|
# Check if running on Alpine
|
||||||
if ! command -v abuild &> /dev/null; then
|
if ! command -v abuild &> /dev/null; then
|
||||||
echo "Installing Alpine build tools..."
|
echo "Installing Alpine build tools..."
|
||||||
apk add --no-cache alpine-sdk rust cargo openssl-dev systemd-dev git
|
apk add --no-cache alpine-sdk rust cargo openssl-dev openrc git
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Generate abuild signing keys (ALWAYS generate fresh - same shell session as abuild commands)
|
||||||
|
echo "Generating abuild signing keys..."
|
||||||
|
apk add --no-cache abuild
|
||||||
|
abuild-keygen -a -n 2>&1 | tee /tmp/keygen.log
|
||||||
|
# Find the actual key file (handles missing username prefix)
|
||||||
|
KEYFILE=$(ls /root/.abuild/*.rsa 2>/dev/null | head -1)
|
||||||
|
if [ -z "$KEYFILE" ]; then
|
||||||
|
KEYFILE=$(ls /root/.abuild/-*.rsa 2>/dev/null | head -1)
|
||||||
|
fi
|
||||||
|
echo "Found key: $KEYFILE"
|
||||||
|
# Write directly to abuild.conf (overwrite any stale config)
|
||||||
|
echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /etc/abuild.conf
|
||||||
|
cat /etc/abuild.conf
|
||||||
|
|
||||||
# Setup build environment
|
# Setup build environment
|
||||||
echo "Setting up build environment..."
|
echo "Setting up build environment..."
|
||||||
export CBUILDROOT=$(pwd)/.abuild
|
export CBUILDROOT=$(pwd)/.abuild
|
||||||
@ -27,13 +49,13 @@ cargo build --release --target x86_64-unknown-linux-musl
|
|||||||
PKGDIR=$(pwd)/apk-package
|
PKGDIR=$(pwd)/apk-package
|
||||||
mkdir -p "$PKGDIR"/usr/bin
|
mkdir -p "$PKGDIR"/usr/bin
|
||||||
mkdir -p "$PKGDIR"/etc/linux_patch_api
|
mkdir -p "$PKGDIR"/etc/linux_patch_api
|
||||||
mkdir -p "$PKGDIR"/lib/systemd/system
|
mkdir -p "$PKGDIR"/etc/init.d
|
||||||
|
|
||||||
# Copy files
|
# Copy files
|
||||||
cp target/x86_64-unknown-linux-musl/release/linux-patch-api "$PKGDIR"/usr/bin/
|
cp target/x86_64-unknown-linux-musl/release/linux-patch-api "$PKGDIR"/usr/bin/
|
||||||
chmod 755 "$PKGDIR"/usr/bin/linux-patch-api
|
chmod 755 "$PKGDIR"/usr/bin/linux-patch-api
|
||||||
cp configs/linux-patch-api.service "$PKGDIR"/lib/systemd/system/
|
cp configs/linux-patch-api-openrc "$PKGDIR"/etc/init.d/linux-patch-api
|
||||||
cp configs/config.yaml.example "$PKGDIR"/etc/linux_patch_api/config.yaml
|
chmod 755 "$PKGDIR"/etc/init.d/linux-patch-api
|
||||||
cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml
|
cp configs/whitelist.yaml.example "$PKGDIR"/etc/linux_patch_api/whitelist.yaml
|
||||||
|
|
||||||
# Create APKBUILD
|
# Create APKBUILD
|
||||||
@ -46,17 +68,60 @@ pkgdesc="Secure remote package management API for Linux systems"
|
|||||||
url="https://gitea.internal/linux-patch-api"
|
url="https://gitea.internal/linux-patch-api"
|
||||||
arch="x86_64"
|
arch="x86_64"
|
||||||
license="MIT"
|
license="MIT"
|
||||||
depends="systemd"
|
makedepends=""
|
||||||
source="apk-package"
|
depends="openrc"
|
||||||
|
source=""
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
cp -r "$srcdir"/apk-package/* "$pkgdir"/
|
# Create directory structure in pkgdir
|
||||||
|
install -d "$pkgdir"/usr/bin
|
||||||
|
install -d "$pkgdir"/etc/linux_patch_api
|
||||||
|
install -d "$pkgdir"/etc/init.d
|
||||||
|
# Copy from pre-built apk-package directory
|
||||||
|
cp -r /workspace/echo/linux_patch_api/apk-package/usr/bin/* "$pkgdir"/usr/bin/
|
||||||
|
cp -r /workspace/echo/linux_patch_api/apk-package/etc/linux_patch_api/* "$pkgdir"/etc/linux_patch_api/
|
||||||
|
cp -r /workspace/echo/linux_patch_api/apk-package/etc/init.d/* "$pkgdir"/etc/init.d/
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# Generate checksums for APKBUILD sources
|
||||||
|
echo "Generating checksums..."
|
||||||
|
|
||||||
# Build APK package
|
# Build APK package
|
||||||
echo "Building APK package..."
|
echo "Building APK package..."
|
||||||
abuild -F -r
|
|
||||||
|
# For CI/container environments where we run as root, create a build user
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
echo "Running as root - creating build user for abuild..."
|
||||||
|
adduser -D -s /bin/sh builduser 2>/dev/null || true
|
||||||
|
# CRITICAL: Add builduser to abuild group (required for apk install permissions)
|
||||||
|
addgroup builduser abuild 2>/dev/null || usermod -aG abuild builduser
|
||||||
|
chown -R builduser:builduser "$(pwd)"
|
||||||
|
chown -R builduser:builduser /root/packages 2>/dev/null || true
|
||||||
|
# Copy abuild keys from root to builduser home
|
||||||
|
mkdir -p /home/builduser/.abuild
|
||||||
|
cp /root/.abuild/* /home/builduser/.abuild/
|
||||||
|
chown -R builduser:builduser /home/builduser/.abuild
|
||||||
|
|
||||||
|
# Find the actual key file
|
||||||
|
KEYFILE=$(ls /home/builduser/.abuild/*.rsa 2>/dev/null | head -1)
|
||||||
|
if [ -z "$KEYFILE" ]; then
|
||||||
|
KEYFILE=$(ls /home/builduser/.abuild/-*.rsa 2>/dev/null | head -1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Key file: $KEYFILE"
|
||||||
|
echo "Key file exists: $(test -f "$KEYFILE" && echo YES || echo NO)"
|
||||||
|
|
||||||
|
# CRITICAL: Write to builduser's PERSONAL abuild.conf (~/.abuild/abuild.conf)
|
||||||
|
# abuild reads this when running as builduser - standard behavior, no shell quoting issues!
|
||||||
|
echo "PACKAGER_PRIVKEY=\"$KEYFILE\"" > /home/builduser/.abuild/abuild.conf
|
||||||
|
chown builduser:builduser /home/builduser/.abuild/abuild.conf
|
||||||
|
su - builduser -c "cd $(pwd) && abuild checksum && abuild -d -F && cp /home/builduser/packages/x86_64/*.apk ./releases/ 2>/dev/null || cp /home/builduser/packages/*.apk ./releases/ 2>/dev/null || ls -la /home/builduser/packages/"
|
||||||
|
else
|
||||||
|
abuild checksum
|
||||||
|
abuild -F -r
|
||||||
|
cp ~/packages/x86_64/*.apk releases/ 2>/dev/null || cp ~/packages/*.apk releases/ 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
# Copy to releases directory
|
# Copy to releases directory
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@ -43,24 +43,34 @@ pkgname=linux-patch-api
|
|||||||
pkgver=1.0.0
|
pkgver=1.0.0
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Secure remote package management API for Linux systems"
|
pkgdesc="Secure remote package management API for Linux systems"
|
||||||
url="https://gitea.internal/linux-patch-api"
|
url="https://gitea.moon-dragon.us/echo/linux_patch_api"
|
||||||
arch=('x86_64')
|
arch=('x86_64')
|
||||||
license=('MIT')
|
license=('MIT')
|
||||||
depends=('systemd')
|
depends=('systemd')
|
||||||
source=('arch-package')
|
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
cp -r "$srcdir"/arch-package/* "$pkgdir"/
|
# Use absolute path since makepkg changes working directory to srcdir
|
||||||
|
cp -r /workspace/echo/linux_patch_api/arch-package/* "$pkgdir"/
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create .SRCINFO
|
# Create .SRCINFO
|
||||||
echo "Creating .SRCINFO..."
|
echo "Creating .SRCINFO..."
|
||||||
makepkg --printsrcinfo > .SRCINFO
|
|
||||||
|
|
||||||
# Build package
|
# Build package
|
||||||
echo "Building Arch package..."
|
echo "Building Arch package..."
|
||||||
makepkg -f --noconfirm
|
|
||||||
|
# For CI/container environments where we run as root, create a build user
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
echo "Running as root - creating build user for makepkg..."
|
||||||
|
useradd -m builduser 2>/dev/null || true
|
||||||
|
chown -R builduser:builduser "$(pwd)"
|
||||||
|
su - builduser -c "cd $(pwd) && makepkg --printsrcinfo > .SRCINFO"
|
||||||
|
su - builduser -c "cd $(pwd) && makepkg -f --noconfirm"
|
||||||
|
else
|
||||||
|
makepkg --printsrcinfo > .SRCINFO
|
||||||
|
makepkg -f --noconfirm
|
||||||
|
fi
|
||||||
|
|
||||||
# Copy to releases directory
|
# Copy to releases directory
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
72
configs/linux-patch-api-openrc
Normal file
72
configs/linux-patch-api-openrc
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
# OpenRC init script for linux-patch-api
|
||||||
|
# Used on Alpine Linux and other OpenRC-based systems
|
||||||
|
|
||||||
|
name="linux_patch_api"
|
||||||
|
command="/usr/bin/linux-patch-api"
|
||||||
|
command_args="--config /etc/linux_patch_api/config.yaml"
|
||||||
|
command_background=true
|
||||||
|
pidfile="/run/linux-patch-api/linux-patch-api.pid"
|
||||||
|
output_log="/var/log/linux_patch_api/linux-patch-api.log"
|
||||||
|
error_log="/var/log/linux_patch_api/linux-patch-api.err"
|
||||||
|
|
||||||
|
# Required dependencies
|
||||||
|
depend() {
|
||||||
|
use net logger
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create required directories before starting
|
||||||
|
start_pre() {
|
||||||
|
checkpath --directory --owner linux-patch-api:linux-patch-api --mode 0755 \
|
||||||
|
/run/linux-patch-api \
|
||||||
|
/var/log/linux-patch-api \
|
||||||
|
/var/lib/linux-patch-api \
|
||||||
|
/etc/linux_patch_api/certs
|
||||||
|
|
||||||
|
# Ensure config files exist
|
||||||
|
if [ ! -f "/etc/linux_patch_api/config.yaml" ]; then
|
||||||
|
eerror "Configuration file missing: /etc/linux_patch_api/config.yaml"
|
||||||
|
eerror "Please create config.yaml before starting the service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "/etc/linux_patch_api/whitelist.yaml" ]; then
|
||||||
|
eerror "Whitelist file missing: /etc/linux_patch_api/whitelist.yaml"
|
||||||
|
eerror "Please create whitelist.yaml before starting the service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify service started successfully
|
||||||
|
start_post() {
|
||||||
|
sleep 2
|
||||||
|
if [ -f "$pidfile" ]; then
|
||||||
|
einfo "linux-patch-api started successfully (PID: $(cat $pidfile))"
|
||||||
|
else
|
||||||
|
ewarn "linux-patch-api may not have started correctly - pidfile not found"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean shutdown
|
||||||
|
stop_pre() {
|
||||||
|
einfo "Stopping linux-patch-api service..."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify service stopped
|
||||||
|
stop_post() {
|
||||||
|
if [ -f "$pidfile" ]; then
|
||||||
|
rm -f "$pidfile"
|
||||||
|
fi
|
||||||
|
einfo "linux-patch-api stopped"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Service status
|
||||||
|
status() {
|
||||||
|
if [ -f "$pidfile" ] && kill -0 $(cat "$pidfile") 2>/dev/null; then
|
||||||
|
einfo "linux-patch-api is running (PID: $(cat $pidfile))"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
eerror "linux-patch-api is not running"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
%global debug_package %{nil}
|
||||||
|
|
||||||
Name: linux-patch-api
|
Name: linux-patch-api
|
||||||
Version: 1.0.0
|
Version: 1.0.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
|
|||||||
Reference in New Issue
Block a user