/
githubmirror
/
rsyslog
Обзор
Документация
Войти
/
githubmirror
/
rsyslog
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
devtools/release/amazonlinux-daily-stable.sh
365 строк
12 KB
Rainer Gerhards
packaging: enable Amazon Linux GnuTLS profile
04 авг 2026, 13:23
04 авг 2026, 13:23
0b5901a
Код
Авторство
О чём код?
#!/usr/bin/env bash set -euo pipefail usage() { cat >&2 <<'EOF' Usage: amazonlinux-daily-stable.sh <command> [args...] Commands: version prepare-sources <baseline-root> <dist-tarball> <output-dir> <policy-file> <feature-contract> <version> <release> build-package <prepared-dir> <artifact-dir> <build-log> <expected-evr> <arch> sign-rpms <artifact-dir> <fingerprint> generate-repo <artifact-dir> <repo-dir> <arch> <fingerprint> <passphrase-file> verify-repo <repo-url> <arch> <expected-evr> <expected-fingerprint> manifest <artifact-dir> <expected-evr> <arch> <channel> <distro> <distro-version> EOF } die() { echo "ERROR: $*" >&2 exit 1 } base_version() { local configure_file script_dir script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" configure_file="${RSYSLOG_SOURCE_DIR:-$script_dir/../..}/configure.ac" sed -n 's/AC_INIT(\[rsyslog\],\[\([^]]*\)\].*/\1/p' "$configure_file" | sed 's/\.daily$//' } short_commit_sha() { local candidate="${SOURCE_GIT_SHA:-${GITHUB_SHA:-}}" if [ -n "$candidate" ] && printf '%s\n' "$candidate" | grep -Eq '^[0-9a-fA-F]{12,64}$'; then printf '%.12s\n' "$candidate" | tr '[:upper:]' '[:lower:]' return fi git rev-parse --verify HEAD >/dev/null 2>&1 || die "could not determine git commit" git rev-parse --short=12 HEAD } cmd_version() { local version date run attempt short_sha release expected_evr version="$(base_version)" [ -n "$version" ] || die "could not determine base version" date="${RSYSLOG_BUILD_DATE:-$(date -u +%Y%m%d)}" printf '%s\n' "$date" | grep -Eq '^[0-9]{8}$' || die "RSYSLOG_BUILD_DATE must use YYYYMMDD" run="${GITHUB_RUN_NUMBER:-0}" attempt="${GITHUB_RUN_ATTEMPT:-1}" short_sha="$(short_commit_sha)" release="0.daily${date}.${run}.${attempt}.git${short_sha}.adiscon1" expected_evr="${version}-${release}.amzn2023" printf '%s\n' "$expected_evr" if [ -n "${GITHUB_OUTPUT:-}" ]; then { printf 'version=%s\n' "$version" printf 'release=%s\n' "$release" printf 'expected_evr=%s\n' "$expected_evr" printf 'archive_date=%s-%s-%s\n' \ "${date:0:4}" "${date:4:2}" "${date:6:2}" } >> "$GITHUB_OUTPUT" fi } cmd_prepare_sources() { local baseline_root="$1" local dist_tarball="$2" local output_dir="$3" local policy_file="$4" local feature_contract="$5" local version="$6" local release="$7" local baseline_spec baseline_sources spec_file tmp_dir source_root baseline_spec="$baseline_root/SPECS/rsyslog.spec" baseline_sources="$baseline_root/SOURCES" [ -f "$baseline_spec" ] || die "missing Amazon Linux spec: $baseline_spec" [ -d "$baseline_sources" ] || die "missing Amazon Linux sources: $baseline_sources" [ -f "$dist_tarball" ] || die "missing dist tarball: $dist_tarball" [ -f "$policy_file" ] || die "missing Amazon Linux policy: $policy_file" [ -f "$feature_contract" ] || die "missing package feature contract: $feature_contract" rm -rf "$output_dir" mkdir -p "$output_dir/SOURCES" "$output_dir/SPECS" cp -a "$baseline_sources/." "$output_dir/SOURCES/" cp "$baseline_spec" "$output_dir/SPECS/rsyslog.spec" spec_file="$output_dir/SPECS/rsyslog.spec" tmp_dir="$(mktemp -d)" trap 'rm -rf "$tmp_dir"' RETURN tar -xzf "$dist_tarball" -C "$tmp_dir" source_root="$(find "$tmp_dir" -mindepth 1 -maxdepth 1 -type d -print -quit)" [ -n "$source_root" ] || die "dist tarball has no source directory" [ "$(find "$tmp_dir" -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ] || die "dist tarball must contain exactly one source directory" mv "$source_root" "$tmp_dir/rsyslog-$version" tar -C "$tmp_dir" -czf "$output_dir/SOURCES/rsyslog-$version.tar.gz" \ "rsyslog-$version" python3 - "$spec_file" "$policy_file" "$version" "$release" <<'PY' import json import pathlib import re import sys from datetime import datetime, timezone spec_path = pathlib.Path(sys.argv[1]) policy_path = pathlib.Path(sys.argv[2]) version = sys.argv[3] release = sys.argv[4] spec = spec_path.read_text(encoding="utf-8") policy = json.loads(policy_path.read_text(encoding="utf-8")) patches = { match.group(2): match.group(1) for match in re.finditer(r"(?m)^Patch(\d+):\s*(\S+)\s*$", spec) } allowed = policy.get("allowed_patch_skips", []) allowed_names = [entry.get("patch", "").strip() for entry in allowed] if any(not name for name in allowed_names): raise SystemExit("policy contains an empty allowed patch name") missing = sorted(set(allowed_names) - set(patches)) if missing: raise SystemExit(f"allowed patch is absent from Amazon Linux baseline: {missing}") for name in allowed_names: number = patches[name] spec, declaration_count = re.subn( rf"(?m)^Patch{re.escape(number)}:\s*{re.escape(name)}\s*\n", "", spec ) application_pattern = ( rf"(?m)^%patch(?:\s+-P\s*{re.escape(number)}|" rf"\s+-P{re.escape(number)}|{re.escape(number)})(?:\s+[^\n]*)?\s*\n" ) spec, application_count = re.subn(application_pattern, "", spec) if declaration_count != 1 or application_count != 1: raise SystemExit( f"could not remove exactly one declaration/application for {name}" ) if not policy.get("drop_stale_html_docs", False): raise SystemExit("Amazon Linux policy must explicitly decide about stale HTML docs") doc_edits = [ (r"(?m)^Source1:\s*.*\n", "", 1, "Source1"), ( r"(?ms)^%package doc\n.*?(?=^%package elasticsearch\n)", "", 1, "doc package", ), ( r"(?ms)^%description doc\n.*?(?=^%description elasticsearch\n)", "", 1, "doc description", ), ( r"(?ms)^# set up rsyslog-doc sources\n.*?^# set up rsyslog sources\n", "# set up rsyslog sources\n", 1, "doc prep", ), ( r"(?m)^install -d -m 755 %\{buildroot\}%\{rsyslog_docdir\}/html\n", "install -d -m 755 %{buildroot}%{rsyslog_docdir}\n", 1, "doc install directory", ), ( r"(?m)^# extract documentation\ncp -r doc/\* %\{buildroot\}%\{rsyslog_docdir\}/html\n", "", 1, "doc install", ), ( r"(?m)^%exclude %\{rsyslog_docdir\}/html\n", "", 1, "doc exclusion", ), ( r"(?m)^%doc AUTHORS ChangeLog README\.md\n", "", 1, "duplicate core docs", ), ( r"(?ms)^%files doc\n.*?(?=^%files elasticsearch\n)", "", 1, "doc files", ), ] for pattern, replacement, expected, label in doc_edits: spec, count = re.subn(pattern, replacement, spec) if count != expected: raise SystemExit(f"Amazon Linux spec {label} did not match exactly once") enabled_bconds = policy.get("enabled_bconds", []) features = [entry.get("feature", "").strip() for entry in enabled_bconds] if any(not feature for feature in features): raise SystemExit("policy contains an empty enabled bcond feature") if len(features) != len(set(features)): raise SystemExit("policy contains duplicate enabled bcond features") for feature in features: spec, count = re.subn( rf"(?m)^%bcond_with\s+{re.escape(feature)}\s*$", f"%bcond_without {feature}", spec, count=1, ) if count != 1: raise SystemExit(f"could not enable Amazon Linux bcond: {feature}") build_requires = policy.get("supplemental_build_requires", []) packages = [entry.get("package", "").strip() for entry in build_requires] if any(not package for package in packages): raise SystemExit("policy contains an empty supplemental BuildRequires package") for package in packages: if re.search(rf"(?m)^BuildRequires:\s*{re.escape(package)}(?:\s|$)", spec): continue spec, count = re.subn( r"(?m)^(BuildRequires:\s*autoconf\s*)$", rf"\1\nBuildRequires: {package}", spec, count=1, ) if count != 1: raise SystemExit(f"could not insert supplemental BuildRequires: {package}") core_files = policy.get("supplemental_core_files", []) if any(not path.strip() for path in core_files): raise SystemExit("policy contains an empty supplemental core file") for path in core_files: if re.search(rf"(?m)^{re.escape(path)}\s*$", spec): continue spec, count = re.subn( r"(?m)^(%\{_libdir\}/rsyslog/lmzlibw\.so\s*)$", rf"\1\n{path}", spec, count=1, ) if count != 1: raise SystemExit(f"could not add supplemental core file: {path}") spec, version_count = re.subn(r"(?m)^Version:\s*.*$", f"Version: {version}", spec) spec, release_count = re.subn( r"(?m)^Release:\s*.*$", f"Release: {release}%{{?dist}}", spec ) spec, source_count = re.subn( r"(?m)^Source0:\s*.*$", "Source0: %{name}-%{version}.tar.gz", spec ) if (version_count, release_count, source_count) != (1, 1, 1): raise SystemExit("Amazon Linux spec version/source fields did not match exactly once") stamp = datetime.now(timezone.utc).strftime("%a %b %d %Y") entry = ( f"%changelog\n* {stamp} Adiscon package maintainers " f"<release-bot@adiscon.com> - {version}-{release}\n" "- Automated rsyslog Amazon Linux 2023 daily stable build.\n\n" ) spec, changelog_count = re.subn(r"(?m)^%changelog\s*$", entry.rstrip(), spec, count=1) if changelog_count != 1: raise SystemExit("Amazon Linux spec has no unique %changelog marker") spec_path.write_text(spec, encoding="utf-8") PY python3 "$(dirname "$0")/package-feature-overlay.py" rpm \ "$spec_file" "$feature_contract" rpm rm -rf "$tmp_dir" trap - RETURN } cmd_build_package() { local prepared_dir="$1" local artifact_dir="$2" local build_log="$3" local expected_evr="$4" local arch="$5" local build_root srpm rpm_file actual_evr rc command -v dnf >/dev/null || die "dnf is not installed" command -v rpmbuild >/dev/null || die "rpmbuild is not installed" rm -rf "$artifact_dir" mkdir -p "$artifact_dir/srpm" "$artifact_dir/rpms" dnf -q -y builddep "$prepared_dir/SPECS/rsyslog.spec" set +e rpmbuild -bs --define "_topdir $prepared_dir" \ "$prepared_dir/SPECS/rsyslog.spec" 2>&1 | tee "$build_log" rc=${PIPESTATUS[0]} set -e [ "$rc" -eq 0 ] || return "$rc" srpm="$(find "$prepared_dir/SRPMS" -maxdepth 1 -type f -name '*.src.rpm' -print -quit)" [ -n "$srpm" ] || die "rpmbuild did not produce a source RPM" cp "$srpm" "$artifact_dir/srpm/" build_root="$(mktemp -d)" trap 'rm -rf "$build_root"' RETURN mkdir -p "$build_root/BUILD" "$build_root/BUILDROOT" "$build_root/RPMS" \ "$build_root/SOURCES" "$build_root/SPECS" "$build_root/SRPMS" set +e rpmbuild --rebuild --define "_topdir $build_root" "$srpm" \ 2>&1 | tee -a "$build_log" rc=${PIPESTATUS[0]} set -e [ "$rc" -eq 0 ] || return "$rc" find "$build_root/RPMS" -type f -name '*.rpm' -exec cp -a {} "$artifact_dir/rpms/" \; rpm_file="$(find "$artifact_dir/rpms" -maxdepth 1 -type f \ -name 'rsyslog-[0-9]*.rpm' ! -name '*-debuginfo-*' ! -name '*-debugsource-*' \ -print -quit)" [ -n "$rpm_file" ] || die "rpmbuild did not produce the base rsyslog RPM" [ "$(rpm -qp --qf '%{ARCH}\n' "$rpm_file")" = "$arch" ] || die "base RPM architecture does not match $arch" actual_evr="$(rpm -qp --qf '%{VERSION}-%{RELEASE}\n' "$rpm_file")" [ "$actual_evr" = "$expected_evr" ] || die "built RPM EVR $actual_evr does not match $expected_evr" local package for package in openssl gnutls omotel omazuredce standard full; do find "$artifact_dir/rpms" -maxdepth 1 -type f \ -name "rsyslog-${package}-[0-9]*.rpm" -print -quit | grep -q . || die "rsyslog-$package RPM was not produced" done cp "$build_log" "$artifact_dir/build.log" cp "$prepared_dir/SPECS/rsyslog.spec" "$artifact_dir/rsyslog.spec" rm -rf "$build_root" trap - RETURN } command="${1:-}" case "$command" in version) shift cmd_version "$@" ;; prepare-sources) shift cmd_prepare_sources "$@" ;; build-package) shift cmd_build_package "$@" ;; sign-rpms | generate-repo | verify-repo | manifest) exec "$(dirname "$0")/rpm-daily-stable.sh" "$@" ;; *) usage exit 2 ;; esac