Private
Public Access
1
0

fix: RPM packaging - pre-build binary, fix ownership, fix deps, prevent stale cache

This commit is contained in:
2026-05-20 19:45:38 +00:00
parent 21d01179d6
commit ee46c48c0b
5 changed files with 129 additions and 18 deletions

View File

@ -249,19 +249,46 @@ jobs:
- name: Install build dependencies - name: Install build dependencies
run: | run: |
sudo dnf install -y gcc rpm-build systemd-devel pkg-config openssl-devel sudo dnf install -y gcc rpm-build systemd-devel pkg-config openssl-devel
- name: Clean stale RPM artifacts
run: |
rm -f ~/rpmbuild/RPMS/x86_64/linux-patch-api-*.rpm
rm -f releases/linux-patch-api-*.rpm
- name: Build release binary - name: Build release binary
run: cargo build --release run: cargo build --release
- name: Build RPM package - name: Build RPM package
run: | run: |
chmod +x build-rpm.sh chmod +x build-rpm.sh
./build-rpm.sh SKIP_CARGO_BUILD=1 ./build-rpm.sh
- name: Verify RPM package
run: |
VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*=.*"\([^"]*\)".*/\1/')
RPM_FILE=$(ls ~/rpmbuild/RPMS/x86_64/linux-patch-api-${VERSION}-*.rpm 2>/dev/null | head -1)
if [ -z "$RPM_FILE" ]; then
echo "ERROR: RPM package not found for version $VERSION!"
ls -la ~/rpmbuild/RPMS/x86_64/ 2>/dev/null || echo "RPM directory empty or missing"
exit 1
fi
RPM_VERSION=$(rpm -qp --queryformat '%{VERSION}' "$RPM_FILE" 2>/dev/null || true)
echo "RPM file: $RPM_FILE"
echo "RPM version: $RPM_VERSION"
echo "Expected version: $VERSION"
if [ "$RPM_VERSION" != "$VERSION" ]; then
echo "ERROR: RPM version ($RPM_VERSION) does not match expected version ($VERSION)!"
exit 1
fi
echo "RPM verification passed"
- name: Upload to Gitea Release - name: Upload to Gitea Release
if: github.ref_type == 'tag' if: github.ref_type == 'tag'
env: env:
GITEA_TOKEN: ${{ secrets.GITEATOKEN }} GITEA_TOKEN: ${{ secrets.GITEATOKEN }}
run: | run: |
TAG_NAME=${GITHUB_REF#refs/tags/} TAG_NAME=${GITHUB_REF#refs/tags/}
FILE=$(ls ~/rpmbuild/RPMS/x86_64/*.rpm 2>/dev/null | head -1) VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*=.*"\([^"]*\)".*/\1/')
FILE=$(ls ~/rpmbuild/RPMS/x86_64/linux-patch-api-${VERSION}-*.rpm 2>/dev/null | head -1)
if [ -z "$FILE" ]; then
echo "ERROR: No RPM found with version $VERSION for upload!"
exit 1
fi
chmod +x scripts/upload-release.sh chmod +x scripts/upload-release.sh
./scripts/upload-release.sh "$TAG_NAME" "$FILE" ./scripts/upload-release.sh "$TAG_NAME" "$FILE"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "linux-patch-api" name = "linux-patch-api"
version = "1.1.13" version = "1.1.14"
edition = "2021" edition = "2021"
authors = ["Echo <echo@moon-dragon.us>"] authors = ["Echo <echo@moon-dragon.us>"]
description = "Secure remote package management API for Linux systems" description = "Secure remote package management API for Linux systems"

View File

@ -2,19 +2,29 @@
# Build RPM Package for RHEL/CentOS/Fedora # Build RPM Package for RHEL/CentOS/Fedora
# Run on: RHEL 8/9, CentOS 8/9, Fedora 38+ # Run on: RHEL 8/9, CentOS 8/9, Fedora 38+
# Designed for native Gitea Actions runner execution # Designed for native Gitea Actions runner execution
#
# Build pattern: Pre-build binary BEFORE creating tarball (like Alpine/Arch)
# The binary is included in the source tarball so rpmbuild's %build
# section is a no-op. This avoids PATH issues where rpmbuild can't find
# cargo installed via rustup.
set -e set -e
echo "=== Linux Patch API - RPM Build Script ===" echo "=== Linux Patch API - RPM 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 RPM-based system # Check if running on RPM-based system
if ! command -v rpmbuild &> /dev/null; then if ! command -v rpmbuild &> /dev/null; then
echo "Installing RPM build tools..." echo "Installing RPM build tools..."
if command -v dnf &> /dev/null; then if command -v dnf &> /dev/null; then
dnf install -y rpm-build cargo rust gcc systemd-devel dnf install -y rpm-build
elif command -v yum &> /dev/null; then elif command -v yum &> /dev/null; then
yum install -y rpm-build cargo rust gcc systemd-devel yum install -y rpm-build
else else
echo "Error: Cannot install rpm-build. Please install manually." echo "Error: Cannot install rpm-build. Please install manually."
exit 1 exit 1
@ -23,13 +33,38 @@ fi
# Get version from Cargo.toml # Get version from Cargo.toml
VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*=.*"\([^"]*\)".*/\1/') VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*=.*"\([^"]*\)".*/\1/')
if [ -z "$VERSION" ]; then
echo "Error: Could not determine version from Cargo.toml"
exit 1
fi
echo "Building version: $VERSION" echo "Building version: $VERSION"
# Remove stale RPM artifacts to prevent uploading cached/old packages
echo "Cleaning stale RPM artifacts..."
rm -f ~/rpmbuild/RPMS/x86_64/linux-patch-api-*.rpm
rm -f releases/linux-patch-api-*.rpm
# Build release binary (skip if already built by CI)
if [ -z "$SKIP_CARGO_BUILD" ]; then
echo "Building release binary..."
cargo build --release
else
echo "Skipping cargo build (SKIP_CARGO_BUILD is set)"
fi
# Verify binary exists
if [ ! -f "target/release/linux-patch-api" ]; then
echo "Error: Pre-built binary not found at target/release/linux-patch-api"
echo "Run 'cargo build --release' first or unset SKIP_CARGO_BUILD"
exit 1
fi
# Setup RPM build directory structure # Setup RPM build directory structure
mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
# Create source tarball (required by %autosetup in spec file) # Create source tarball with pre-built binary included
echo "Creating source tarball..." # (required by %autosetup in spec file)
echo "Creating source tarball with pre-built binary..."
TMPDIR=$(mktemp -d) TMPDIR=$(mktemp -d)
mkdir -p "$TMPDIR/linux-patch-api-${VERSION}" mkdir -p "$TMPDIR/linux-patch-api-${VERSION}"
@ -47,6 +82,12 @@ rm -rf "$TMPDIR/linux-patch-api-${VERSION}/.abuild"
rm -rf "$TMPDIR/linux-patch-api-${VERSION}/apk-package" rm -rf "$TMPDIR/linux-patch-api-${VERSION}/apk-package"
rm -rf "$TMPDIR/linux-patch-api-${VERSION}/.a0proj" rm -rf "$TMPDIR/linux-patch-api-${VERSION}/.a0proj"
# Re-create target/release with just the pre-built binary
# This is the key change: binary is in the tarball so %build is a no-op
mkdir -p "$TMPDIR/linux-patch-api-${VERSION}/target/release"
cp target/release/linux-patch-api "$TMPDIR/linux-patch-api-${VERSION}/target/release/"
chmod 755 "$TMPDIR/linux-patch-api-${VERSION}/target/release/linux-patch-api"
tar -czf ~/rpmbuild/SOURCES/linux-patch-api-${VERSION}.tar.gz -C "$TMPDIR" "linux-patch-api-${VERSION}" tar -czf ~/rpmbuild/SOURCES/linux-patch-api-${VERSION}.tar.gz -C "$TMPDIR" "linux-patch-api-${VERSION}"
rm -rf "$TMPDIR" rm -rf "$TMPDIR"
@ -54,10 +95,35 @@ rm -rf "$TMPDIR"
echo "Preparing spec file..." echo "Preparing spec file..."
sed "s/VERSION_PLACEHOLDER/$VERSION/" linux-patch-api.spec > ~/rpmbuild/SPECS/linux-patch-api.spec sed "s/VERSION_PLACEHOLDER/$VERSION/" linux-patch-api.spec > ~/rpmbuild/SPECS/linux-patch-api.spec
# Verify VERSION replacement succeeded
if grep -q 'VERSION_PLACEHOLDER' ~/rpmbuild/SPECS/linux-patch-api.spec; then
echo "Error: VERSION_PLACEHOLDER not replaced in spec file!"
exit 1
fi
echo "Spec file version verified: $VERSION"
# Build RPM # Build RPM
echo "Building RPM package..." echo "Building RPM package..."
rpmbuild -ba ~/rpmbuild/SPECS/linux-patch-api.spec rpmbuild -ba ~/rpmbuild/SPECS/linux-patch-api.spec
# Verify RPM was actually built
RPM_FILE=$(ls ~/rpmbuild/RPMS/x86_64/linux-patch-api-${VERSION}-*.rpm 2>/dev/null | head -1)
if [ -z "$RPM_FILE" ]; then
echo "Error: RPM package not found after build!"
echo "Looking for: ~/rpmbuild/RPMS/x86_64/linux-patch-api-${VERSION}-*.rpm"
ls -la ~/rpmbuild/RPMS/x86_64/ 2>/dev/null || echo "Directory empty or missing"
exit 1
fi
# Verify RPM contains the correct version
RPM_VERSION=$(rpm -qp --queryformat '%{VERSION}' "$RPM_FILE" 2>/dev/null || true)
echo "RPM built: $RPM_FILE"
echo "RPM version: $RPM_VERSION"
if [ "$RPM_VERSION" != "$VERSION" ]; then
echo "Error: RPM version ($RPM_VERSION) does not match expected version ($VERSION)!"
exit 1
fi
# Copy to releases directory # Copy to releases directory
echo "" echo ""
echo "Copying package to releases/..." echo "Copying package to releases/..."

12
debian/changelog vendored
View File

@ -1,3 +1,15 @@
linux-patch-api (1.1.14) unstable; urgency=medium
* Fix RPM packaging: pre-build binary before tarball (like Alpine/Arch pattern)
* Fix rpmbuild can't find cargo in PATH - binary now included in source tarball
* Fix config file ownership: add %defattr(-,root,root,-) in %files section
* Fix Requires: libsystemd -> systemd-libs for Fedora compatibility
* Remove Requires: systemd (not needed, may not exist in containers)
* Add stale RPM cleanup and version verification to build-rpm.sh
* Support SKIP_CARGO_BUILD=1 like Alpine/Arch builds
-- Echo <echo@moon-dragon.us> Tue, 20 May 2026 14:44:00 -0500
linux-patch-api (1.1.13) unstable; urgency=medium linux-patch-api (1.1.13) unstable; urgency=medium
* Fix APK backend detection for Alpine (/sbin/apk not /usr/bin/apk) * Fix APK backend detection for Alpine (/sbin/apk not /usr/bin/apk)

View File

@ -21,8 +21,7 @@ BuildArch: x86_64
# BuildRequires: pkgconfig(systemd) # BuildRequires: pkgconfig(systemd)
# Runtime requirements # Runtime requirements
Requires: systemd Requires: systemd-libs
Requires: libsystemd
Requires: openssl-libs Requires: openssl-libs
Requires: ca-certificates Requires: ca-certificates
@ -45,10 +44,11 @@ Features:
%prep %prep
%autosetup -n linux-patch-api-%{version} %autosetup -n linux-patch-api-%{version}
# Build # Build - no-op, binary is pre-built and included in source tarball
# The binary is built by build-rpm.sh BEFORE creating the tarball,
# so cargo does not need to be in rpmbuild's PATH.
%build %build
export RUSTFLAGS="-C target-cpu=native" # Binary already built - nothing to do
cargo build --release --target x86_64-unknown-linux-gnu
# Install # Install
%install %install
@ -59,8 +59,8 @@ mkdir -p %{buildroot}/lib/systemd/system
mkdir -p %{buildroot}/var/log/linux_patch_api mkdir -p %{buildroot}/var/log/linux_patch_api
mkdir -p %{buildroot}/var/lib/linux_patch_api mkdir -p %{buildroot}/var/lib/linux_patch_api
# Install binary # Install binary (pre-built, included in tarball at target/release/)
cp target/x86_64-unknown-linux-gnu/release/linux-patch-api %{buildroot}/usr/bin/ cp target/release/linux-patch-api %{buildroot}/usr/bin/
chmod 755 %{buildroot}/usr/bin/linux-patch-api chmod 755 %{buildroot}/usr/bin/linux-patch-api
# Install systemd service # Install systemd service
@ -149,6 +149,7 @@ fi
# Files # Files
%files %files
%defattr(-,root,root,-)
/usr/bin/linux-patch-api /usr/bin/linux-patch-api
/lib/systemd/system/linux-patch-api.service /lib/systemd/system/linux-patch-api.service
%config(noreplace) /etc/linux_patch_api/config.yaml.example %config(noreplace) /etc/linux_patch_api/config.yaml.example
@ -162,6 +163,15 @@ fi
# Changelog # Changelog
%changelog %changelog
* Tue May 20 2026 Echo <echo@moon-dragon.us> - 1.1.14-1
- Fix RPM packaging: pre-build binary before tarball (like Alpine/Arch pattern)
- Fix rpmbuild can't find cargo in PATH - binary now included in source tarball
- Fix config file ownership: add %defattr(-,root,root,-) in %files section
- Fix Requires: libsystemd -> systemd-libs for Fedora compatibility
- Remove Requires: systemd (not needed, may not exist in containers)
- Add stale RPM cleanup and version verification to build-rpm.sh
- Support SKIP_CARGO_BUILD=1 like Alpine/Arch builds
* Wed May 20 2026 Echo <echo@moon-dragon.us> - 1.1.12-1 * Wed May 20 2026 Echo <echo@moon-dragon.us> - 1.1.12-1
- Add APK (Alpine Linux) package manager backend - Add APK (Alpine Linux) package manager backend
- Add machine-id generation to Alpine pre-install script - Add machine-id generation to Alpine pre-install script
@ -198,7 +208,3 @@ fi
- Initial production release - Initial production release
- Secure mTLS-authenticated REST API for remote package management - Secure mTLS-authenticated REST API for remote package management
- 15 API endpoints for package install/remove, patch application, system management - 15 API endpoints for package install/remove, patch application, system management
- Asynchronous job processing with WebSocket status streaming
- IP whitelist enforcement and comprehensive audit logging
- Systemd integration with security hardening
- Supports RHEL 8/9, CentOS 8/9, Fedora 38+