Add fedora rpm building
This commit is contained in:
parent
8c478249d9
commit
4d2250f974
6 changed files with 185 additions and 5 deletions
102
Dockerfile.rpmbuild
Normal file
102
Dockerfile.rpmbuild
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
FROM fedora:42
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
dnf -y update; \
|
||||||
|
dnf -y install \
|
||||||
|
rpm-build \
|
||||||
|
rpmdevtools \
|
||||||
|
redhat-rpm-config \
|
||||||
|
gcc \
|
||||||
|
make \
|
||||||
|
findutils \
|
||||||
|
tar \
|
||||||
|
gzip \
|
||||||
|
rsync \
|
||||||
|
python3 \
|
||||||
|
python3-devel \
|
||||||
|
python3-setuptools \
|
||||||
|
python3-wheel \
|
||||||
|
pyproject-rpm-macros \
|
||||||
|
python3-rpm-macros \
|
||||||
|
python3-yaml \
|
||||||
|
python3-paramiko \
|
||||||
|
openssl-devel \
|
||||||
|
python3-poetry-core ; \
|
||||||
|
dnf -y clean all
|
||||||
|
|
||||||
|
# Build runner script (copies repo, tars, runs rpmbuild)
|
||||||
|
RUN set -eux; cat > /usr/local/bin/build-rpm <<'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SRC="${SRC:-/src}"
|
||||||
|
WORKROOT="${WORKROOT:-/work}"
|
||||||
|
OUT="${OUT:-/out}"
|
||||||
|
DEPS_DIR="${DEPS_DIR:-/deps}"
|
||||||
|
|
||||||
|
# Install jinjaturtle from local rpm
|
||||||
|
# Filter out .src.rpm and debug* subpackages if present.
|
||||||
|
if [ -d "${DEPS_DIR}" ] && compgen -G "${DEPS_DIR}/*.rpm" > /dev/null; then
|
||||||
|
mapfile -t rpms < <(ls -1 "${DEPS_DIR}"/*.rpm | grep -vE '(\.src\.rpm$|-(debuginfo|debugsource)-)')
|
||||||
|
if [ "${#rpms[@]}" -gt 0 ]; then
|
||||||
|
echo "Installing dependency RPMs from ${DEPS_DIR}:"
|
||||||
|
printf ' - %s\n' "${rpms[@]}"
|
||||||
|
dnf -y install "${rpms[@]}"
|
||||||
|
dnf -y clean all
|
||||||
|
else
|
||||||
|
echo "NOTE: Only src/debug RPMs found in ${DEPS_DIR}; nothing installed." >&2
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "NOTE: No RPMs found in ${DEPS_DIR}. If the build fails with missing python3dist(jinjaturtle)," >&2
|
||||||
|
echo " mount your jinjaturtle RPM directory as -v <dir>:/deps" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${WORKROOT}" "${OUT}"
|
||||||
|
WORK="${WORKROOT}/src"
|
||||||
|
rm -rf "${WORK}"
|
||||||
|
mkdir -p "${WORK}"
|
||||||
|
|
||||||
|
rsync -a --delete \
|
||||||
|
--exclude '.git' \
|
||||||
|
--exclude '.venv' \
|
||||||
|
--exclude 'dist' \
|
||||||
|
--exclude 'build' \
|
||||||
|
--exclude '__pycache__' \
|
||||||
|
--exclude '.pytest_cache' \
|
||||||
|
--exclude '.mypy_cache' \
|
||||||
|
"${SRC}/" "${WORK}/"
|
||||||
|
|
||||||
|
cd "${WORK}"
|
||||||
|
|
||||||
|
# Determine version from pyproject.toml unless provided
|
||||||
|
if [ -n "${VERSION:-}" ]; then
|
||||||
|
ver="${VERSION}"
|
||||||
|
else
|
||||||
|
ver="$(grep -m1 '^version = ' pyproject.toml | sed -E 's/version = "([^"]+)".*/\1/')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TOPDIR="${WORKROOT}/rpmbuild"
|
||||||
|
mkdir -p "${TOPDIR}"/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
|
||||||
|
|
||||||
|
tarball="${TOPDIR}/SOURCES/enroll-${ver}.tar.gz"
|
||||||
|
tar -czf "${tarball}" --transform "s#^#enroll/#" .
|
||||||
|
|
||||||
|
spec_src="rpm/enroll.spec"
|
||||||
|
|
||||||
|
cp -v "${spec_src}" "${TOPDIR}/SPECS/enroll.spec"
|
||||||
|
|
||||||
|
rpmbuild -ba "${TOPDIR}/SPECS/enroll.spec" \
|
||||||
|
--define "_topdir ${TOPDIR}" \
|
||||||
|
--define "upstream_version ${ver}"
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
cp -v "${TOPDIR}"/RPMS/*/*.rpm "${OUT}/" || true
|
||||||
|
cp -v "${TOPDIR}"/SRPMS/*.src.rpm "${OUT}/" || true
|
||||||
|
echo "Artifacts copied to ${OUT}"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
RUN chmod +x /usr/local/bin/build-rpm
|
||||||
|
|
||||||
|
WORKDIR /work
|
||||||
|
ENTRYPOINT ["/usr/local/bin/build-rpm"]
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
**enroll** inspects a Linux machine (currently Debian-only) and generates Ansible roles/playbooks (and optionally inventory) for what it finds.
|
**enroll** inspects a Linux machine (currently Debian-only) and generates Ansible roles/playbooks (and optionally inventory) for what it finds.
|
||||||
|
|
||||||
It aims to be **optimistic and noninteractive**:
|
|
||||||
- Detects packages that have been installed.
|
- Detects packages that have been installed.
|
||||||
- Detects Debian package ownership of `/etc` files using dpkg’s local database.
|
- Detects Debian package ownership of `/etc` files using dpkg’s local database.
|
||||||
- Captures config that has **changed from packaged defaults** (dpkg conffile hashes + package md5sums when available).
|
- Captures config that has **changed from packaged defaults** (dpkg conffile hashes + package md5sums when available).
|
||||||
|
|
@ -26,9 +25,10 @@ It aims to be **optimistic and noninteractive**:
|
||||||
1) **Harvest**: collect host facts + relevant files into a harvest bundle (`state.json` + harvested artifacts)
|
1) **Harvest**: collect host facts + relevant files into a harvest bundle (`state.json` + harvested artifacts)
|
||||||
2) **Manifest**: turn that harvest into Ansible roles/playbooks (and optionally inventory)
|
2) **Manifest**: turn that harvest into Ansible roles/playbooks (and optionally inventory)
|
||||||
|
|
||||||
Additionally:
|
Additionally, some other functionalities exist:
|
||||||
|
|
||||||
- **Diff**: compare two harvests and report what changed (packages/services/users/files) since the previous snapshot.
|
- **Diff**: compare two harvests and report what changed (packages/services/users/files) since the previous snapshot.
|
||||||
|
- **Single-shot mode**: run both harvest and manifest at once.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
2
poetry.lock
generated
2
poetry.lock
generated
|
|
@ -923,4 +923,4 @@ zstd = ["backports-zstd (>=1.0.0)"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.10"
|
python-versions = "^3.10"
|
||||||
content-hash = "c3466a6595a9822763431a6dff0c7f835407a2591b92d5995592f8e6802c774a"
|
content-hash = "20623104a1a5f4c6d4aaa759f25b2591d5de345d1464e727eb4140a6ef9a5b6e"
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ repository = "https://git.mig5.net/mig5/enroll"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.10"
|
python = "^3.10"
|
||||||
pyyaml = "^6.0.3"
|
pyyaml = "^6"
|
||||||
paramiko = "^4.0.0"
|
paramiko = ">=3.5"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
enroll = "enroll.cli:main"
|
enroll = "enroll.cli:main"
|
||||||
|
|
|
||||||
31
release.sh
31
release.sh
|
|
@ -42,3 +42,34 @@ for dist in ${DISTS[@]}; do
|
||||||
debfile=$(ls -1 dist/${release}/*.deb)
|
debfile=$(ls -1 dist/${release}/*.deb)
|
||||||
reprepro -b /home/user/git/repo includedeb "${release}" "${debfile}"
|
reprepro -b /home/user/git/repo includedeb "${release}" "${debfile}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# RPM
|
||||||
|
sudo apt-get -y install createrepo-c rpm
|
||||||
|
docker build -f Dockerfile.rpmbuild -t enroll:f42 --progress=plain .
|
||||||
|
docker run --rm -v "$PWD":/src -v "$PWD/dist/rpm":/out -v "$HOME/git/jinjaturtle/dist/rpm":/deps:ro enroll:f42
|
||||||
|
sudo chown -R "${USER}" "$PWD/dist"
|
||||||
|
|
||||||
|
REPO_ROOT="${HOME}/git/repo_rpm"
|
||||||
|
RPM_REPO="${REPO_ROOT}/rpm/x86_64"
|
||||||
|
BUILD_OUTPUT="${HOME}/git/enroll/dist"
|
||||||
|
REMOTE="letessier.mig5.net:/opt/repo_rpm"
|
||||||
|
KEYID="00AE817C24A10C2540461A9C1D7CDE0234DB458D"
|
||||||
|
|
||||||
|
echo "==> Updating RPM repo..."
|
||||||
|
mkdir -p "$RPM_REPO"
|
||||||
|
|
||||||
|
for file in `ls -1 "${BUILD_OUTPUT}/rpm"`; do
|
||||||
|
rpmsign --addsign "${BUILD_OUTPUT}/rpm/$file"
|
||||||
|
done
|
||||||
|
|
||||||
|
cp "${BUILD_OUTPUT}/rpm/"*.rpm "$RPM_REPO/"
|
||||||
|
|
||||||
|
createrepo_c "$RPM_REPO"
|
||||||
|
|
||||||
|
echo "==> Signing repomd.xml..."
|
||||||
|
qubes-gpg-client --local-user "$KEYID" --detach-sign --armor "$RPM_REPO/repodata/repomd.xml" > "$RPM_REPO/repodata/repomd.xml.asc"
|
||||||
|
|
||||||
|
echo "==> Syncing repo to server..."
|
||||||
|
rsync -aHPvz --exclude=.git --delete "$REPO_ROOT/" "$REMOTE/"
|
||||||
|
|
||||||
|
echo "Done!"
|
||||||
|
|
|
||||||
47
rpm/enroll.spec
Normal file
47
rpm/enroll.spec
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
%global upstream_version 0.1.3
|
||||||
|
|
||||||
|
Name: enroll
|
||||||
|
Version: %{upstream_version}
|
||||||
|
Release: 1%{?dist}.enroll1
|
||||||
|
Summary: Enroll a server's running state retrospectively into Ansible.
|
||||||
|
|
||||||
|
License: GPL-3.0-or-later
|
||||||
|
URL: https://git.mig5.net/mig5/enroll
|
||||||
|
Source0: %{name}-%{version}.tar.gz
|
||||||
|
|
||||||
|
BuildArch: noarch
|
||||||
|
|
||||||
|
BuildRequires: pyproject-rpm-macros
|
||||||
|
BuildRequires: python3-devel
|
||||||
|
BuildRequires: python3-poetry-core
|
||||||
|
|
||||||
|
Requires: python3-yaml
|
||||||
|
Requires: python3-paramiko
|
||||||
|
|
||||||
|
# Make sure private repo dependency is pulled in by package name as well.
|
||||||
|
Recommends: jinjaturtle
|
||||||
|
|
||||||
|
%description
|
||||||
|
Enroll a server's running state retrospectively into Ansible.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup -n enroll
|
||||||
|
|
||||||
|
%generate_buildrequires
|
||||||
|
%pyproject_buildrequires
|
||||||
|
|
||||||
|
%build
|
||||||
|
%pyproject_wheel
|
||||||
|
|
||||||
|
%install
|
||||||
|
%pyproject_install
|
||||||
|
%pyproject_save_files enroll
|
||||||
|
|
||||||
|
%files -f %{pyproject_files}
|
||||||
|
%license LICENSE
|
||||||
|
%doc README.md CHANGELOG.md
|
||||||
|
%{_bindir}/enroll
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Sat Dec 27 2025 Miguel Jacq <mig@mig5.net> - %{version}-%{release}
|
||||||
|
- Initial RPM packaging for Fedora 42
|
||||||
Loading…
Add table
Add a link
Reference in a new issue