mirror of
https://github.com/xcat2/xcat-dep.git
synced 2026-04-25 13:21:27 +00:00
fix: Add scripts & patches for building in mock for EL10
Signed-off-by: Daniel Hilst Selli <392820+dhilst@users.noreply.github.com>
This commit is contained in:
265
BUILD.md
Normal file
265
BUILD.md
Normal file
@@ -0,0 +1,265 @@
|
||||
# Build Guide (`mockbuild-all.pl`)
|
||||
|
||||
This guide explains how to use `mockbuild-all.pl` to build, validate, and package xCAT dependencies and optional xCAT packages into a unified EL10 repository layout.
|
||||
It also documents the operational flags for controlling build, install-check, collection, and packaging behavior.
|
||||
|
||||
# Purpose
|
||||
|
||||
`mockbuild-all.pl` is the top-level build orchestrator for generating a **unified xCAT repository**.
|
||||
It builds required dependency RPMs and, by default, xCAT RPMs, then assembles:
|
||||
|
||||
- a binary RPM repo tree with repodata
|
||||
- an SRPM repo tree with repodata
|
||||
- one binary repo tarball and one SRPM repo tarball
|
||||
|
||||
# Historical Context
|
||||
|
||||
Historically, the deployment flow used separate repositories:
|
||||
|
||||
- `xcat-core` for xCAT packages
|
||||
- `xcat-dep` for dependency packages
|
||||
|
||||
The current flow produces a single **unified `xcat` repository** containing all required packages together.
|
||||
|
||||
# Placeholder Conventions
|
||||
|
||||
This guide uses the following placeholders consistently:
|
||||
|
||||
- `<REPO_ROOT>`: xcat-dep repository root (example: `/root/xcat-dep`)
|
||||
- `<XCAT_SOURCE>`: xCAT source root (example: `<REPO_ROOT>/xcat-source-code`)
|
||||
- `<ARCH>`: output of `uname -m` (for example: `x86_64`, `ppc64le`)
|
||||
- `<OS_ID>`: `ID` field from `/etc/os-release` (for example: `rhel`, `rocky`)
|
||||
- `<REL>`: integer major release from `VERSION_ID` in `/etc/os-release` (for example: `10`)
|
||||
- `<TARGET>`: `<OS_ID>+epel-<REL>-<ARCH>`
|
||||
- `<RUN_ID>`: build run identifier (auto-generated if omitted)
|
||||
|
||||
# Build Pipeline Overview
|
||||
|
||||
`mockbuild-all.pl` orchestrates these build components in parallel:
|
||||
|
||||
- `<REPO_ROOT>/elilo/mockbuild.pl`
|
||||
- `<REPO_ROOT>/grub2-xcat/mockbuild.pl`
|
||||
- `<REPO_ROOT>/ipmitool/mockbuild.pl`
|
||||
- `<REPO_ROOT>/syslinux/mockbuild.pl`
|
||||
- `<REPO_ROOT>/goconserver/mockbuild.pl`
|
||||
- `<REPO_ROOT>/mockbuild-perl-packages.pl`
|
||||
- `<XCAT_SOURCE>/buildrpms.pl` (unless `--skip-xcat` is set)
|
||||
|
||||
Each build path uses `mock` for chroot isolation. Top-level steps are parallelized by `mockbuild-all.pl`, and perl dependency builds are also parallelized internally by `mockbuild-perl-packages.pl`.
|
||||
|
||||
`mockbuild-all.pl` does more than building RPMs. In a default run it performs these stages:
|
||||
|
||||
1. Optional chroot cleanup (`--scrub-all-chroots`)
|
||||
2. Parallel build execution
|
||||
3. Optional install/smoke checks inside child builders (disabled with `--skip-install`)
|
||||
4. Binary RPM collection into `repo/<ARCH>/`
|
||||
5. Source RPM collection into `repo-src/`
|
||||
6. `createrepo --update` on both repo trees
|
||||
7. Tarball creation for both repo trees
|
||||
8. Summary generation (`summary.txt`)
|
||||
|
||||
# Skip and Control Flags
|
||||
|
||||
Use these flags to skip specific operations:
|
||||
|
||||
- `--skip-install`
|
||||
- Skips install/smoke checks performed by child builder scripts after RPM build.
|
||||
- `--skip-xcat`
|
||||
- Skips `<XCAT_SOURCE>/buildrpms.pl` (xCAT package build step).
|
||||
- `--skip-xcat-dep`
|
||||
- Skips non-perl xcat-dep package builders (`elilo`, `grub2-xcat`, `ipmitool-xcat`, `syslinux-xcat`, `goconserver`).
|
||||
- `--skip-perl`
|
||||
- Skips `<REPO_ROOT>/mockbuild-perl-packages.pl`.
|
||||
- `--skip-build`
|
||||
- Skips all build steps; only runs collection/repo/tarball stages from existing artifact roots.
|
||||
- `--skip-createrepo`
|
||||
- Skips `createrepo --update`.
|
||||
- `--skip-tarball`
|
||||
- Skips tarball creation for both binary and SRPM repos.
|
||||
- `--scrub-all-chroots`
|
||||
- Runs `mock -r <TARGET> --scrub=all` before build and collection.
|
||||
- `--collect-dir <PATH>`
|
||||
- Adds extra artifact roots to the collection phase (repeatable).
|
||||
- `--dry-run`
|
||||
- Prints planned actions without executing them.
|
||||
|
||||
# Prerequisites
|
||||
|
||||
- Run as `root`.
|
||||
- `mockbuild-all.pl` and package sources present under `<REPO_ROOT>`.
|
||||
- xCAT sources present under `<XCAT_SOURCE>`.
|
||||
|
||||
Install baseline tooling:
|
||||
|
||||
```bash
|
||||
dnf -y install perl perl-Parallel-ForkManager mock createrepo tar rpm-build rpmdevtools dnf-plugins-core wget git
|
||||
```
|
||||
|
||||
If you will build xCAT packages (that is, you will **not** use `--skip-xcat`), install xCAT build dependencies:
|
||||
|
||||
```bash
|
||||
cd <XCAT_SOURCE>
|
||||
perl buildrpms.pl --install_deps
|
||||
```
|
||||
|
||||
Validate mock config availability:
|
||||
|
||||
```bash
|
||||
mock -r <TARGET> --print-root-path
|
||||
```
|
||||
|
||||
# Target Resolution
|
||||
|
||||
`--target` is optional.
|
||||
|
||||
If `--target` is omitted, `mockbuild-all.pl` derives `<TARGET>` from:
|
||||
|
||||
- `/etc/os-release` (`ID`, `VERSION_ID`)
|
||||
- `uname -m`
|
||||
|
||||
Equivalent derivation:
|
||||
|
||||
```text
|
||||
<TARGET> = <OS_ID>+epel-<REL>-<ARCH>
|
||||
```
|
||||
|
||||
`<TARGET>` is also passed to `mock` as the chroot/config identifier:
|
||||
|
||||
```text
|
||||
mock -r <TARGET> ...
|
||||
```
|
||||
|
||||
# Build Full Unified Repository (xCAT + Dependencies)
|
||||
|
||||
Use this mode to build dependency packages and xCAT packages together.
|
||||
|
||||
```bash
|
||||
cd /root/xcat-dep
|
||||
perl ./mockbuild-all.pl \
|
||||
--repo-root /root/xcat-dep \
|
||||
--xcat-source /root/xcat-dep/xcat-source-code \
|
||||
--scrub-all-chroots
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Install/smoke checks run by default inside child builders.
|
||||
- Add `--skip-install` to skip those checks.
|
||||
- `<RUN_ID>` is optional; when omitted it is timestamp-based.
|
||||
|
||||
# Build Unified Repository Without xCAT (`--skip-xcat`)
|
||||
|
||||
Use this mode to build dependency packages only and skip invoking `/root/xcat-dep/xcat-source-code/buildrpms.pl`.
|
||||
|
||||
```bash
|
||||
cd /root/xcat-dep
|
||||
perl ./mockbuild-all.pl \
|
||||
--repo-root /root/xcat-dep \
|
||||
--xcat-source /root/xcat-dep/xcat-source-code \
|
||||
--scrub-all-chroots \
|
||||
--skip-xcat \
|
||||
--skip-install
|
||||
```
|
||||
|
||||
Important behavior:
|
||||
|
||||
- `--skip-xcat` skips the xCAT build step, but collection still scans:
|
||||
- `<XCAT_SOURCE>/dist/<TARGET>/rpms`
|
||||
- If that path already has xCAT RPMs, they are included in the resulting unified repo.
|
||||
|
||||
# Common Build Modes
|
||||
|
||||
Full unified repo (xCAT + dependencies, with install/smoke checks):
|
||||
|
||||
```bash
|
||||
cd <REPO_ROOT>
|
||||
perl ./mockbuild-all.pl \
|
||||
--repo-root <REPO_ROOT> \
|
||||
--xcat-source <XCAT_SOURCE> \
|
||||
--scrub-all-chroots
|
||||
```
|
||||
|
||||
Full unified repo (xCAT + dependencies, skip install/smoke checks):
|
||||
|
||||
```bash
|
||||
cd <REPO_ROOT>
|
||||
perl ./mockbuild-all.pl \
|
||||
--repo-root <REPO_ROOT> \
|
||||
--xcat-source <XCAT_SOURCE> \
|
||||
--scrub-all-chroots \
|
||||
--skip-install
|
||||
```
|
||||
|
||||
Dependency-only repo (skip xCAT package build):
|
||||
|
||||
```bash
|
||||
cd <REPO_ROOT>
|
||||
perl ./mockbuild-all.pl \
|
||||
--repo-root <REPO_ROOT> \
|
||||
--xcat-source <XCAT_SOURCE> \
|
||||
--scrub-all-chroots \
|
||||
--skip-xcat \
|
||||
--skip-install
|
||||
```
|
||||
|
||||
Collection-only pass from existing build artifacts:
|
||||
|
||||
```bash
|
||||
cd <REPO_ROOT>
|
||||
perl ./mockbuild-all.pl \
|
||||
--repo-root <REPO_ROOT> \
|
||||
--xcat-source <XCAT_SOURCE> \
|
||||
--skip-build
|
||||
```
|
||||
|
||||
# Output Artifacts and Paths
|
||||
|
||||
For each run:
|
||||
|
||||
- Binary repo path:
|
||||
- `<REPO_ROOT>/build-output/mockbuild-all/<RUN_ID>/repo/<ARCH>/`
|
||||
- SRPM repo path:
|
||||
- `<REPO_ROOT>/build-output/mockbuild-all/<RUN_ID>/repo-src/`
|
||||
- Run summary:
|
||||
- `<REPO_ROOT>/build-output/mockbuild-all/<RUN_ID>/summary.txt`
|
||||
- Binary repo tarball:
|
||||
- `<REPO_ROOT>/build-output/mockbuild-all/mockbuild-all-<TARGET>-<RUN_ID>.tar.gz`
|
||||
- SRPM repo tarball:
|
||||
- `<REPO_ROOT>/build-output/mockbuild-all/mockbuild-all-<TARGET>-<RUN_ID>-srpm.tar.gz`
|
||||
|
||||
# Architecture Requirements
|
||||
|
||||
`mockbuild-all.pl` derives architecture from the build host:
|
||||
|
||||
- `<ARCH> = $(uname -m)`
|
||||
|
||||
Because of this, to build `ppc64le` artifacts you must run `mockbuild-all.pl` on a Power host where:
|
||||
|
||||
- `uname -m` returns `ppc64le`
|
||||
- a matching mock config exists for `<TARGET>` (for example `rocky+epel-10-ppc64le`)
|
||||
|
||||
In short: build `ppc64le` packages on a Power machine.
|
||||
|
||||
# Validation Commands
|
||||
|
||||
```bash
|
||||
cat <REPO_ROOT>/build-output/mockbuild-all/<RUN_ID>/summary.txt
|
||||
ls -1 <REPO_ROOT>/build-output/mockbuild-all/<RUN_ID>/repo/<ARCH>/
|
||||
ls -1 <REPO_ROOT>/build-output/mockbuild-all/<RUN_ID>/repo-src/
|
||||
ls -1 <REPO_ROOT>/build-output/mockbuild-all/mockbuild-all-<TARGET>-<RUN_ID>.tar.gz
|
||||
ls -1 <REPO_ROOT>/build-output/mockbuild-all/mockbuild-all-<TARGET>-<RUN_ID>-srpm.tar.gz
|
||||
find <REPO_ROOT>/build-output/mockbuild-all/<RUN_ID>/build-logs -type f | sort
|
||||
```
|
||||
|
||||
# Common Issues
|
||||
|
||||
- `Missing xCAT build script: .../buildrpms.pl`
|
||||
- Ensure `<XCAT_SOURCE>` points to a valid xCAT source tree.
|
||||
- `WARN: missing dep builder script, skipping: ...`
|
||||
- Sync the repository; one or more package build scripts are missing.
|
||||
- `mock target not found`
|
||||
- Validate with `mock -r <TARGET> --print-root-path` and install the required mock config packages.
|
||||
|
||||
# References
|
||||
|
||||
- [mock project repository](https://github.com/rpm-software-management/mock)
|
||||
@@ -5,6 +5,7 @@ Version: 0.7
|
||||
Release: 10
|
||||
License: GPL
|
||||
Vendor: Linux Networx Inc.
|
||||
%undefine _hardened_build
|
||||
Source: atftp_0.7.dfsg.orig.tar.gz
|
||||
Source1: tftpd
|
||||
Patch: atftp_0.7.dfsg-3.diff
|
||||
@@ -12,6 +13,11 @@ Patch1: dfsg-3-to-multicast.diff
|
||||
Patch2: dfsg-3-bigfiles.diff
|
||||
Patch3: dfsg-3-to-winpaths.diff
|
||||
Patch4: dfsg-3-mclistfix.diff
|
||||
Patch5: dfsg-3-pthread-self-include.diff
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: make
|
||||
BuildRequires: glibc-devel
|
||||
Buildroot: /var/tmp/atftp-buildroot
|
||||
Packager: Allen Reese <areese@lnxi.com>
|
||||
Conflicts: tftp-server
|
||||
@@ -38,11 +44,25 @@ files using the TFTP protocol.
|
||||
|
||||
%prep
|
||||
%setup -n atftp-0.7.dfsg
|
||||
%patch -p1
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
# Avoid argz_next redefinition with modern glibc extern inline semantics.
|
||||
sed -i '/^#include <stdlib.h>$/a\
|
||||
#ifdef __USE_EXTERN_INLINES\
|
||||
#undef __USE_EXTERN_INLINES\
|
||||
#endif' argz.c
|
||||
# Disable glibc extern-inline argz bodies to prevent multiple definitions.
|
||||
sed -i 's/^#ifdef __USE_EXTERN_INLINES/#if 0/' argz.h
|
||||
# Force Strncpy to have a linkable external definition with modern GCC.
|
||||
sed -i 's/^inline char \*Strncpy(/char *Strncpy(/' tftp_def.h
|
||||
sed -i 's/^inline char \*Strncpy(/char *Strncpy(/' tftp_def.c
|
||||
# Force tftpd_clientlist_ready to have a linkable external definition.
|
||||
sed -i 's/^inline void tftpd_clientlist_ready(/void tftpd_clientlist_ready(/' tftpd.h
|
||||
sed -i 's/^inline void tftpd_clientlist_ready(/void tftpd_clientlist_ready(/' tftpd_list.c
|
||||
|
||||
|
||||
%build
|
||||
|
||||
11
atftp/dfsg-3-argz-inline-redefinition.diff
Normal file
11
atftp/dfsg-3-argz-inline-redefinition.diff
Normal file
@@ -0,0 +1,11 @@
|
||||
diff -Naur atftp-0.7.dfsg/argz.c atftp-0.7.dfsg-fixed/argz.c
|
||||
--- atftp-0.7.dfsg/argz.c
|
||||
+++ atftp-0.7.dfsg-fixed/argz.c
|
||||
@@ -41,6 +41,9 @@
|
||||
#include <stdlib.h>
|
||||
+#ifdef __USE_EXTERN_INLINES
|
||||
+#undef __USE_EXTERN_INLINES
|
||||
+#endif
|
||||
#include "argz.h"
|
||||
|
||||
char * argz_next (const char *argz, size_t argz_len, const char *entry)
|
||||
11
atftp/dfsg-3-pthread-self-include.diff
Normal file
11
atftp/dfsg-3-pthread-self-include.diff
Normal file
@@ -0,0 +1,11 @@
|
||||
diff -Naur atftp-0.7.dfsg/logger.c atftp-0.7.dfsg-fixed/logger.c
|
||||
--- atftp-0.7.dfsg/logger.c
|
||||
+++ atftp-0.7.dfsg-fixed/logger.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
+#include <pthread.h>
|
||||
#include <netdb.h>
|
||||
#include "logger.h"
|
||||
|
||||
32
elilo/elilo-gnu-efi-strncpy-conflict.patch
Normal file
32
elilo/elilo-gnu-efi-strncpy-conflict.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
--- elilo/strops.h.orig 2003-08-19 13:47:46.000000000 -0300
|
||||
+++ elilo/strops.h 2026-03-02 13:08:16.755263536 -0300
|
||||
@@ -27,7 +27,6 @@
|
||||
#define __STROPS_H__
|
||||
|
||||
extern CHAR16 *StrChr(IN const CHAR16 *s, const CHAR16 c);
|
||||
-extern CHAR16 *StrnCpy(OUT CHAR16 *dst, IN const CHAR16 *src, UINTN count);
|
||||
extern CHAR8 *StrnXCpy(OUT CHAR8 *dst, IN const CHAR16 *src, UINTN count);
|
||||
|
||||
extern CHAR8 *strtok_simple(CHAR8 *in, CHAR8 c);
|
||||
--- elilo/strops.c.orig 2010-11-09 21:11:07.000000000 -0200
|
||||
+++ elilo/strops.c 2026-03-02 13:08:16.755263536 -0300
|
||||
@@ -36,19 +36,6 @@
|
||||
return (CHAR16 *)s;
|
||||
}
|
||||
|
||||
-CHAR16 *
|
||||
-StrnCpy(OUT CHAR16 *dst, IN const CHAR16 *src, IN UINTN size)
|
||||
-{
|
||||
- CHAR16 *res = dst;
|
||||
-
|
||||
- while (size && size-- && (*dst++ = *src++) != CHAR_NULL);
|
||||
- /*
|
||||
- * does the null padding
|
||||
- */
|
||||
- while (size && size-- > 0) *dst++ = CHAR_NULL;
|
||||
-
|
||||
- return res;
|
||||
-}
|
||||
|
||||
CHAR8 *
|
||||
StrnXCpy(OUT CHAR8 *dst, IN const CHAR16 *src, IN UINTN size)
|
||||
@@ -17,6 +17,15 @@ BuildArch: noarch
|
||||
Source0: elilo-3.14-source.tar.gz
|
||||
Patch1: elilo-xcat.patch
|
||||
Patch2: elilo-big-bzimage-limit.patch
|
||||
Patch3: elilo-gnu-efi-strncpy-conflict.patch
|
||||
Source4: elilo-xcat-3.14-6.noarch.rpm
|
||||
BuildRequires: gcc
|
||||
BuildRequires: make
|
||||
BuildRequires: cpio
|
||||
%if "%{_host_cpu}" != "ppc64le"
|
||||
BuildRequires: gnu-efi
|
||||
BuildRequires: gnu-efi-devel
|
||||
%endif
|
||||
|
||||
%description
|
||||
elilo with patches from the xCAT team. Most significantly, adds iPXE usage to the network support
|
||||
@@ -26,18 +35,35 @@ elilo with patches from the xCAT team. Most significantly, adds iPXE usage to t
|
||||
%setup -n elilo
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
# EL10 gnu-efi installs linker scripts and crt0 objects under /usr/lib.
|
||||
sed -i 's|^GNUEFILIB[[:space:]]*=.*|GNUEFILIB = /usr/lib|' Make.defaults
|
||||
sed -i 's|^EFILIB[[:space:]]*=.*|EFILIB = /usr/lib|' Make.defaults
|
||||
sed -i 's|^EFICRT0[[:space:]]*=.*|EFICRT0 = /usr/lib|' Make.defaults
|
||||
%if "%{_host_cpu}" == "ppc64le"
|
||||
# On ppc64le, reuse the prebuilt EFI payload from the tracked noarch package.
|
||||
mkdir -p prebuilt
|
||||
rpm2cpio %{SOURCE4} | (cd prebuilt && cpio -idm --quiet)
|
||||
test -f prebuilt/tftpboot/xcat/elilo-x64.efi
|
||||
%endif
|
||||
|
||||
%build
|
||||
|
||||
rm -rf %{buildroot}
|
||||
|
||||
%if "%{_host_cpu}" != "ppc64le"
|
||||
make
|
||||
%endif
|
||||
|
||||
|
||||
%install
|
||||
|
||||
mkdir -p %{buildroot}/tftpboot/xcat
|
||||
%if "%{_host_cpu}" == "ppc64le"
|
||||
cp prebuilt/tftpboot/xcat/elilo-x64.efi %{buildroot}/tftpboot/xcat/elilo-x64.efi
|
||||
%else
|
||||
cp elilo.efi %{buildroot}/tftpboot/xcat/elilo-x64.efi
|
||||
%endif
|
||||
|
||||
|
||||
%post
|
||||
|
||||
346
elilo/mockbuild.pl
Executable file
346
elilo/mockbuild.pl
Executable file
@@ -0,0 +1,346 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname);
|
||||
use File::Copy qw(copy);
|
||||
use File::Path qw(make_path remove_tree);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
|
||||
my $script_dir = abs_path(dirname(__FILE__));
|
||||
my $repo_root = abs_path("$script_dir/..");
|
||||
my $pkg_dir = "$repo_root/elilo";
|
||||
my $spec_file = "$pkg_dir/elilo-xcat.spec";
|
||||
|
||||
my $source_url = 'https://downloads.sourceforge.net/project/elilo/elilo/elilo-3.14/elilo-3.14-all.tar.gz';
|
||||
my $source_file = '';
|
||||
my $work_dir = '/tmp/elilo-xcat-mockbuild';
|
||||
my $mock_cfg = '';
|
||||
my $mock_uniqueext = '';
|
||||
my $result_dir = "$repo_root/build-output/list3/elilo-xcat";
|
||||
my $log_dir = "$repo_root/build-logs/list3/elilo-xcat";
|
||||
my $skip_install = 0;
|
||||
|
||||
GetOptions(
|
||||
'source-url=s' => \$source_url,
|
||||
'source-file=s' => \$source_file,
|
||||
'work-dir=s' => \$work_dir,
|
||||
'mock-cfg=s' => \$mock_cfg,
|
||||
'mock-uniqueext=s' => \$mock_uniqueext,
|
||||
'result-dir=s' => \$result_dir,
|
||||
'log-dir=s' => \$log_dir,
|
||||
'skip-install!' => \$skip_install,
|
||||
) or die usage();
|
||||
|
||||
die "Run as root (current uid=$>)\n" if $> != 0;
|
||||
die "Missing spec file: $spec_file\n" if !-f $spec_file;
|
||||
|
||||
for my $bin (qw(wget mock rpmbuild rpm dnf file bash grep)) {
|
||||
run("command -v " . sh_quote($bin) . " >/dev/null 2>&1");
|
||||
}
|
||||
|
||||
my ($version, @spec_assets) = parse_spec($spec_file);
|
||||
die "Could not parse Version from $spec_file\n" if !$version;
|
||||
|
||||
if (!$source_file) {
|
||||
$source_file = "elilo-$version-source.tar.gz";
|
||||
}
|
||||
|
||||
my $source_path = "$pkg_dir/$source_file";
|
||||
my $arch = capture('uname -m');
|
||||
if (!$mock_cfg) {
|
||||
my $os_id = capture(q{bash -lc 'source /etc/os-release; echo $ID'});
|
||||
$mock_cfg = "${os_id}+epel-10-${arch}";
|
||||
}
|
||||
my $mock_uniqueext_opt = $mock_uniqueext ne ''
|
||||
? ' --uniqueext ' . sh_quote($mock_uniqueext)
|
||||
: '';
|
||||
|
||||
print_step("Configuration");
|
||||
print "repo_root: $repo_root\n";
|
||||
print "pkg_dir: $pkg_dir\n";
|
||||
print "work_dir: $work_dir\n";
|
||||
print "result_dir: $result_dir\n";
|
||||
print "log_dir: $log_dir\n";
|
||||
print "mock_cfg: $mock_cfg\n";
|
||||
print "mock_uniqueext: " . ($mock_uniqueext ne '' ? $mock_uniqueext : '(none)') . "\n";
|
||||
print "source_url: $source_url\n";
|
||||
print "source_file:$source_file\n";
|
||||
print "skip_install: $skip_install\n";
|
||||
|
||||
make_path($result_dir);
|
||||
make_path($log_dir);
|
||||
|
||||
print_step("Mock config check");
|
||||
run("mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt . " --print-root-path >/dev/null");
|
||||
|
||||
print_step("Download upstream source");
|
||||
run("wget --spider " . sh_quote($source_url));
|
||||
run("wget -O " . sh_quote($source_path) . " " . sh_quote($source_url));
|
||||
normalize_source_archive($source_path, $version, $work_dir);
|
||||
|
||||
print_step("Verify spec assets");
|
||||
for my $asset (@spec_assets) {
|
||||
my $path = "$pkg_dir/$asset";
|
||||
die "Missing required spec asset: $path\n" if !-f $path;
|
||||
}
|
||||
print "Verified " . scalar(@spec_assets) . " Source/Patch assets from spec.\n";
|
||||
|
||||
print_step("Stage files for patch-application check");
|
||||
remove_tree($work_dir) if -d $work_dir;
|
||||
my $prep_top = "$work_dir/prep";
|
||||
for my $d (qw(BUILD BUILDROOT RPMS SOURCES SPECS SRPMS)) {
|
||||
make_path("$prep_top/$d");
|
||||
}
|
||||
copy($spec_file, "$prep_top/SPECS/elilo-xcat.spec")
|
||||
or die "Failed to copy spec to prep topdir: $!\n";
|
||||
for my $asset (@spec_assets) {
|
||||
copy("$pkg_dir/$asset", "$prep_top/SOURCES/$asset")
|
||||
or die "Failed to copy $asset into prep SOURCES: $!\n";
|
||||
}
|
||||
|
||||
print_step("Apply patches in %prep");
|
||||
my $prep_log = "$log_dir/prep.log";
|
||||
run(
|
||||
"rpmbuild --define " . sh_quote("_topdir $prep_top") .
|
||||
" -bp --nodeps " . sh_quote("$prep_top/SPECS/elilo-xcat.spec") .
|
||||
" > " . sh_quote($prep_log) . " 2>&1"
|
||||
);
|
||||
my $patch_count = capture(
|
||||
"grep -c '^Patch #' " . sh_quote($prep_log) . " || true"
|
||||
);
|
||||
print "Patch application check passed. Applied patches: $patch_count\n";
|
||||
|
||||
print_step("Build SRPM with mock");
|
||||
my $srpm_out = "$work_dir/srpm";
|
||||
make_path($srpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --buildsrpm --spec " . sh_quote($spec_file) .
|
||||
" --sources " . sh_quote($pkg_dir) .
|
||||
" --resultdir " . sh_quote($srpm_out)
|
||||
);
|
||||
|
||||
my @srpms = sort glob("$srpm_out/elilo-xcat-*.src.rpm");
|
||||
die "SRPM not generated in $srpm_out\n" if !@srpms;
|
||||
my $srpm = $srpms[-1];
|
||||
print "SRPM: $srpm\n";
|
||||
|
||||
print_step("Rebuild RPM with mock");
|
||||
my $rpm_out = "$work_dir/rpm";
|
||||
make_path($rpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --rebuild " . sh_quote($srpm) .
|
||||
" --resultdir " . sh_quote($rpm_out)
|
||||
);
|
||||
|
||||
my @all_rpms = sort glob("$rpm_out/*.rpm");
|
||||
die "No RPMs generated in $rpm_out\n" if !@all_rpms;
|
||||
|
||||
my $main_rpm = '';
|
||||
for my $rpm (@all_rpms) {
|
||||
next if $rpm =~ /\.src\.rpm$/;
|
||||
my $name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($rpm));
|
||||
my $rarch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($rpm));
|
||||
if ($name eq 'elilo-xcat' && $rarch eq 'noarch') {
|
||||
$main_rpm = $rpm;
|
||||
last;
|
||||
}
|
||||
}
|
||||
die "Could not find main elilo-xcat noarch RPM in $rpm_out\n" if !$main_rpm;
|
||||
|
||||
print_step("Verify generated RPM");
|
||||
my $rpm_name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($main_rpm));
|
||||
my $rpm_arch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($main_rpm));
|
||||
die "Unexpected RPM name: $rpm_name\n" if $rpm_name ne 'elilo-xcat';
|
||||
die "Unexpected RPM arch: $rpm_arch (expected noarch)\n" if $rpm_arch ne 'noarch';
|
||||
run(
|
||||
"rpm -qpl " . sh_quote($main_rpm) .
|
||||
" | grep -Fx /tftpboot/xcat/elilo-x64.efi >/dev/null"
|
||||
);
|
||||
print "Verified RPM name/arch/payload: $main_rpm\n";
|
||||
|
||||
print_step("Copy artifacts and logs");
|
||||
for my $rpm (@all_rpms) {
|
||||
copy($rpm, $result_dir) or die "Failed to copy $rpm to $result_dir: $!\n";
|
||||
}
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$rpm_out/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$log_dir/$log")
|
||||
or die "Failed to copy $src to $log_dir: $!\n";
|
||||
}
|
||||
|
||||
if (!$skip_install) {
|
||||
print_step("Install RPM and run smoke tests");
|
||||
run("dnf -y install " . sh_quote($main_rpm));
|
||||
|
||||
my $efi_file = '/tftpboot/xcat/elilo-x64.efi';
|
||||
die "Missing installed EFI binary: $efi_file\n" if !-f $efi_file;
|
||||
|
||||
my $file_log = "$log_dir/smoke-file.log";
|
||||
my $qf_log = "$log_dir/smoke-rpm-qf.log";
|
||||
my $rc_file = run_capture_rc("file $efi_file", $file_log);
|
||||
my $rc_qf = run_capture_rc("rpm -qf $efi_file", $qf_log);
|
||||
|
||||
die "Smoke check failed: file returned $rc_file\n" if $rc_file != 0;
|
||||
die "Smoke check failed: rpm -qf returned $rc_qf\n" if $rc_qf != 0;
|
||||
|
||||
my $file_out = slurp($file_log);
|
||||
my $qf_out = slurp($qf_log);
|
||||
|
||||
die "EFI file signature check failed:\n$file_out\n"
|
||||
if $file_out !~ /(EFI application|PE32\+ executable)/i;
|
||||
die "Installed file is not owned by elilo-xcat:\n$qf_out\n"
|
||||
if $qf_out !~ /^elilo-xcat-/m;
|
||||
|
||||
my $summary = "$log_dir/smoke-summary.txt";
|
||||
open my $sfh, '>', $summary or die "Cannot write $summary: $!\n";
|
||||
print {$sfh} "efi_file=$efi_file\n";
|
||||
print {$sfh} "rc_file=$rc_file\n";
|
||||
print {$sfh} "rc_qf=$rc_qf\n";
|
||||
close $sfh;
|
||||
}
|
||||
|
||||
print_step("Completed");
|
||||
print "Main RPM: $main_rpm\n";
|
||||
print "Artifacts: $result_dir\n";
|
||||
print "Logs: $log_dir\n";
|
||||
exit 0;
|
||||
|
||||
sub usage {
|
||||
return <<"USAGE";
|
||||
Usage: $0 [options]
|
||||
--source-url URL Upstream tarball URL (default: $source_url)
|
||||
--source-file FILE Source filename stored in elilo/ (default: inferred from spec version)
|
||||
--work-dir PATH Temporary work dir (default: $work_dir)
|
||||
--mock-cfg NAME Mock config (default: <ID>+epel-10-<ARCH>)
|
||||
--mock-uniqueext TXT Optional mock --uniqueext suffix to isolate concurrent builds
|
||||
--result-dir PATH Output RPM/SRPM directory (default: $result_dir)
|
||||
--log-dir PATH Log directory (default: $log_dir)
|
||||
--skip-install Skip dnf install + smoke tests
|
||||
USAGE
|
||||
}
|
||||
|
||||
sub parse_spec {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot open spec $path: $!\n";
|
||||
|
||||
my $version = '';
|
||||
my @assets;
|
||||
while (my $line = <$fh>) {
|
||||
if ($line =~ /^Version:\s*(\S+)/) {
|
||||
$version = $1;
|
||||
}
|
||||
if ($line =~ /^(?:Source|Patch)\d*:\s*(\S+)/) {
|
||||
my $asset = $1;
|
||||
push @assets, $asset;
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
|
||||
@assets = map {
|
||||
my $v = $_;
|
||||
$v =~ s/%\{version\}/$version/g;
|
||||
$v =~ s/%\{ver\}/$version/g;
|
||||
$v;
|
||||
} @assets;
|
||||
|
||||
return ($version, @assets);
|
||||
}
|
||||
|
||||
sub normalize_source_archive {
|
||||
my ($archive, $version, $work_base) = @_;
|
||||
|
||||
my $has_elilo = capture(
|
||||
"tar -tzf " . sh_quote($archive) .
|
||||
" | grep -E '^(\\./)?elilo/' | head -n1 || true"
|
||||
);
|
||||
return if $has_elilo ne '';
|
||||
|
||||
my $nested = capture(
|
||||
"tar -tzf " . sh_quote($archive) .
|
||||
" | grep -E '^(\\./)?elilo-$version-source\\.tar\\.gz\$' | head -n1 || true"
|
||||
);
|
||||
die "Downloaded archive does not contain elilo source payload: $archive\n"
|
||||
if $nested eq '';
|
||||
|
||||
my $normalize_dir = "$work_base/source-normalize";
|
||||
remove_tree($normalize_dir) if -d $normalize_dir;
|
||||
make_path($normalize_dir);
|
||||
|
||||
run(
|
||||
"tar -xzf " . sh_quote($archive) .
|
||||
" -C " . sh_quote($normalize_dir) .
|
||||
" " . sh_quote($nested)
|
||||
);
|
||||
|
||||
my $nested_rel = $nested;
|
||||
$nested_rel =~ s{^\./}{};
|
||||
my $nested_path = "$normalize_dir/$nested_rel";
|
||||
die "Failed to extract nested source archive: $nested_path\n"
|
||||
if !-f $nested_path;
|
||||
|
||||
copy($nested_path, $archive)
|
||||
or die "Failed to normalize source archive $archive: $!\n";
|
||||
|
||||
my $recheck = capture(
|
||||
"tar -tzf " . sh_quote($archive) .
|
||||
" | grep -E '^(\\./)?elilo/' | head -n1 || true"
|
||||
);
|
||||
die "Normalized source archive still missing elilo top-level tree: $archive\n"
|
||||
if $recheck eq '';
|
||||
}
|
||||
|
||||
sub print_step {
|
||||
my ($msg) = @_;
|
||||
print "\n== $msg ==\n";
|
||||
}
|
||||
|
||||
sub sh_quote {
|
||||
my ($s) = @_;
|
||||
$s =~ s/'/'"'"'/g;
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $rc = system($cmd);
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub capture {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $out = `$cmd`;
|
||||
my $rc = $?;
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\nOutput:\n$out\n";
|
||||
}
|
||||
chomp $out;
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub run_capture_rc {
|
||||
my ($cmd, $log_file) = @_;
|
||||
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
|
||||
print "+ $full\n";
|
||||
my $rc = system($full);
|
||||
return $rc == -1 ? 255 : ($rc >> 8);
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot read $path: $!\n";
|
||||
local $/;
|
||||
my $content = <$fh>;
|
||||
close $fh;
|
||||
return $content;
|
||||
}
|
||||
398
goconserver/mockbuild.pl
Executable file
398
goconserver/mockbuild.pl
Executable file
@@ -0,0 +1,398 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname basename);
|
||||
use File::Copy qw(copy);
|
||||
use File::Path qw(make_path remove_tree);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
|
||||
my $script_dir = abs_path(dirname(__FILE__));
|
||||
my $repo_root = abs_path("$script_dir/..");
|
||||
my $pkg_dir = "$repo_root/goconserver";
|
||||
my $work_dir = '/tmp/goconserver-mockbuild';
|
||||
my $mock_cfg = '';
|
||||
my $mock_uniqueext = '';
|
||||
my $result_dir = '';
|
||||
my $log_dir = '';
|
||||
my $src_rpm = '';
|
||||
my $src_rpm_url = '';
|
||||
my $skip_install = 0;
|
||||
|
||||
GetOptions(
|
||||
'work-dir=s' => \$work_dir,
|
||||
'mock-cfg=s' => \$mock_cfg,
|
||||
'mock-uniqueext=s' => \$mock_uniqueext,
|
||||
'result-dir=s' => \$result_dir,
|
||||
'log-dir=s' => \$log_dir,
|
||||
'src-rpm=s' => \$src_rpm,
|
||||
'src-rpm-url=s' => \$src_rpm_url,
|
||||
'skip-install!' => \$skip_install,
|
||||
) or die usage();
|
||||
|
||||
die "Run as root (current uid=$>)\n" if $> != 0;
|
||||
die "Missing package directory: $pkg_dir\n" if !-d $pkg_dir;
|
||||
|
||||
for my $bin (qw(mock rpmbuild rpm dnf ldd bash grep tar wget sha256sum cut)) {
|
||||
run("command -v " . sh_quote($bin) . " >/dev/null 2>&1");
|
||||
}
|
||||
my $has_bsdtar = command_exists('bsdtar');
|
||||
if (!$has_bsdtar) {
|
||||
for my $bin (qw(rpm2cpio cpio)) {
|
||||
run("command -v " . sh_quote($bin) . " >/dev/null 2>&1");
|
||||
}
|
||||
}
|
||||
|
||||
my $arch = capture('uname -m');
|
||||
if (!$mock_cfg) {
|
||||
my $os_id = capture(q{bash -lc 'source /etc/os-release; echo $ID'});
|
||||
$mock_cfg = "${os_id}+epel-10-${arch}";
|
||||
}
|
||||
my $mock_uniqueext_opt = $mock_uniqueext ne ''
|
||||
? ' --uniqueext ' . sh_quote($mock_uniqueext)
|
||||
: '';
|
||||
|
||||
if (!$result_dir) {
|
||||
$result_dir = "$repo_root/build-output/list5/goconserver/$arch";
|
||||
}
|
||||
if (!$log_dir) {
|
||||
$log_dir = "$repo_root/build-logs/list5/goconserver/$arch";
|
||||
}
|
||||
|
||||
make_path($result_dir);
|
||||
make_path($log_dir);
|
||||
make_path($work_dir);
|
||||
|
||||
if ($src_rpm_url) {
|
||||
my $dst = "$work_dir/" . basename($src_rpm_url);
|
||||
print_step("Download source RPM");
|
||||
run("wget --spider " . sh_quote($src_rpm_url));
|
||||
run("wget -O " . sh_quote($dst) . " " . sh_quote($src_rpm_url));
|
||||
my $sha = capture("sha256sum " . sh_quote($dst) . " | cut -d ' ' -f1");
|
||||
open my $mfh, '>', "$log_dir/source-rpm.txt"
|
||||
or die "Cannot write $log_dir/source-rpm.txt: $!\n";
|
||||
print {$mfh} "url=$src_rpm_url\n";
|
||||
print {$mfh} "path=$dst\n";
|
||||
print {$mfh} "sha256=$sha\n";
|
||||
close $mfh;
|
||||
$src_rpm = $dst;
|
||||
}
|
||||
|
||||
if (!$src_rpm) {
|
||||
my @candidates;
|
||||
push @candidates, glob("$repo_root/build-output/list5/goconserver/$arch/goconserver-*.src.rpm");
|
||||
push @candidates, glob("$repo_root/goconserver-build-$arch/results/srpm/goconserver-*.src.rpm");
|
||||
push @candidates, glob("$repo_root/goconserver-build-$arch/results/rpm/goconserver-*.src.rpm");
|
||||
@candidates = sort @candidates;
|
||||
$src_rpm = $candidates[-1] if @candidates;
|
||||
}
|
||||
die "Could not locate goconserver source RPM. Use --src-rpm or --src-rpm-url.\n"
|
||||
if !$src_rpm || !-f $src_rpm;
|
||||
|
||||
print_step("Configuration");
|
||||
print "repo_root: $repo_root\n";
|
||||
print "pkg_dir: $pkg_dir\n";
|
||||
print "work_dir: $work_dir\n";
|
||||
print "result_dir: $result_dir\n";
|
||||
print "log_dir: $log_dir\n";
|
||||
print "arch: $arch\n";
|
||||
print "mock_cfg: $mock_cfg\n";
|
||||
print "mock_uniqueext: " . ($mock_uniqueext ne '' ? $mock_uniqueext : '(none)') . "\n";
|
||||
print "src_rpm: $src_rpm\n";
|
||||
print "skip_install:$skip_install\n";
|
||||
print "extractor: " . ($has_bsdtar ? 'bsdtar' : 'rpm2cpio|cpio') . "\n";
|
||||
|
||||
print_step("Mock config check");
|
||||
run("mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt . " --print-root-path >/dev/null");
|
||||
|
||||
print_step("Extract source RPM contents");
|
||||
my $stage_dir = "$work_dir/stage";
|
||||
remove_tree($stage_dir) if -d $stage_dir;
|
||||
make_path($stage_dir);
|
||||
if ($has_bsdtar) {
|
||||
run("bsdtar -xf " . sh_quote($src_rpm) . " -C " . sh_quote($stage_dir));
|
||||
} else {
|
||||
my $extract_cmd =
|
||||
"cd " . sh_quote($stage_dir) .
|
||||
" && rpm2cpio " . sh_quote($src_rpm) .
|
||||
" | cpio -idm --quiet";
|
||||
run(
|
||||
"bash -lc " .
|
||||
sh_quote($extract_cmd)
|
||||
);
|
||||
}
|
||||
|
||||
my @specs = sort glob("$stage_dir/*.spec");
|
||||
die "Expected exactly one spec in $stage_dir, found " . scalar(@specs) . "\n"
|
||||
if @specs != 1;
|
||||
my $spec_file = $specs[0];
|
||||
|
||||
my ($version, @assets) = parse_spec($spec_file);
|
||||
die "Could not parse Version from $spec_file\n" if !$version;
|
||||
die "No Source/Patch assets parsed from $spec_file\n" if !@assets;
|
||||
|
||||
for my $asset (@assets) {
|
||||
my $path = "$stage_dir/$asset";
|
||||
die "Missing extracted spec asset: $path\n" if !-f $path;
|
||||
}
|
||||
|
||||
my @repack = grep { /goconserver-repack-.*\.tar\.gz$/ } @assets;
|
||||
die "Expected goconserver-repack source tar from spec assets.\n" if !@repack;
|
||||
my $repack_tar = "$stage_dir/$repack[0]";
|
||||
|
||||
print_step("Verify repack payload");
|
||||
for my $required (
|
||||
'/usr/bin/goconserver',
|
||||
'/usr/bin/congo',
|
||||
'/usr/lib/systemd/system/goconserver.service',
|
||||
'/etc/goconserver/server.conf'
|
||||
) {
|
||||
my $rel = substr($required, 1);
|
||||
run(
|
||||
"tar -tzf " . sh_quote($repack_tar) .
|
||||
" | grep -F " . sh_quote("./$rel") .
|
||||
" >/dev/null"
|
||||
);
|
||||
}
|
||||
|
||||
print_step("Run %prep check");
|
||||
my $prep_top = "$work_dir/prep";
|
||||
remove_tree($prep_top) if -d $prep_top;
|
||||
for my $d (qw(BUILD BUILDROOT RPMS SOURCES SPECS SRPMS)) {
|
||||
make_path("$prep_top/$d");
|
||||
}
|
||||
copy($spec_file, "$prep_top/SPECS/" . basename($spec_file))
|
||||
or die "Failed to copy spec for prep check: $!\n";
|
||||
for my $asset (@assets) {
|
||||
copy("$stage_dir/$asset", "$prep_top/SOURCES/$asset")
|
||||
or die "Failed to copy $asset for prep check: $!\n";
|
||||
}
|
||||
run(
|
||||
"rpmbuild --define " . sh_quote("_topdir $prep_top") .
|
||||
" -bp --nodeps " . sh_quote("$prep_top/SPECS/" . basename($spec_file)) .
|
||||
" > " . sh_quote("$log_dir/prep.log") . " 2>&1"
|
||||
);
|
||||
|
||||
print_step("Build SRPM with mock");
|
||||
my $srpm_out = "$work_dir/srpm";
|
||||
remove_tree($srpm_out) if -d $srpm_out;
|
||||
make_path($srpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --buildsrpm --spec " . sh_quote($spec_file) .
|
||||
" --sources " . sh_quote($stage_dir) .
|
||||
" --resultdir " . sh_quote($srpm_out) .
|
||||
" > " . sh_quote("$log_dir/mock-buildsrpm.log") . " 2>&1"
|
||||
);
|
||||
|
||||
my @srpms = sort glob("$srpm_out/goconserver-*.src.rpm");
|
||||
die "SRPM not generated in $srpm_out\n" if !@srpms;
|
||||
my $built_srpm = $srpms[-1];
|
||||
print "SRPM: $built_srpm\n";
|
||||
|
||||
print_step("Rebuild RPM with mock");
|
||||
my $rpm_out = "$work_dir/rpm";
|
||||
remove_tree($rpm_out) if -d $rpm_out;
|
||||
make_path($rpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --rebuild " . sh_quote($built_srpm) .
|
||||
" --resultdir " . sh_quote($rpm_out) .
|
||||
" > " . sh_quote("$log_dir/mock-rebuild.log") . " 2>&1"
|
||||
);
|
||||
|
||||
my @all_rpms = sort glob("$rpm_out/*.rpm");
|
||||
die "No RPMs generated in $rpm_out\n" if !@all_rpms;
|
||||
|
||||
my $main_rpm = '';
|
||||
for my $rpm (@all_rpms) {
|
||||
next if $rpm =~ /\.src\.rpm$/;
|
||||
my $name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($rpm));
|
||||
my $rarch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($rpm));
|
||||
if ($name eq 'goconserver' && $rarch eq $arch) {
|
||||
$main_rpm = $rpm;
|
||||
last;
|
||||
}
|
||||
}
|
||||
die "Could not find main goconserver RPM in $rpm_out\n" if !$main_rpm;
|
||||
|
||||
print_step("Verify generated RPM");
|
||||
my $rpm_name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($main_rpm));
|
||||
my $rpm_arch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($main_rpm));
|
||||
die "Unexpected main RPM name: $rpm_name\n" if $rpm_name ne 'goconserver';
|
||||
die "Unexpected main RPM arch: $rpm_arch (expected $arch)\n" if $rpm_arch ne $arch;
|
||||
for my $required (
|
||||
'/usr/bin/goconserver',
|
||||
'/usr/bin/congo',
|
||||
'/usr/lib/systemd/system/goconserver.service'
|
||||
) {
|
||||
run("rpm -qpl " . sh_quote($main_rpm) . " | grep -Fx " . sh_quote($required) . " >/dev/null");
|
||||
}
|
||||
|
||||
print_step("Copy artifacts and logs");
|
||||
for my $rpm (@all_rpms) {
|
||||
copy($rpm, $result_dir) or die "Failed to copy $rpm to $result_dir: $!\n";
|
||||
}
|
||||
copy($built_srpm, $result_dir) or die "Failed to copy $built_srpm to $result_dir: $!\n";
|
||||
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$rpm_out/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$log_dir/$log") or die "Failed to copy $src to $log_dir: $!\n";
|
||||
}
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$srpm_out/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$log_dir/srpm-$log") or die "Failed to copy $src to $log_dir: $!\n";
|
||||
}
|
||||
|
||||
if (!$skip_install) {
|
||||
print_step("Install RPM and run smoke tests");
|
||||
run("dnf -y install " . sh_quote($main_rpm));
|
||||
|
||||
my $bin_main = '/usr/bin/goconserver';
|
||||
my $bin_cli = '/usr/bin/congo';
|
||||
die "Missing installed binary: $bin_main\n" if !-x $bin_main;
|
||||
die "Missing installed binary: $bin_cli\n" if !-x $bin_cli;
|
||||
|
||||
my $rc_help_main = run_capture_rc("$bin_main -h", "$log_dir/smoke-goconserver-help.log");
|
||||
my $rc_help_cli = run_capture_rc("$bin_cli -h", "$log_dir/smoke-congo-help.log");
|
||||
my $rc_ldd_main = run_capture_rc("ldd $bin_main", "$log_dir/smoke-goconserver-ldd.log");
|
||||
my $rc_ldd_cli = run_capture_rc("ldd $bin_cli", "$log_dir/smoke-congo-ldd.log");
|
||||
|
||||
die "goconserver -h returned unexpected rc=$rc_help_main\n"
|
||||
if $rc_help_main != 0 && $rc_help_main != 1;
|
||||
die "congo -h returned unexpected rc=$rc_help_cli\n"
|
||||
if $rc_help_cli != 0 && $rc_help_cli != 1;
|
||||
die "ldd goconserver returned rc=$rc_ldd_main\n" if $rc_ldd_main != 0;
|
||||
die "ldd congo returned rc=$rc_ldd_cli\n" if $rc_ldd_cli != 0;
|
||||
|
||||
my $help_main = slurp("$log_dir/smoke-goconserver-help.log");
|
||||
my $help_cli = slurp("$log_dir/smoke-congo-help.log");
|
||||
my $ldd_main = slurp("$log_dir/smoke-goconserver-ldd.log");
|
||||
my $ldd_cli = slurp("$log_dir/smoke-congo-ldd.log");
|
||||
|
||||
die "goconserver help output missing usage text\n"
|
||||
if $help_main !~ /usage|goconserver/i;
|
||||
die "congo help output missing usage text\n"
|
||||
if $help_cli !~ /usage|congo/i;
|
||||
die "goconserver ldd output missing libc\n"
|
||||
if $ldd_main !~ /libc/;
|
||||
die "congo ldd output missing libc\n"
|
||||
if $ldd_cli !~ /libc/;
|
||||
|
||||
open my $sfh, '>', "$log_dir/smoke-summary.txt"
|
||||
or die "Cannot write $log_dir/smoke-summary.txt: $!\n";
|
||||
print {$sfh} "binary_main=$bin_main\n";
|
||||
print {$sfh} "binary_cli=$bin_cli\n";
|
||||
print {$sfh} "rc_help_main=$rc_help_main\n";
|
||||
print {$sfh} "rc_help_cli=$rc_help_cli\n";
|
||||
print {$sfh} "rc_ldd_main=$rc_ldd_main\n";
|
||||
print {$sfh} "rc_ldd_cli=$rc_ldd_cli\n";
|
||||
close $sfh;
|
||||
}
|
||||
|
||||
print_step("Completed");
|
||||
print "Main RPM: $main_rpm\n";
|
||||
print "Artifacts: $result_dir\n";
|
||||
print "Logs: $log_dir\n";
|
||||
exit 0;
|
||||
|
||||
sub usage {
|
||||
return <<"USAGE";
|
||||
Usage: $0 [options]
|
||||
--src-rpm PATH Source RPM containing goconserver.spec + repack tar
|
||||
--src-rpm-url URL Optional URL to download source RPM before build
|
||||
--work-dir PATH Temporary work dir (default: $work_dir)
|
||||
--mock-cfg NAME Mock config (default: <ID>+epel-10-<ARCH>)
|
||||
--mock-uniqueext TXT Optional mock --uniqueext suffix to isolate concurrent builds
|
||||
--result-dir PATH Output RPM/SRPM directory (default: build-output/list5/goconserver/<ARCH>)
|
||||
--log-dir PATH Log directory (default: build-logs/list5/goconserver/<ARCH>)
|
||||
--skip-install Skip dnf install + smoke tests
|
||||
USAGE
|
||||
}
|
||||
|
||||
sub parse_spec {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot open spec $path: $!\n";
|
||||
|
||||
my $version = '';
|
||||
my @assets;
|
||||
while (my $line = <$fh>) {
|
||||
if ($line =~ /^Version:\s*(\S+)/) {
|
||||
$version = $1;
|
||||
}
|
||||
if ($line =~ /^(?:Source|Patch)\d*:\s*(\S+)/) {
|
||||
my $asset = $1;
|
||||
push @assets, $asset;
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
|
||||
@assets = map {
|
||||
my $v = $_;
|
||||
$v =~ s/%\{version\}/$version/g;
|
||||
$v =~ s/%\{ver\}/$version/g;
|
||||
$v;
|
||||
} @assets;
|
||||
|
||||
return ($version, @assets);
|
||||
}
|
||||
|
||||
sub command_exists {
|
||||
my ($bin) = @_;
|
||||
my $rc = system("command -v " . sh_quote($bin) . " >/dev/null 2>&1");
|
||||
return $rc == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
sub print_step {
|
||||
my ($msg) = @_;
|
||||
print "\n== $msg ==\n";
|
||||
}
|
||||
|
||||
sub sh_quote {
|
||||
my ($s) = @_;
|
||||
$s =~ s/'/'"'"'/g;
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $rc = system($cmd);
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub capture {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $out = `$cmd`;
|
||||
my $rc = $?;
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\nOutput:\n$out\n";
|
||||
}
|
||||
chomp $out;
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub run_capture_rc {
|
||||
my ($cmd, $log_file) = @_;
|
||||
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
|
||||
print "+ $full\n";
|
||||
my $rc = system($full);
|
||||
return $rc == -1 ? 255 : ($rc >> 8);
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot read $path: $!\n";
|
||||
local $/;
|
||||
my $content = <$fh>;
|
||||
close $fh;
|
||||
return $content;
|
||||
}
|
||||
362
grub2-xcat/mockbuild.pl
Executable file
362
grub2-xcat/mockbuild.pl
Executable file
@@ -0,0 +1,362 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname basename);
|
||||
use File::Copy qw(copy);
|
||||
use File::Path qw(make_path remove_tree);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
|
||||
my $script_dir = abs_path(dirname(__FILE__));
|
||||
my $repo_root = abs_path("$script_dir/..");
|
||||
my $pkg_dir = "$repo_root/grub2-xcat";
|
||||
my $spec_file = "$pkg_dir/grub2-xcat.spec";
|
||||
my $recompile_dir = "$repo_root/grub2-xcat.recompile";
|
||||
|
||||
my $resource_mode = 'reuse-grub2-res';
|
||||
my $upstream_url = 'https://mirror.stream.centos.org/10-stream/BaseOS/source/tree/Packages/grub2-2.12-37.el10.src.rpm';
|
||||
my $upstream_file = '';
|
||||
my $work_dir = '/tmp/grub2-xcat-mockbuild';
|
||||
my $mock_cfg = '';
|
||||
my $mock_uniqueext = '';
|
||||
my $result_dir = "$repo_root/build-output/list3/grub2-xcat";
|
||||
my $log_dir = "$repo_root/build-logs/list3/grub2-xcat";
|
||||
my $skip_install = 0;
|
||||
my $skip_upstream_download = 0;
|
||||
|
||||
GetOptions(
|
||||
'resource-mode=s' => \$resource_mode,
|
||||
'upstream-url=s' => \$upstream_url,
|
||||
'upstream-file=s' => \$upstream_file,
|
||||
'work-dir=s' => \$work_dir,
|
||||
'mock-cfg=s' => \$mock_cfg,
|
||||
'mock-uniqueext=s' => \$mock_uniqueext,
|
||||
'result-dir=s' => \$result_dir,
|
||||
'log-dir=s' => \$log_dir,
|
||||
'skip-install!' => \$skip_install,
|
||||
'skip-upstream-download!' => \$skip_upstream_download,
|
||||
) or die usage();
|
||||
|
||||
die "Run as root (current uid=$>)\n" if $> != 0;
|
||||
die "Missing spec file: $spec_file\n" if !-f $spec_file;
|
||||
die "Missing recompile dir: $recompile_dir\n" if !-d $recompile_dir;
|
||||
die "Invalid --resource-mode '$resource_mode'\n"
|
||||
if $resource_mode ne 'reuse-grub2-res' && $resource_mode ne 'regenerate-from-el10-srcrpm';
|
||||
die "Mode regenerate-from-el10-srcrpm is not supported in this script yet; use reuse-grub2-res on x86_64 first.\n"
|
||||
if $resource_mode eq 'regenerate-from-el10-srcrpm';
|
||||
|
||||
for my $bin (qw(wget mock rpmbuild rpm dnf file bash tar sha256sum grep cmp cut)) {
|
||||
run("command -v " . sh_quote($bin) . " >/dev/null 2>&1");
|
||||
}
|
||||
|
||||
my ($version, @spec_assets) = parse_spec($spec_file);
|
||||
die "Could not parse Version from $spec_file\n" if !$version;
|
||||
|
||||
if (!$upstream_file) {
|
||||
$upstream_file = basename($upstream_url);
|
||||
}
|
||||
die "Could not derive upstream file name from URL: $upstream_url\n" if !$upstream_file;
|
||||
my $upstream_path = "$recompile_dir/$upstream_file";
|
||||
|
||||
my $arch = capture('uname -m');
|
||||
if (!$mock_cfg) {
|
||||
my $os_id = capture(q{bash -lc 'source /etc/os-release; echo $ID'});
|
||||
$mock_cfg = "${os_id}+epel-10-${arch}";
|
||||
}
|
||||
my $mock_uniqueext_opt = $mock_uniqueext ne ''
|
||||
? ' --uniqueext ' . sh_quote($mock_uniqueext)
|
||||
: '';
|
||||
|
||||
print_step("Configuration");
|
||||
print "repo_root: $repo_root\n";
|
||||
print "pkg_dir: $pkg_dir\n";
|
||||
print "spec_file: $spec_file\n";
|
||||
print "recompile_dir: $recompile_dir\n";
|
||||
print "resource_mode: $resource_mode\n";
|
||||
print "work_dir: $work_dir\n";
|
||||
print "result_dir: $result_dir\n";
|
||||
print "log_dir: $log_dir\n";
|
||||
print "mock_cfg: $mock_cfg\n";
|
||||
print "mock_uniqueext: " . ($mock_uniqueext ne '' ? $mock_uniqueext : '(none)') . "\n";
|
||||
print "upstream_url: $upstream_url\n";
|
||||
print "upstream_file: $upstream_file\n";
|
||||
print "skip_install: $skip_install\n";
|
||||
print "skip_upstream_download: $skip_upstream_download\n";
|
||||
|
||||
make_path($result_dir);
|
||||
make_path($log_dir);
|
||||
|
||||
print_step("Mock config check");
|
||||
run("mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt . " --print-root-path >/dev/null");
|
||||
|
||||
if (!$skip_upstream_download) {
|
||||
print_step("Download upstream source RPM");
|
||||
run("wget --spider " . sh_quote($upstream_url));
|
||||
run("wget -O " . sh_quote($upstream_path) . " " . sh_quote($upstream_url));
|
||||
my $sha = capture("sha256sum " . sh_quote($upstream_path) . " | cut -d ' ' -f1");
|
||||
my $meta_file = "$log_dir/upstream-source.txt";
|
||||
open my $mfh, '>', $meta_file or die "Cannot write $meta_file: $!\n";
|
||||
print {$mfh} "url=$upstream_url\n";
|
||||
print {$mfh} "file=$upstream_path\n";
|
||||
print {$mfh} "sha256=$sha\n";
|
||||
close $mfh;
|
||||
print "Downloaded upstream source rpm: $upstream_path\n";
|
||||
print "SHA256: $sha\n";
|
||||
}
|
||||
|
||||
print_step("Verify grub2 resource payload");
|
||||
my $resource_tar = "$pkg_dir/grub2-res.tar.gz";
|
||||
die "Missing required resource tarball: $resource_tar\n" if !-f $resource_tar;
|
||||
run(
|
||||
"tar -tzf " . sh_quote($resource_tar) .
|
||||
" | grep -F 'powerpc-ieee1275/' >/dev/null"
|
||||
);
|
||||
run(
|
||||
"tar -tzf " . sh_quote($resource_tar) .
|
||||
" | grep -F 'powerpc-ieee1275/core.elf' >/dev/null"
|
||||
);
|
||||
|
||||
print_step("Verify spec assets");
|
||||
for my $asset (@spec_assets) {
|
||||
my $path = "$pkg_dir/$asset";
|
||||
die "Missing required spec asset: $path\n" if !-f $path;
|
||||
}
|
||||
print "Verified " . scalar(@spec_assets) . " Source/Patch assets from spec.\n";
|
||||
|
||||
print_step("Stage files for prep check");
|
||||
remove_tree($work_dir) if -d $work_dir;
|
||||
my $prep_top = "$work_dir/prep";
|
||||
for my $d (qw(BUILD BUILDROOT RPMS SOURCES SPECS SRPMS)) {
|
||||
make_path("$prep_top/$d");
|
||||
}
|
||||
copy($spec_file, "$prep_top/SPECS/grub2-xcat.spec")
|
||||
or die "Failed to copy spec to prep topdir: $!\n";
|
||||
for my $asset (@spec_assets) {
|
||||
copy("$pkg_dir/$asset", "$prep_top/SOURCES/$asset")
|
||||
or die "Failed to copy $asset into prep SOURCES: $!\n";
|
||||
}
|
||||
|
||||
print_step("Apply %prep flow");
|
||||
my $prep_log = "$log_dir/prep.log";
|
||||
run(
|
||||
"rpmbuild --define " . sh_quote("_topdir $prep_top") .
|
||||
" -bp --nodeps " . sh_quote("$prep_top/SPECS/grub2-xcat.spec") .
|
||||
" > " . sh_quote($prep_log) . " 2>&1"
|
||||
);
|
||||
my $patch_count = capture("grep -c '^Patch #' " . sh_quote($prep_log) . " || true");
|
||||
print "Prep dry run passed. Applied patches: $patch_count\n";
|
||||
|
||||
print_step("Build SRPM with mock");
|
||||
my $srpm_out = "$work_dir/srpm";
|
||||
make_path($srpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --buildsrpm --spec " . sh_quote($spec_file) .
|
||||
" --sources " . sh_quote($pkg_dir) .
|
||||
" --resultdir " . sh_quote($srpm_out)
|
||||
);
|
||||
|
||||
my @srpms = sort glob("$srpm_out/grub2-xcat-*.src.rpm");
|
||||
die "SRPM not generated in $srpm_out\n" if !@srpms;
|
||||
my $srpm = $srpms[-1];
|
||||
print "SRPM: $srpm\n";
|
||||
|
||||
print_step("Rebuild RPM with mock");
|
||||
my $rpm_out = "$work_dir/rpm";
|
||||
make_path($rpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --rebuild " . sh_quote($srpm) .
|
||||
" --resultdir " . sh_quote($rpm_out)
|
||||
);
|
||||
|
||||
my @all_rpms = sort glob("$rpm_out/*.rpm");
|
||||
die "No RPMs generated in $rpm_out\n" if !@all_rpms;
|
||||
|
||||
my $main_rpm = '';
|
||||
for my $rpm (@all_rpms) {
|
||||
next if $rpm =~ /\.src\.rpm$/;
|
||||
my $name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($rpm));
|
||||
my $rarch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($rpm));
|
||||
if ($name eq 'grub2-xcat' && $rarch eq 'noarch') {
|
||||
$main_rpm = $rpm;
|
||||
last;
|
||||
}
|
||||
}
|
||||
die "Could not find main grub2-xcat noarch RPM in $rpm_out\n" if !$main_rpm;
|
||||
|
||||
print_step("Verify generated RPM");
|
||||
my $rpm_name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($main_rpm));
|
||||
my $rpm_arch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($main_rpm));
|
||||
die "Unexpected RPM name: $rpm_name\n" if $rpm_name ne 'grub2-xcat';
|
||||
die "Unexpected RPM arch: $rpm_arch (expected noarch)\n" if $rpm_arch ne 'noarch';
|
||||
run(
|
||||
"rpm -qpl " . sh_quote($main_rpm) .
|
||||
" | grep -F '/tftpboot/boot/grub2/powerpc-ieee1275/' >/dev/null"
|
||||
);
|
||||
run(
|
||||
"rpm -qpl " . sh_quote($main_rpm) .
|
||||
" | grep -Fx /tftpboot/boot/grub2/powerpc-ieee1275/core.elf >/dev/null"
|
||||
);
|
||||
print "Verified RPM name/arch/payload: $main_rpm\n";
|
||||
|
||||
print_step("Copy artifacts and logs");
|
||||
for my $rpm (@all_rpms) {
|
||||
copy($rpm, $result_dir) or die "Failed to copy $rpm to $result_dir: $!\n";
|
||||
}
|
||||
copy($srpm, $result_dir) or die "Failed to copy $srpm to $result_dir: $!\n";
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$rpm_out/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$log_dir/$log")
|
||||
or die "Failed to copy $src to $log_dir: $!\n";
|
||||
}
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$srpm_out/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$log_dir/srpm-$log")
|
||||
or die "Failed to copy $src to $log_dir: $!\n";
|
||||
}
|
||||
|
||||
if (!$skip_install) {
|
||||
print_step("Install RPM and run smoke tests");
|
||||
run("dnf -y install " . sh_quote($main_rpm));
|
||||
|
||||
my $core = '/tftpboot/boot/grub2/powerpc-ieee1275/core.elf';
|
||||
my $grub2ppc = '/tftpboot/boot/grub2/grub2.ppc';
|
||||
die "Missing installed core image: $core\n" if !-f $core;
|
||||
die "Missing installed post script output: $grub2ppc\n" if !-f $grub2ppc;
|
||||
|
||||
my $file_core_log = "$log_dir/smoke-file-core.log";
|
||||
my $file_ppc_log = "$log_dir/smoke-file-grub2ppc.log";
|
||||
my $qf_log = "$log_dir/smoke-rpm-qf.log";
|
||||
|
||||
my $rc_file_core = run_capture_rc("file $core", $file_core_log);
|
||||
my $rc_file_ppc = run_capture_rc("file $grub2ppc", $file_ppc_log);
|
||||
my $rc_qf = run_capture_rc("rpm -qf $core", $qf_log);
|
||||
my $rc_cmp = run_capture_rc("cmp -s $core $grub2ppc", "$log_dir/smoke-cmp.log");
|
||||
|
||||
die "Smoke check failed: file core returned $rc_file_core\n" if $rc_file_core != 0;
|
||||
die "Smoke check failed: file grub2.ppc returned $rc_file_ppc\n" if $rc_file_ppc != 0;
|
||||
die "Smoke check failed: rpm -qf returned $rc_qf\n" if $rc_qf != 0;
|
||||
die "Smoke check failed: core.elf and grub2.ppc differ (cmp rc=$rc_cmp)\n" if $rc_cmp != 0;
|
||||
|
||||
my $core_out = slurp($file_core_log);
|
||||
my $qf_out = slurp($qf_log);
|
||||
|
||||
die "Core image signature check failed:\n$core_out\n"
|
||||
if $core_out !~ /ELF|data/i;
|
||||
die "Installed core image is not owned by grub2-xcat:\n$qf_out\n"
|
||||
if $qf_out !~ /^grub2-xcat-/m;
|
||||
|
||||
my $summary = "$log_dir/smoke-summary.txt";
|
||||
open my $sfh, '>', $summary or die "Cannot write $summary: $!\n";
|
||||
print {$sfh} "core=$core\n";
|
||||
print {$sfh} "grub2ppc=$grub2ppc\n";
|
||||
print {$sfh} "rc_file_core=$rc_file_core\n";
|
||||
print {$sfh} "rc_file_ppc=$rc_file_ppc\n";
|
||||
print {$sfh} "rc_qf=$rc_qf\n";
|
||||
print {$sfh} "rc_cmp=$rc_cmp\n";
|
||||
close $sfh;
|
||||
}
|
||||
|
||||
print_step("Completed");
|
||||
print "Main RPM: $main_rpm\n";
|
||||
print "Artifacts: $result_dir\n";
|
||||
print "Logs: $log_dir\n";
|
||||
exit 0;
|
||||
|
||||
sub usage {
|
||||
return <<"USAGE";
|
||||
Usage: $0 [options]
|
||||
--resource-mode MODE Build mode: reuse-grub2-res|regenerate-from-el10-srcrpm (default: $resource_mode)
|
||||
--upstream-url URL Upstream grub2 source RPM URL (default: $upstream_url)
|
||||
--upstream-file FILE Source RPM filename stored in grub2-xcat.recompile/ (default: basename of URL)
|
||||
--work-dir PATH Temporary work dir (default: $work_dir)
|
||||
--mock-cfg NAME Mock config (default: <ID>+epel-10-<ARCH>)
|
||||
--mock-uniqueext TXT Optional mock --uniqueext suffix to isolate concurrent builds
|
||||
--result-dir PATH Output RPM/SRPM directory (default: $result_dir)
|
||||
--log-dir PATH Log directory (default: $log_dir)
|
||||
--skip-upstream-download Skip wget of upstream source RPM
|
||||
--skip-install Skip dnf install + smoke tests
|
||||
USAGE
|
||||
}
|
||||
|
||||
sub parse_spec {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot open spec $path: $!\n";
|
||||
|
||||
my $version = '';
|
||||
my @assets;
|
||||
while (my $line = <$fh>) {
|
||||
if ($line =~ /^Version:\s*(\S+)/) {
|
||||
$version = $1;
|
||||
}
|
||||
if ($line =~ /^(?:Source|Patch)\d*:\s*(\S+)/) {
|
||||
my $asset = $1;
|
||||
push @assets, $asset;
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
|
||||
@assets = map {
|
||||
my $v = $_;
|
||||
$v =~ s/%\{version\}/$version/g;
|
||||
$v =~ s/%\{ver\}/$version/g;
|
||||
$v;
|
||||
} @assets;
|
||||
|
||||
return ($version, @assets);
|
||||
}
|
||||
|
||||
sub print_step {
|
||||
my ($msg) = @_;
|
||||
print "\n== $msg ==\n";
|
||||
}
|
||||
|
||||
sub sh_quote {
|
||||
my ($s) = @_;
|
||||
$s =~ s/'/'"'"'/g;
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $rc = system($cmd);
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub capture {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $out = `$cmd`;
|
||||
my $rc = $?;
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\nOutput:\n$out\n";
|
||||
}
|
||||
chomp $out;
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub run_capture_rc {
|
||||
my ($cmd, $log_file) = @_;
|
||||
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
|
||||
print "+ $full\n";
|
||||
my $rc = system($full);
|
||||
return $rc == -1 ? 255 : ($rc >> 8);
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot read $path: $!\n";
|
||||
local $/;
|
||||
my $content = <$fh>;
|
||||
close $fh;
|
||||
return $content;
|
||||
}
|
||||
13
ipmitool/0016-el10-gcc14-missing-intf-getters.patch
Normal file
13
ipmitool/0016-el10-gcc14-missing-intf-getters.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h
|
||||
index 063fdd5..fcf5937 100644
|
||||
--- a/include/ipmitool/ipmi_intf.h
|
||||
+++ b/include/ipmitool/ipmi_intf.h
|
||||
@@ -262,6 +262,8 @@ struct ipmi_intf {
|
||||
struct ipmi_intf * ipmi_intf_load(char * name);
|
||||
void ipmi_intf_print(struct ipmi_intf_support * intflist);
|
||||
|
||||
+uint16_t ipmi_intf_get_max_request_data_size(struct ipmi_intf * intf);
|
||||
+uint16_t ipmi_intf_get_max_response_data_size(struct ipmi_intf * intf);
|
||||
void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname);
|
||||
void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username);
|
||||
void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password);
|
||||
@@ -23,6 +23,7 @@ Patch12: 0012-CVE-2020-5208.patch
|
||||
Patch13: 0013-quanta-oem-support.patch
|
||||
Patch14: 0014-lanplus-cipher-retry.patch
|
||||
Patch15: 0015-lanplus-Cleanup.-Refix-6dec83ff-fix-be2c0c4b.patch
|
||||
Patch16: 0016-el10-gcc14-missing-intf-getters.patch
|
||||
|
||||
Patch80: ipmitool-%{version}-saneretry.patch
|
||||
Patch82: ipmitool-%{version}-rflash.patch
|
||||
@@ -73,6 +74,7 @@ fi
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch80 -p1
|
||||
%patch82 -p1
|
||||
%patch83 -p1
|
||||
@@ -475,4 +477,3 @@ fi
|
||||
|
||||
* Sun Mar 30 2003 <duncan@iceblink.org> 1.0-1
|
||||
- Initial release.
|
||||
|
||||
|
||||
357
ipmitool/mockbuild.pl
Executable file
357
ipmitool/mockbuild.pl
Executable file
@@ -0,0 +1,357 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname basename);
|
||||
use File::Copy qw(copy);
|
||||
use File::Path qw(make_path remove_tree);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
|
||||
my $script_dir = abs_path(dirname(__FILE__));
|
||||
my $repo_root = abs_path("$script_dir/..");
|
||||
my $pkg_dir = "$repo_root/ipmitool";
|
||||
my $spec_file = "$pkg_dir/ipmitool.spec";
|
||||
|
||||
my $source_url = 'https://github.com/ipmitool/ipmitool/archive/refs/tags/IPMITOOL_1_8_18.tar.gz';
|
||||
my $source_file = '';
|
||||
my $work_dir = '/tmp/ipmitool-xcat-mockbuild';
|
||||
my $mock_cfg = '';
|
||||
my $mock_uniqueext = '';
|
||||
my $result_dir = "$repo_root/build-output/list3/ipmitool-xcat";
|
||||
my $log_dir = "$repo_root/build-logs/list3/ipmitool-xcat";
|
||||
my $skip_install = 0;
|
||||
|
||||
GetOptions(
|
||||
'source-url=s' => \$source_url,
|
||||
'source-file=s' => \$source_file,
|
||||
'work-dir=s' => \$work_dir,
|
||||
'mock-cfg=s' => \$mock_cfg,
|
||||
'mock-uniqueext=s' => \$mock_uniqueext,
|
||||
'result-dir=s' => \$result_dir,
|
||||
'log-dir=s' => \$log_dir,
|
||||
'skip-install!' => \$skip_install,
|
||||
) or die usage();
|
||||
|
||||
die "Run as root (current uid=$>)\n" if $> != 0;
|
||||
die "Missing spec file: $spec_file\n" if !-f $spec_file;
|
||||
|
||||
for my $bin (qw(wget mock rpmbuild rpm dnf ldd bash)) {
|
||||
run("command -v " . sh_quote($bin) . " >/dev/null 2>&1");
|
||||
}
|
||||
|
||||
my ($version, @spec_assets) = parse_spec($spec_file);
|
||||
die "Could not parse Version from $spec_file\n" if !$version;
|
||||
|
||||
if (!$source_file) {
|
||||
$source_file = "ipmitool-$version.tar.gz";
|
||||
}
|
||||
|
||||
my $source_path = "$pkg_dir/$source_file";
|
||||
my $arch = capture('uname -m');
|
||||
if (!$mock_cfg) {
|
||||
my $os_id = capture(q{bash -lc 'source /etc/os-release; echo $ID'});
|
||||
$mock_cfg = "${os_id}+epel-10-${arch}";
|
||||
}
|
||||
my $mock_uniqueext_opt = $mock_uniqueext ne ''
|
||||
? ' --uniqueext ' . sh_quote($mock_uniqueext)
|
||||
: '';
|
||||
|
||||
print_step("Configuration");
|
||||
print "repo_root: $repo_root\n";
|
||||
print "pkg_dir: $pkg_dir\n";
|
||||
print "work_dir: $work_dir\n";
|
||||
print "result_dir: $result_dir\n";
|
||||
print "log_dir: $log_dir\n";
|
||||
print "mock_cfg: $mock_cfg\n";
|
||||
print "mock_uniqueext: " . ($mock_uniqueext ne '' ? $mock_uniqueext : '(none)') . "\n";
|
||||
print "source_url: $source_url\n";
|
||||
print "source_file:$source_file\n";
|
||||
print "skip_install: $skip_install\n";
|
||||
|
||||
make_path($result_dir);
|
||||
make_path($log_dir);
|
||||
|
||||
print_step("Mock config check");
|
||||
run("mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt . " --print-root-path >/dev/null");
|
||||
|
||||
print_step("Download upstream source");
|
||||
run("wget --spider " . sh_quote($source_url));
|
||||
run("wget -O " . sh_quote($source_path) . " " . sh_quote($source_url));
|
||||
normalize_source_archive($source_path, $version, $work_dir);
|
||||
|
||||
print_step("Verify spec assets");
|
||||
for my $asset (@spec_assets) {
|
||||
my $path = "$pkg_dir/$asset";
|
||||
die "Missing required spec asset: $path\n" if !-f $path;
|
||||
}
|
||||
print "Verified " . scalar(@spec_assets) . " Source/Patch assets from spec.\n";
|
||||
|
||||
print_step("Stage files for patch-application check");
|
||||
remove_tree($work_dir) if -d $work_dir;
|
||||
my $prep_top = "$work_dir/prep";
|
||||
for my $d (qw(BUILD BUILDROOT RPMS SOURCES SPECS SRPMS)) {
|
||||
make_path("$prep_top/$d");
|
||||
}
|
||||
copy($spec_file, "$prep_top/SPECS/ipmitool.spec")
|
||||
or die "Failed to copy spec to prep topdir: $!\n";
|
||||
for my $asset (@spec_assets) {
|
||||
copy("$pkg_dir/$asset", "$prep_top/SOURCES/$asset")
|
||||
or die "Failed to copy $asset into prep SOURCES: $!\n";
|
||||
}
|
||||
|
||||
print_step("Apply patches in %prep");
|
||||
my $prep_log = "$log_dir/prep.log";
|
||||
run(
|
||||
"rpmbuild --define " . sh_quote("_topdir $prep_top") .
|
||||
" -bp --nodeps " . sh_quote("$prep_top/SPECS/ipmitool.spec") .
|
||||
" > " . sh_quote($prep_log) . " 2>&1"
|
||||
);
|
||||
my $patch_count = capture(
|
||||
"grep -c '^Patch #' " . sh_quote($prep_log) . " || true"
|
||||
);
|
||||
print "Patch application check passed. Applied patches: $patch_count\n";
|
||||
|
||||
print_step("Build SRPM with mock");
|
||||
my $srpm_out = "$work_dir/srpm";
|
||||
make_path($srpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --buildsrpm --spec " . sh_quote($spec_file) .
|
||||
" --sources " . sh_quote($pkg_dir) .
|
||||
" --resultdir " . sh_quote($srpm_out)
|
||||
);
|
||||
|
||||
my @srpms = sort glob("$srpm_out/ipmitool-xcat-*.src.rpm");
|
||||
die "SRPM not generated in $srpm_out\n" if !@srpms;
|
||||
my $srpm = $srpms[-1];
|
||||
print "SRPM: $srpm\n";
|
||||
|
||||
print_step("Rebuild RPM with mock");
|
||||
my $rpm_out = "$work_dir/rpm";
|
||||
make_path($rpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --rebuild " . sh_quote($srpm) .
|
||||
" --resultdir " . sh_quote($rpm_out)
|
||||
);
|
||||
|
||||
my @arch_rpms = sort glob("$rpm_out/*.${arch}.rpm");
|
||||
die "No architecture RPMs generated in $rpm_out\n" if !@arch_rpms;
|
||||
|
||||
my $main_rpm = '';
|
||||
for my $rpm (@arch_rpms) {
|
||||
my $name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($rpm));
|
||||
if ($name eq 'ipmitool-xcat') {
|
||||
$main_rpm = $rpm;
|
||||
last;
|
||||
}
|
||||
}
|
||||
die "Could not find main ipmitool-xcat RPM in $rpm_out\n" if !$main_rpm;
|
||||
|
||||
print_step("Verify generated RPM");
|
||||
my $rpm_name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($main_rpm));
|
||||
my $rpm_arch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($main_rpm));
|
||||
die "Unexpected RPM name: $rpm_name\n" if $rpm_name ne 'ipmitool-xcat';
|
||||
die "Unexpected RPM arch: $rpm_arch (expected $arch)\n" if $rpm_arch ne $arch;
|
||||
run(
|
||||
"rpm -qpl " . sh_quote($main_rpm) .
|
||||
" | grep -Fx /opt/xcat/bin/ipmitool-xcat >/dev/null"
|
||||
);
|
||||
print "Verified RPM name/arch/payload: $main_rpm\n";
|
||||
|
||||
print_step("Copy artifacts and logs");
|
||||
for my $rpm (@arch_rpms) {
|
||||
copy($rpm, $result_dir) or die "Failed to copy $rpm to $result_dir: $!\n";
|
||||
}
|
||||
copy($srpm, $result_dir) or die "Failed to copy $srpm to $result_dir: $!\n";
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$rpm_out/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$log_dir/$log")
|
||||
or die "Failed to copy $src to $log_dir: $!\n";
|
||||
}
|
||||
|
||||
if (!$skip_install) {
|
||||
print_step("Install RPM and run smoke tests");
|
||||
run("dnf -y install " . sh_quote($main_rpm));
|
||||
|
||||
my $bin = '/opt/xcat/bin/ipmitool-xcat';
|
||||
die "Missing installed binary: $bin\n" if !-x $bin;
|
||||
|
||||
my $help_short_log = "$log_dir/smoke-help-short.log";
|
||||
my $help_long_log = "$log_dir/smoke-help-long.log";
|
||||
my $version_log = "$log_dir/smoke-version.log";
|
||||
my $open_log = "$log_dir/smoke-open-mc-info.log";
|
||||
my $ldd_log = "$log_dir/smoke-ldd.log";
|
||||
|
||||
my $rc_help_short = run_capture_rc("$bin -h", $help_short_log);
|
||||
my $rc_help_long = run_capture_rc("$bin --help", $help_long_log);
|
||||
my $rc_version = run_capture_rc("$bin -V", $version_log);
|
||||
my $rc_open = run_capture_rc("$bin -I open mc info", $open_log);
|
||||
my $rc_ldd = run_capture_rc("ldd $bin", $ldd_log);
|
||||
|
||||
die "Smoke check failed: -h returned $rc_help_short\n" if $rc_help_short != 0;
|
||||
die "Smoke check failed: -V returned $rc_version\n" if $rc_version != 0;
|
||||
die "Smoke check failed: ldd returned $rc_ldd\n" if $rc_ldd != 0;
|
||||
|
||||
my $help_short_out = slurp($help_short_log);
|
||||
my $help_long_out = slurp($help_long_log);
|
||||
my $version_out = slurp($version_log);
|
||||
my $open_out = slurp($open_log);
|
||||
my $ldd_out = slurp($ldd_log);
|
||||
|
||||
die "Short help output does not contain usage text\n"
|
||||
if $help_short_out !~ /usage:/i;
|
||||
die "Long help output does not contain usage text\n"
|
||||
if $help_long_out !~ /usage:/i;
|
||||
die "Long help returned unexpected rc=$rc_help_long (expected 0 or 1)\n"
|
||||
if $rc_help_long != 0 && $rc_help_long != 1;
|
||||
die "Version output missing expected version string\n"
|
||||
if $version_out !~ /ipmitool-xcat version \Q$version\E/i;
|
||||
die "ldd output missing libcrypto dependency\n"
|
||||
if $ldd_out !~ /libcrypto/;
|
||||
die "Expected no-IPMI failure did not occur; rc=$rc_open\n"
|
||||
if $rc_open == 0;
|
||||
die "No-IPMI probe failed with unexpected output:\n$open_out\n"
|
||||
if $open_out !~ m{Could not open device|/dev/ipmi};
|
||||
|
||||
my $summary = "$log_dir/smoke-summary.txt";
|
||||
open my $sfh, '>', $summary or die "Cannot write $summary: $!\n";
|
||||
print {$sfh} "binary=$bin\n";
|
||||
print {$sfh} "rc_help_short=$rc_help_short\n";
|
||||
print {$sfh} "rc_help_long=$rc_help_long\n";
|
||||
print {$sfh} "rc_version=$rc_version\n";
|
||||
print {$sfh} "rc_open=$rc_open\n";
|
||||
print {$sfh} "rc_ldd=$rc_ldd\n";
|
||||
close $sfh;
|
||||
}
|
||||
|
||||
print_step("Completed");
|
||||
print "Main RPM: $main_rpm\n";
|
||||
print "Artifacts: $result_dir\n";
|
||||
print "Logs: $log_dir\n";
|
||||
exit 0;
|
||||
|
||||
sub usage {
|
||||
return <<"USAGE";
|
||||
Usage: $0 [options]
|
||||
--source-url URL Upstream tarball URL (default: $source_url)
|
||||
--source-file FILE Source filename stored in ipmitool/ (default: inferred from spec version)
|
||||
--work-dir PATH Temporary work dir (default: $work_dir)
|
||||
--mock-cfg NAME Mock config (default: <ID>+epel-10-<ARCH>)
|
||||
--mock-uniqueext TXT Optional mock --uniqueext suffix to isolate concurrent builds
|
||||
--result-dir PATH Output RPM/SRPM directory (default: $result_dir)
|
||||
--log-dir PATH Log directory (default: $log_dir)
|
||||
--skip-install Skip dnf install + smoke tests
|
||||
USAGE
|
||||
}
|
||||
|
||||
sub parse_spec {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot open spec $path: $!\n";
|
||||
|
||||
my $version = '';
|
||||
my @assets;
|
||||
while (my $line = <$fh>) {
|
||||
if ($line =~ /^Version:\s*(\S+)/) {
|
||||
$version = $1;
|
||||
}
|
||||
if ($line =~ /^(?:Source|Patch)\d*:\s*(\S+)/) {
|
||||
my $asset = $1;
|
||||
push @assets, $asset;
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
|
||||
@assets = map {
|
||||
my $v = $_;
|
||||
$v =~ s/%\{version\}/$version/g;
|
||||
$v =~ s/%\{ver\}/$version/g;
|
||||
$v;
|
||||
} @assets;
|
||||
|
||||
return ($version, @assets);
|
||||
}
|
||||
|
||||
sub normalize_source_archive {
|
||||
my ($archive, $version, $work_base) = @_;
|
||||
|
||||
my $normalize_dir = "$work_base/source-normalize";
|
||||
remove_tree($normalize_dir) if -d $normalize_dir;
|
||||
make_path($normalize_dir);
|
||||
|
||||
run("tar -xzf " . sh_quote($archive) . " -C " . sh_quote($normalize_dir));
|
||||
|
||||
my @entries = grep { $_ !~ m{/\.\.?$} } glob("$normalize_dir/*");
|
||||
die "Unexpected archive layout in $archive\n" if @entries != 1;
|
||||
my $top_path = $entries[0];
|
||||
die "Unexpected non-directory top-level entry in $archive: $top_path\n"
|
||||
if !-d $top_path;
|
||||
|
||||
my $expected_top = "ipmitool-$version";
|
||||
my $actual_top = basename($top_path);
|
||||
if ($actual_top ne $expected_top) {
|
||||
my $new_path = "$normalize_dir/$expected_top";
|
||||
run("rm -rf " . sh_quote($new_path));
|
||||
run("mv " . sh_quote($top_path) . " " . sh_quote($new_path));
|
||||
}
|
||||
|
||||
# Repack using the expected top-level directory required by the spec.
|
||||
run(
|
||||
"tar -C " . sh_quote($normalize_dir) .
|
||||
" -czf " . sh_quote($archive) .
|
||||
" " . sh_quote($expected_top)
|
||||
);
|
||||
}
|
||||
|
||||
sub print_step {
|
||||
my ($msg) = @_;
|
||||
print "\n== $msg ==\n";
|
||||
}
|
||||
|
||||
sub sh_quote {
|
||||
my ($s) = @_;
|
||||
$s =~ s/'/'"'"'/g;
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $rc = system($cmd);
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub capture {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $out = `$cmd`;
|
||||
my $rc = $?;
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\nOutput:\n$out\n";
|
||||
}
|
||||
chomp $out;
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub run_capture_rc {
|
||||
my ($cmd, $log_file) = @_;
|
||||
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
|
||||
print "+ $full\n";
|
||||
my $rc = system($full);
|
||||
return $rc == -1 ? 255 : ($rc >> 8);
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot read $path: $!\n";
|
||||
local $/;
|
||||
my $content = <$fh>;
|
||||
close $fh;
|
||||
return $content;
|
||||
}
|
||||
840
mockbuild-all.pl
Executable file
840
mockbuild-all.pl
Executable file
@@ -0,0 +1,840 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cwd qw(abs_path cwd);
|
||||
use File::Basename qw(dirname basename);
|
||||
use File::Copy qw(copy);
|
||||
use File::Find qw(find);
|
||||
use File::Path qw(make_path);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
use Parallel::ForkManager;
|
||||
use POSIX qw(strftime);
|
||||
|
||||
my $script_dir = abs_path(dirname(__FILE__));
|
||||
my $repo_root = abs_path($script_dir);
|
||||
my $xcat_src = "$repo_root/xcat-source-code";
|
||||
my $output_root = "$repo_root/build-output/mockbuild-all";
|
||||
my $target = '';
|
||||
my $nproc = 1;
|
||||
my $parallel_builds;
|
||||
my $run_id = strftime('%Y%m%d-%H%M%S', localtime);
|
||||
my $skip_install = 0;
|
||||
my $skip_build = 0;
|
||||
my $skip_xcat_dep = 0;
|
||||
my $skip_perl = 0;
|
||||
my $skip_xcat = 0;
|
||||
my $skip_createrepo = 0;
|
||||
my $skip_tarball = 0;
|
||||
my $skip_dhcp = 0;
|
||||
my $scrub_all_chroots = 0;
|
||||
my $dry_run = 0;
|
||||
my $dhcp_repo_url = 'https://github.com/VersatusHPC/rpms-dhcp.git';
|
||||
my $dhcp_repo_ref = 'master';
|
||||
my $dhcp_source_dir = '';
|
||||
my @extra_collect_dirs;
|
||||
|
||||
GetOptions(
|
||||
'repo-root=s' => \$repo_root,
|
||||
'xcat-source=s' => \$xcat_src,
|
||||
'output-root=s' => \$output_root,
|
||||
'target=s' => \$target,
|
||||
'nproc=i' => \$nproc,
|
||||
'parallel-builds=i' => \$parallel_builds,
|
||||
'run-id=s' => \$run_id,
|
||||
'skip-install!' => \$skip_install,
|
||||
'skip-build!' => \$skip_build,
|
||||
'skip-xcat-dep!' => \$skip_xcat_dep,
|
||||
'skip-perl!' => \$skip_perl,
|
||||
'skip-xcat!' => \$skip_xcat,
|
||||
'skip-createrepo!' => \$skip_createrepo,
|
||||
'skip-tarball!' => \$skip_tarball,
|
||||
'skip-dhcp!' => \$skip_dhcp,
|
||||
'scrub-all-chroots!' => \$scrub_all_chroots,
|
||||
'dhcp-repo-url=s' => \$dhcp_repo_url,
|
||||
'dhcp-repo-ref=s' => \$dhcp_repo_ref,
|
||||
'dhcp-source-dir=s' => \$dhcp_source_dir,
|
||||
'collect-dir=s@' => \@extra_collect_dirs,
|
||||
'dry-run!' => \$dry_run,
|
||||
) or die usage();
|
||||
|
||||
die "Run as root (uid=$>)\n" if $> != 0;
|
||||
die "--parallel-builds must be >= 1\n"
|
||||
if defined($parallel_builds) && $parallel_builds < 1;
|
||||
|
||||
$repo_root = abs_path($repo_root);
|
||||
$xcat_src = resolve_xcat_source($xcat_src, $repo_root);
|
||||
|
||||
my $arch = capture('uname -m');
|
||||
my %os = read_os_release('/etc/os-release');
|
||||
my $os_id = $os{ID} // '';
|
||||
my $version_id = $os{VERSION_ID} // '';
|
||||
my ($rel) = $version_id =~ /^(\d+)/;
|
||||
|
||||
die "Could not resolve ID from /etc/os-release\n" if $os_id eq '';
|
||||
die "Could not resolve major release from VERSION_ID='$version_id' in /etc/os-release\n"
|
||||
if !defined($rel) || $rel eq '';
|
||||
|
||||
if (!$target) {
|
||||
$target = "${os_id}+epel-${rel}-${arch}";
|
||||
}
|
||||
my $target_rel = parse_target_rel($target);
|
||||
my $dhcp_auto_enabled = defined($target_rel) && $target_rel eq '10' ? 1 : 0;
|
||||
my $dhcp_enabled = (!$skip_dhcp && $dhcp_auto_enabled) ? 1 : 0;
|
||||
my $dhcp_effective_source = '';
|
||||
my $dhcp_commit = '';
|
||||
my @dhcp_srpm_collect_roots;
|
||||
|
||||
if (!$dhcp_auto_enabled && !$skip_dhcp) {
|
||||
print "INFO: DHCP build step disabled for non-EL10 target '$target'.\n";
|
||||
}
|
||||
|
||||
for my $bin (qw(perl uname createrepo tar find rpm)) {
|
||||
require_command($bin);
|
||||
}
|
||||
require_command('mock') if $scrub_all_chroots;
|
||||
if ($dhcp_enabled && !$skip_build) {
|
||||
require_command('git');
|
||||
require_command('mock');
|
||||
require_command('rpmdev-spectool');
|
||||
}
|
||||
|
||||
my $run_root = "$output_root/$run_id";
|
||||
my $build_root = "$run_root/build-results";
|
||||
my $log_root = "$run_root/build-logs";
|
||||
my $repo_dir = "$run_root/repo/$arch";
|
||||
my $summary_file = "$run_root/summary.txt";
|
||||
my $tarball = "$output_root/mockbuild-all-$target-$run_id.tar.gz";
|
||||
my $srpm_repo_dir = "$run_root/repo-src";
|
||||
my $srpm_tarball = "$output_root/mockbuild-all-$target-$run_id-srpm.tar.gz";
|
||||
|
||||
my @dep_builders = (
|
||||
{ name => 'elilo-xcat', script => "$repo_root/elilo/mockbuild.pl" },
|
||||
{ name => 'grub2-xcat', script => "$repo_root/grub2-xcat/mockbuild.pl" },
|
||||
{ name => 'ipmitool-xcat', script => "$repo_root/ipmitool/mockbuild.pl" },
|
||||
{ name => 'syslinux-xcat', script => "$repo_root/syslinux/mockbuild.pl" },
|
||||
{ name => 'goconserver', script => "$repo_root/goconserver/mockbuild.pl" },
|
||||
);
|
||||
|
||||
my $perl_builder = "$repo_root/mockbuild-perl-packages.pl";
|
||||
|
||||
die "Missing xCAT build script: $xcat_src/buildrpms.pl\n"
|
||||
if !$skip_xcat && !-f "$xcat_src/buildrpms.pl";
|
||||
|
||||
my @active_dep_builders;
|
||||
for my $b (@dep_builders) {
|
||||
if (-f $b->{script}) {
|
||||
push @active_dep_builders, $b;
|
||||
next;
|
||||
}
|
||||
print "WARN: missing dep builder script, skipping: $b->{script}\n";
|
||||
}
|
||||
die "Missing perl builder script: $perl_builder\n"
|
||||
if !$skip_perl && !$perl_builder;
|
||||
|
||||
if (!$dry_run) {
|
||||
make_path($build_root, $log_root, $repo_dir, $srpm_repo_dir);
|
||||
}
|
||||
|
||||
print_step("Configuration");
|
||||
print "repo_root: $repo_root\n";
|
||||
print "xcat_source: $xcat_src\n";
|
||||
print "output_root: $output_root\n";
|
||||
print "run_root: $run_root\n";
|
||||
print "arch: $arch\n";
|
||||
print "os_id: $os_id\n";
|
||||
print "version_id: $version_id\n";
|
||||
print "rel: $rel\n";
|
||||
print "target: $target\n";
|
||||
print "target_rel: " . (defined($target_rel) ? $target_rel : 'unknown') . "\n";
|
||||
print "nproc: $nproc\n";
|
||||
print "parallel_builds: " . (defined($parallel_builds) ? $parallel_builds : 'auto') . "\n";
|
||||
print "skip_build: $skip_build\n";
|
||||
print "skip_xcat_dep: $skip_xcat_dep\n";
|
||||
print "skip_perl: $skip_perl\n";
|
||||
print "skip_xcat: $skip_xcat\n";
|
||||
print "skip_dhcp: $skip_dhcp\n";
|
||||
print "dhcp_enabled: $dhcp_enabled\n";
|
||||
print "dhcp_repo_url: $dhcp_repo_url\n";
|
||||
print "dhcp_repo_ref: $dhcp_repo_ref\n";
|
||||
print "dhcp_source_dir: " . ($dhcp_source_dir ne '' ? $dhcp_source_dir : '(auto)') . "\n";
|
||||
print "skip_install: $skip_install\n";
|
||||
print "skip_createrepo: $skip_createrepo\n";
|
||||
print "skip_tarball: $skip_tarball\n";
|
||||
print "scrub_all_chroots:$scrub_all_chroots\n";
|
||||
print "dry_run: $dry_run\n";
|
||||
print "perl_builder: $perl_builder\n";
|
||||
print "tarball: $tarball\n";
|
||||
print "srpm_repo_dir: $srpm_repo_dir\n";
|
||||
print "srpm_tarball: $srpm_tarball\n";
|
||||
|
||||
my @collect_roots;
|
||||
|
||||
if ($dhcp_enabled && !$skip_build) {
|
||||
($dhcp_effective_source, $dhcp_commit) = prepare_dhcp_source(
|
||||
run_root => $run_root,
|
||||
log_root => "$log_root/dhcpd",
|
||||
repo_url => $dhcp_repo_url,
|
||||
repo_ref => $dhcp_repo_ref,
|
||||
source_dir => $dhcp_source_dir,
|
||||
);
|
||||
} elsif ($dhcp_enabled && $skip_build && $dhcp_source_dir ne '') {
|
||||
$dhcp_effective_source = eval { abs_path($dhcp_source_dir) } || $dhcp_source_dir;
|
||||
$dhcp_commit = '(skip-build)';
|
||||
}
|
||||
|
||||
if ($dhcp_enabled) {
|
||||
print "dhcp_source: " . ($dhcp_effective_source ne '' ? $dhcp_effective_source : '(pending)') . "\n";
|
||||
print "dhcp_commit: " . ($dhcp_commit ne '' ? $dhcp_commit : '(pending)') . "\n";
|
||||
}
|
||||
|
||||
if ($scrub_all_chroots) {
|
||||
run_step(
|
||||
step => "Scrub all chroots for target $target",
|
||||
cmd => "mock -r " . sh_quote($target) . " --scrub=all",
|
||||
log => "$log_root/scrub-all-chroots.log",
|
||||
);
|
||||
}
|
||||
|
||||
if (!$skip_build) {
|
||||
my @build_steps;
|
||||
my $build_step_seq = 0;
|
||||
|
||||
if (!$skip_xcat_dep) {
|
||||
for my $builder (@active_dep_builders) {
|
||||
my $name = $builder->{name};
|
||||
my $script = $builder->{script};
|
||||
my $step_result = "$build_root/$name";
|
||||
my $step_log = "$log_root/$name";
|
||||
my $step_uniqueext = build_mock_uniqueext($run_id, ++$build_step_seq, $name);
|
||||
my $cmd = join(' ',
|
||||
'perl', sh_quote($script),
|
||||
'--mock-cfg', sh_quote($target),
|
||||
'--mock-uniqueext', sh_quote($step_uniqueext),
|
||||
'--result-dir', sh_quote($step_result),
|
||||
'--log-dir', sh_quote($step_log),
|
||||
($skip_install ? '--skip-install' : ()),
|
||||
);
|
||||
push @build_steps, {
|
||||
id => "xcat-dep:$name",
|
||||
step => "Build xcat-dep: $name",
|
||||
cmd => $cmd,
|
||||
log => "$log_root/$name/run.log",
|
||||
};
|
||||
push @collect_roots, $step_result;
|
||||
}
|
||||
}
|
||||
|
||||
if ($dhcp_enabled) {
|
||||
my $dhcp_uniqueext = build_mock_uniqueext($run_id, ++$build_step_seq, 'dhcpd');
|
||||
my $dhcp_build_cmd = join(' && ',
|
||||
'mkdir -p build/SRPMS build/RPMS',
|
||||
'rpmdev-spectool --get-files --sources ./dhcp.spec',
|
||||
'mock -r ' . sh_quote($target) .
|
||||
' --uniqueext ' . sh_quote($dhcp_uniqueext) .
|
||||
' --buildsrpm --spec ./dhcp.spec --sources . --resultdir ./build/SRPMS',
|
||||
'mock -r ' . sh_quote($target) .
|
||||
' --uniqueext ' . sh_quote($dhcp_uniqueext) .
|
||||
' --rebuild ./build/SRPMS/*.src.rpm --resultdir ./build/RPMS',
|
||||
);
|
||||
push @build_steps, {
|
||||
id => 'xcat-dep:dhcpd',
|
||||
step => 'Build xcat-dep: dhcpd',
|
||||
cmd => $dhcp_build_cmd,
|
||||
cwd => $dhcp_effective_source,
|
||||
log => "$log_root/dhcpd/build.log",
|
||||
};
|
||||
push @collect_roots, "$dhcp_effective_source/build/RPMS";
|
||||
push @dhcp_srpm_collect_roots, "$dhcp_effective_source/build/SRPMS";
|
||||
}
|
||||
|
||||
if (!$skip_perl) {
|
||||
my $perl_result = "$build_root/perl/$arch";
|
||||
my $perl_log = "$log_root/perl/$arch";
|
||||
my $perl_uniqueext = build_mock_uniqueext($run_id, ++$build_step_seq, 'perl-list6');
|
||||
my $cmd = join(' ',
|
||||
'perl', sh_quote($perl_builder),
|
||||
'--mock-cfg', sh_quote($target),
|
||||
'--mock-uniqueext', sh_quote($perl_uniqueext),
|
||||
'--result-dir', sh_quote($perl_result),
|
||||
'--log-dir', sh_quote($perl_log),
|
||||
($skip_install ? '--skip-install' : ()),
|
||||
);
|
||||
push @build_steps, {
|
||||
id => 'perl',
|
||||
step => 'Build perl xcat-dep packages',
|
||||
cmd => $cmd,
|
||||
log => "$log_root/perl-build.log",
|
||||
};
|
||||
push @collect_roots, $perl_result;
|
||||
}
|
||||
|
||||
if (!$skip_xcat) {
|
||||
my $cmd = join(' ',
|
||||
'perl', sh_quote("$xcat_src/buildrpms.pl"),
|
||||
'--target', sh_quote($target),
|
||||
'--nproc', int($nproc),
|
||||
'--force',
|
||||
'--verbose',
|
||||
'--xcat_dep_path', sh_quote($repo_root),
|
||||
);
|
||||
push @build_steps, {
|
||||
id => 'xcat',
|
||||
step => 'Build xCAT packages',
|
||||
cmd => $cmd,
|
||||
cwd => $xcat_src,
|
||||
log => "$log_root/xcat-build.log",
|
||||
};
|
||||
}
|
||||
|
||||
if (@build_steps) {
|
||||
my $effective_parallel_builds = defined($parallel_builds)
|
||||
? $parallel_builds
|
||||
: scalar(@build_steps);
|
||||
run_build_steps_parallel(
|
||||
steps => \@build_steps,
|
||||
max_processes => $effective_parallel_builds,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
my $xcat_rpms_dir = "$xcat_src/dist/$target/rpms";
|
||||
my $xcat_srpms_dir = "$xcat_src/dist/$target/srpms";
|
||||
push @collect_roots, $xcat_rpms_dir;
|
||||
|
||||
if ($skip_build) {
|
||||
push @collect_roots,
|
||||
"$repo_root/build-output/list3/elilo-xcat",
|
||||
"$repo_root/build-output/list3/grub2-xcat",
|
||||
"$repo_root/build-output/list3/ipmitool-xcat",
|
||||
"$repo_root/build-output/list3/syslinux-xcat",
|
||||
"$repo_root/build-output/list5/goconserver/$arch",
|
||||
"$repo_root/goconserver-build-$arch/results/rpm",
|
||||
"$repo_root/build-output/list6/perl/$arch",
|
||||
"$repo_root/perl-list6/$arch";
|
||||
}
|
||||
|
||||
if ($dhcp_effective_source ne '') {
|
||||
push @collect_roots, "$dhcp_effective_source/build/RPMS";
|
||||
push @dhcp_srpm_collect_roots, "$dhcp_effective_source/build/SRPMS";
|
||||
}
|
||||
|
||||
push @collect_roots, @extra_collect_dirs;
|
||||
@collect_roots = uniq(@collect_roots);
|
||||
my @srpm_collect_roots = uniq(@collect_roots, $xcat_srpms_dir, @dhcp_srpm_collect_roots);
|
||||
|
||||
print_step('Collect RPM artifacts');
|
||||
print "collection roots:\n";
|
||||
print " $_\n" for @collect_roots;
|
||||
|
||||
my ($copied, $skipped_src, $missing_roots) = collect_rpms(
|
||||
roots => \@collect_roots,
|
||||
dest_dir => $repo_dir,
|
||||
dry_run => $dry_run,
|
||||
);
|
||||
|
||||
if (!$dry_run && $copied == 0) {
|
||||
die "No binary RPMs were collected. Check build logs and collection roots.\n";
|
||||
}
|
||||
|
||||
print_step('Collect source RPM artifacts');
|
||||
print "source collection roots:\n";
|
||||
print " $_\n" for @srpm_collect_roots;
|
||||
|
||||
my ($copied_srpms, $skipped_non_src, $missing_srpm_roots) = collect_srpms(
|
||||
roots => \@srpm_collect_roots,
|
||||
dest_dir => $srpm_repo_dir,
|
||||
dry_run => $dry_run,
|
||||
);
|
||||
|
||||
if (!$dry_run && $copied_srpms == 0) {
|
||||
print "WARN: No source RPMs were collected. SRPM repo and tarball may be empty.\n";
|
||||
}
|
||||
|
||||
if (!$skip_createrepo) {
|
||||
run_step(
|
||||
step => 'Run createrepo',
|
||||
cmd => 'createrepo --update ' . sh_quote($repo_dir),
|
||||
log => "$log_root/createrepo.log",
|
||||
);
|
||||
run_step(
|
||||
step => 'Run createrepo for SRPM repo',
|
||||
cmd => 'createrepo --update ' . sh_quote($srpm_repo_dir),
|
||||
log => "$log_root/createrepo-srpm.log",
|
||||
);
|
||||
}
|
||||
|
||||
if (!$skip_tarball) {
|
||||
my $cmd = join(' ',
|
||||
'tar', '-C', sh_quote($run_root),
|
||||
'-czf', sh_quote($tarball),
|
||||
'repo'
|
||||
);
|
||||
run_step(
|
||||
step => 'Create tarball',
|
||||
cmd => $cmd,
|
||||
log => "$log_root/tarball.log",
|
||||
);
|
||||
my $srpm_cmd = join(' ',
|
||||
'tar', '-C', sh_quote($run_root),
|
||||
'-czf', sh_quote($srpm_tarball),
|
||||
'repo-src'
|
||||
);
|
||||
run_step(
|
||||
step => 'Create SRPM tarball',
|
||||
cmd => $srpm_cmd,
|
||||
log => "$log_root/tarball-srpm.log",
|
||||
);
|
||||
}
|
||||
|
||||
if (!$dry_run) {
|
||||
open my $sfh, '>', $summary_file or die "Cannot write $summary_file: $!\n";
|
||||
print {$sfh} "run_root=$run_root\n";
|
||||
print {$sfh} "repo_dir=$repo_dir\n";
|
||||
print {$sfh} "target=$target\n";
|
||||
print {$sfh} "target_rel=" . (defined($target_rel) ? $target_rel : '') . "\n";
|
||||
print {$sfh} "arch=$arch\n";
|
||||
print {$sfh} "os_id=$os_id\n";
|
||||
print {$sfh} "version_id=$version_id\n";
|
||||
print {$sfh} "rel=$rel\n";
|
||||
print {$sfh} "dhcp_enabled=$dhcp_enabled\n";
|
||||
print {$sfh} "dhcp_repo_url=$dhcp_repo_url\n";
|
||||
print {$sfh} "dhcp_repo_ref=$dhcp_repo_ref\n";
|
||||
print {$sfh} "dhcp_source=" . ($dhcp_effective_source ne '' ? $dhcp_effective_source : '') . "\n";
|
||||
print {$sfh} "dhcp_commit=" . ($dhcp_commit ne '' ? $dhcp_commit : '') . "\n";
|
||||
print {$sfh} "copied_rpms=$copied\n";
|
||||
print {$sfh} "skipped_src_rpms=$skipped_src\n";
|
||||
print {$sfh} "missing_collection_roots=$missing_roots\n";
|
||||
print {$sfh} "srpm_repo_dir=$srpm_repo_dir\n";
|
||||
print {$sfh} "copied_srpms=$copied_srpms\n";
|
||||
print {$sfh} "skipped_non_src_rpms=$skipped_non_src\n";
|
||||
print {$sfh} "missing_srpm_collection_roots=$missing_srpm_roots\n";
|
||||
print {$sfh} "tarball=$tarball\n" if !$skip_tarball;
|
||||
print {$sfh} "srpm_tarball=$srpm_tarball\n" if !$skip_tarball;
|
||||
close $sfh;
|
||||
}
|
||||
|
||||
print_step('Completed');
|
||||
print "Collected binary RPMs: $copied\n";
|
||||
print "Skipped source RPMs: $skipped_src\n";
|
||||
print "Missing roots: $missing_roots\n";
|
||||
print "Repo dir: $repo_dir\n";
|
||||
print "Collected source RPMs: $copied_srpms\n";
|
||||
print "Skipped non-src RPMs: $skipped_non_src\n";
|
||||
print "Missing source roots: $missing_srpm_roots\n";
|
||||
print "SRPM repo dir: $srpm_repo_dir\n";
|
||||
print "DHCP source: $dhcp_effective_source\n" if $dhcp_effective_source ne '';
|
||||
print "DHCP ref: $dhcp_repo_ref\n" if $dhcp_enabled;
|
||||
print "DHCP commit: $dhcp_commit\n" if $dhcp_commit ne '';
|
||||
print "Summary: $summary_file\n" if !$dry_run;
|
||||
print "Tarball: $tarball\n" if !$skip_tarball;
|
||||
print "SRPM Tarball: $srpm_tarball\n" if !$skip_tarball;
|
||||
exit 0;
|
||||
|
||||
sub usage {
|
||||
return <<"USAGE";
|
||||
Usage: $0 [options]
|
||||
|
||||
Build xcat-dep and xCAT RPMs, consolidate binary/source artifacts, run createrepo, and create tarballs.
|
||||
|
||||
Options:
|
||||
--repo-root PATH xcat-dep repository root (default: script directory)
|
||||
--xcat-source PATH xCAT source root with buildrpms.pl (default: <repo-root>/xcat-source-code)
|
||||
--output-root PATH Root output directory (default: <repo-root>/build-output/mockbuild-all)
|
||||
--target NAME Optional unified target in <ID>+epel-<REL>-<ARCH> format
|
||||
--nproc N Parallel jobs for buildrpms.pl (default: 1)
|
||||
--parallel-builds N Max concurrent top-level build steps (default: auto=queued steps)
|
||||
--run-id ID Run identifier suffix (default: timestamp)
|
||||
--skip-install Skip install/smoke tests in child builder scripts
|
||||
--skip-build Skip all build steps and only collect/create repo/tarballs
|
||||
--skip-xcat-dep Skip xcat-dep mockbuild.pl package steps
|
||||
--skip-perl Skip perl package build step
|
||||
--skip-xcat Skip xCAT buildrpms.pl step
|
||||
--skip-dhcp Skip rpms-dhcp build step
|
||||
--skip-createrepo Skip createrepo
|
||||
--skip-tarball Skip binary/SRPM tarball creation
|
||||
--scrub-all-chroots Run mock -r <target> --scrub=all before build/collect
|
||||
--dhcp-repo-url URL rpms-dhcp git URL (default: https://github.com/VersatusHPC/rpms-dhcp.git)
|
||||
--dhcp-repo-ref REF rpms-dhcp git ref/tag/branch to checkout (default: master)
|
||||
--dhcp-source-dir PATH Local rpms-dhcp source directory override (skip clone/fetch)
|
||||
--collect-dir PATH Additional directory to scan recursively for RPMs (repeatable)
|
||||
--dry-run Print planned commands without executing
|
||||
|
||||
Notes:
|
||||
- Run this script as root on the build host.
|
||||
- ARCH is derived from: uname -m
|
||||
- Top-level parallel queue includes xcat-dep mockbuild.pl steps, perl builder,
|
||||
and xcat-source-code/buildrpms.pl.
|
||||
- Child mockbuild scripts are invoked with per-step mock --uniqueext values
|
||||
to avoid lock collisions on the same mock config.
|
||||
- If --target is omitted, it is deduced from /etc/os-release:
|
||||
ID + epel + int(VERSION_ID) + ARCH
|
||||
- DHCP step auto-enables only for EL10 targets, unless explicitly skipped.
|
||||
USAGE
|
||||
}
|
||||
|
||||
sub parse_target_rel {
|
||||
my ($target_name) = @_;
|
||||
return undef if !defined($target_name) || $target_name eq '';
|
||||
return $1 if $target_name =~ /\+epel-(\d+)-/;
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub prepare_dhcp_source {
|
||||
my (%args) = @_;
|
||||
my $run_root = $args{run_root} // die "prepare_dhcp_source missing run_root\n";
|
||||
my $log_root = $args{log_root} // die "prepare_dhcp_source missing log_root\n";
|
||||
my $repo_url = $args{repo_url} // die "prepare_dhcp_source missing repo_url\n";
|
||||
my $repo_ref = $args{repo_ref} // 'master';
|
||||
my $source_dir = $args{source_dir} // '';
|
||||
|
||||
my $clone_log = "$log_root/clone.log";
|
||||
my $source_path;
|
||||
|
||||
if ($source_dir ne '') {
|
||||
$source_path = eval { abs_path($source_dir) } || $source_dir;
|
||||
die "DHCP source directory does not exist: $source_path\n"
|
||||
if !$dry_run && !-d $source_path;
|
||||
run_step(
|
||||
step => 'Prepare DHCP source',
|
||||
cmd => 'echo Using local DHCP source directory: ' . sh_quote($source_path),
|
||||
log => $clone_log,
|
||||
);
|
||||
} else {
|
||||
$source_path = "$run_root/sources/rpms-dhcp";
|
||||
my $prepare_cmd = join(' && ',
|
||||
'mkdir -p ' . sh_quote("$run_root/sources"),
|
||||
'if [ -d ' . sh_quote("$source_path/.git") . ' ]; then ' .
|
||||
'cd ' . sh_quote($source_path) . ' && ' .
|
||||
'git remote set-url origin ' . sh_quote($repo_url) . ' && ' .
|
||||
'git fetch --tags origin' .
|
||||
'; else ' .
|
||||
'git clone ' . sh_quote($repo_url) . ' ' . sh_quote($source_path) .
|
||||
'; fi',
|
||||
'cd ' . sh_quote($source_path),
|
||||
'git fetch --tags origin',
|
||||
'git checkout --force ' . sh_quote($repo_ref),
|
||||
);
|
||||
run_step(
|
||||
step => 'Prepare DHCP source',
|
||||
cmd => $prepare_cmd,
|
||||
log => $clone_log,
|
||||
);
|
||||
}
|
||||
|
||||
if (!$dry_run && !-f "$source_path/dhcp.spec") {
|
||||
die "Missing dhcp.spec in DHCP source: $source_path/dhcp.spec\n";
|
||||
}
|
||||
|
||||
my $commit = '';
|
||||
if ($dry_run) {
|
||||
$commit = '(dry-run)';
|
||||
} elsif (-d "$source_path/.git") {
|
||||
$commit = capture("cd " . sh_quote($source_path) . " && git rev-parse HEAD");
|
||||
} else {
|
||||
$commit = '(local-source-no-git)';
|
||||
}
|
||||
|
||||
return ($source_path, $commit);
|
||||
}
|
||||
|
||||
sub print_step {
|
||||
my ($msg) = @_;
|
||||
print "\n== $msg ==\n";
|
||||
}
|
||||
|
||||
sub require_command {
|
||||
my ($cmd) = @_;
|
||||
run_simple("command -v " . sh_quote($cmd) . " >/dev/null 2>&1");
|
||||
}
|
||||
|
||||
sub run_simple {
|
||||
my ($cmd) = @_;
|
||||
my $rc = system($cmd);
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub capture {
|
||||
my ($cmd) = @_;
|
||||
my $out = `$cmd`;
|
||||
my $rc = $?;
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\n$out\n";
|
||||
}
|
||||
chomp $out;
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub run_step {
|
||||
my (%args) = @_;
|
||||
my $step = $args{step} // 'Run command';
|
||||
my $cmd = $args{cmd} // die "run_step missing cmd\n";
|
||||
my $cwd = $args{cwd};
|
||||
my $log = $args{log};
|
||||
|
||||
print_step($step);
|
||||
print "+ $cmd\n";
|
||||
if ($cwd) {
|
||||
print " (cwd: $cwd)\n";
|
||||
}
|
||||
if ($log) {
|
||||
print " (log: $log)\n";
|
||||
}
|
||||
|
||||
return if $dry_run;
|
||||
|
||||
my $full_cmd = $cmd;
|
||||
if ($cwd) {
|
||||
$full_cmd = "cd " . sh_quote($cwd) . " && $cmd";
|
||||
}
|
||||
if ($log) {
|
||||
my $log_dir = dirname($log);
|
||||
make_path($log_dir) if !-d $log_dir;
|
||||
$full_cmd .= " > " . sh_quote($log) . " 2>&1";
|
||||
}
|
||||
|
||||
my $rc = system($full_cmd);
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Step failed (rc=$exit): $step\nCommand: $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub run_build_steps_parallel {
|
||||
my (%args) = @_;
|
||||
my $steps = $args{steps} // [];
|
||||
my $max_processes = $args{max_processes} // 1;
|
||||
return if !@{$steps};
|
||||
|
||||
if ($dry_run || $max_processes <= 1 || @{$steps} == 1) {
|
||||
for my $step (@{$steps}) {
|
||||
run_step(%{$step});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
my $workers = $max_processes;
|
||||
$workers = scalar(@{$steps}) if $workers > scalar(@{$steps});
|
||||
|
||||
print_step('Run build steps in parallel');
|
||||
print "max_processes: $workers\n";
|
||||
print "queued steps:\n";
|
||||
print " - $_->{step}\n" for @{$steps};
|
||||
|
||||
my %failed;
|
||||
my $pm = Parallel::ForkManager->new($workers);
|
||||
$pm->run_on_finish(
|
||||
sub {
|
||||
my ($pid, $exit_code, $ident, $signal, $core_dump) = @_;
|
||||
return if $exit_code == 0 && $signal == 0 && !$core_dump;
|
||||
my $key = defined($ident) ? $ident : "pid:$pid";
|
||||
$failed{$key} = {
|
||||
exit => $exit_code,
|
||||
signal => $signal,
|
||||
core_dump => $core_dump ? 1 : 0,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
for my $step (@{$steps}) {
|
||||
my %step_copy = %{$step};
|
||||
my $ident = delete $step_copy{id};
|
||||
$ident = $step_copy{step} if !defined($ident) || $ident eq '';
|
||||
|
||||
my $pid = $pm->start($ident);
|
||||
next if $pid;
|
||||
|
||||
my $ok = eval {
|
||||
run_step(%step_copy);
|
||||
1;
|
||||
};
|
||||
if (!$ok) {
|
||||
my $err = $@;
|
||||
$err = "unknown error\n" if !defined($err) || $err eq '';
|
||||
print STDERR "ERROR [$ident] $err";
|
||||
$pm->finish(1);
|
||||
}
|
||||
$pm->finish(0);
|
||||
}
|
||||
$pm->wait_all_children;
|
||||
|
||||
if (%failed) {
|
||||
my @lines;
|
||||
for my $id (sort keys %failed) {
|
||||
my $f = $failed{$id};
|
||||
push @lines,
|
||||
"$id (exit=$f->{exit}, signal=$f->{signal}, core_dump=$f->{core_dump})";
|
||||
}
|
||||
die "Parallel build steps failed:\n " . join("\n ", @lines) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub collect_rpms {
|
||||
my (%args) = @_;
|
||||
my $roots = $args{roots} // [];
|
||||
my $dest = $args{dest_dir} // die "collect_rpms missing dest_dir\n";
|
||||
my $is_dry = $args{dry_run} ? 1 : 0;
|
||||
|
||||
my %seen;
|
||||
my $copied = 0;
|
||||
my $skipped_src = 0;
|
||||
my $missing_roots = 0;
|
||||
|
||||
for my $root (@{$roots}) {
|
||||
if (!$root || !-d $root) {
|
||||
$missing_roots++;
|
||||
print "WARN: missing collection root: $root\n";
|
||||
next;
|
||||
}
|
||||
my @rpms;
|
||||
find(
|
||||
sub {
|
||||
return if !-f $_;
|
||||
return if $_ !~ /\.rpm$/;
|
||||
push @rpms, $File::Find::name;
|
||||
},
|
||||
$root,
|
||||
);
|
||||
@rpms = sort uniq(@rpms);
|
||||
for my $rpm (@rpms) {
|
||||
next if !-f $rpm;
|
||||
if ($rpm =~ /\.src\.rpm$/) {
|
||||
$skipped_src++;
|
||||
next;
|
||||
}
|
||||
my $base = basename($rpm);
|
||||
next if $seen{$base}++;
|
||||
if ($is_dry) {
|
||||
print "DRY-RUN copy: $rpm -> $dest/$base\n";
|
||||
$copied++;
|
||||
next;
|
||||
}
|
||||
copy($rpm, "$dest/$base")
|
||||
or die "Failed to copy $rpm to $dest/$base: $!\n";
|
||||
$copied++;
|
||||
}
|
||||
}
|
||||
|
||||
return ($copied, $skipped_src, $missing_roots);
|
||||
}
|
||||
|
||||
sub collect_srpms {
|
||||
my (%args) = @_;
|
||||
my $roots = $args{roots} // [];
|
||||
my $dest = $args{dest_dir} // die "collect_srpms missing dest_dir\n";
|
||||
my $is_dry = $args{dry_run} ? 1 : 0;
|
||||
|
||||
my %seen;
|
||||
my $copied = 0;
|
||||
my $skipped_non_src = 0;
|
||||
my $missing_roots = 0;
|
||||
|
||||
for my $root (@{$roots}) {
|
||||
if (!$root || !-d $root) {
|
||||
$missing_roots++;
|
||||
print "WARN: missing source collection root: $root\n";
|
||||
next;
|
||||
}
|
||||
my @rpms;
|
||||
find(
|
||||
sub {
|
||||
return if !-f $_;
|
||||
return if $_ !~ /\.rpm$/;
|
||||
push @rpms, $File::Find::name;
|
||||
},
|
||||
$root,
|
||||
);
|
||||
@rpms = sort uniq(@rpms);
|
||||
for my $rpm (@rpms) {
|
||||
next if !-f $rpm;
|
||||
if ($rpm !~ /\.src\.rpm$/) {
|
||||
$skipped_non_src++;
|
||||
next;
|
||||
}
|
||||
my $base = basename($rpm);
|
||||
next if $seen{$base}++;
|
||||
if ($is_dry) {
|
||||
print "DRY-RUN copy source: $rpm -> $dest/$base\n";
|
||||
$copied++;
|
||||
next;
|
||||
}
|
||||
copy($rpm, "$dest/$base")
|
||||
or die "Failed to copy $rpm to $dest/$base: $!\n";
|
||||
$copied++;
|
||||
}
|
||||
}
|
||||
|
||||
return ($copied, $skipped_non_src, $missing_roots);
|
||||
}
|
||||
|
||||
sub build_mock_uniqueext {
|
||||
my ($run, $seq, $label) = @_;
|
||||
|
||||
my $run_part = defined($run) ? $run : 'run';
|
||||
$run_part =~ s/[^A-Za-z0-9_.-]+/-/g;
|
||||
$run_part =~ s/^-+|-+$//g;
|
||||
$run_part = 'run' if $run_part eq '';
|
||||
$run_part = substr($run_part, -24) if length($run_part) > 24;
|
||||
|
||||
my $label_part = defined($label) ? $label : 'step';
|
||||
$label_part =~ s/[^A-Za-z0-9_.-]+/-/g;
|
||||
$label_part =~ s/^-+|-+$//g;
|
||||
$label_part = 'step' if $label_part eq '';
|
||||
$label_part = substr($label_part, 0, 20) if length($label_part) > 20;
|
||||
|
||||
my $idx = defined($seq) ? int($seq) : 0;
|
||||
$idx = 0 if $idx < 0;
|
||||
|
||||
return sprintf("mba-%02d-%s-%s", $idx, $run_part, $label_part);
|
||||
}
|
||||
|
||||
sub resolve_xcat_source {
|
||||
my ($requested, $root) = @_;
|
||||
my @candidates = (
|
||||
$requested,
|
||||
"$root/xcat-source-code",
|
||||
"$root/../xCAT3",
|
||||
'/home/build/xCAT3',
|
||||
);
|
||||
for my $c (@candidates) {
|
||||
next if !defined($c) || $c eq '';
|
||||
my $abs = eval { abs_path($c) };
|
||||
next if !$abs;
|
||||
return $abs if -f "$abs/buildrpms.pl";
|
||||
}
|
||||
return eval { abs_path($requested) } || $requested;
|
||||
}
|
||||
|
||||
sub read_os_release {
|
||||
my ($path) = @_;
|
||||
my %vals;
|
||||
open my $fh, '<', $path or die "Cannot open $path: $!\n";
|
||||
while (my $line = <$fh>) {
|
||||
chomp $line;
|
||||
next if $line =~ /^\s*#/;
|
||||
next if $line !~ /=/;
|
||||
my ($k, $v) = split /=/, $line, 2;
|
||||
$v =~ s/^"(.*)"$/$1/;
|
||||
$v =~ s/^'(.*)'$/$1/;
|
||||
$vals{$k} = $v;
|
||||
}
|
||||
close $fh;
|
||||
return %vals;
|
||||
}
|
||||
|
||||
sub uniq {
|
||||
my %seen;
|
||||
return grep { defined($_) && !$seen{$_}++ } @_;
|
||||
}
|
||||
|
||||
sub sh_quote {
|
||||
my ($s) = @_;
|
||||
$s = '' if !defined $s;
|
||||
$s =~ s/'/'"'"'/g;
|
||||
return "'$s'";
|
||||
}
|
||||
557
mockbuild-perl-packages.pl
Executable file
557
mockbuild-perl-packages.pl
Executable file
@@ -0,0 +1,557 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname basename);
|
||||
use File::Copy qw(copy);
|
||||
use File::Path qw(make_path remove_tree);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
use Parallel::ForkManager;
|
||||
|
||||
my $repo_root = abs_path(dirname(__FILE__));
|
||||
my $work_dir = '/tmp/perl-list6-mockbuild';
|
||||
my $mock_cfg = '';
|
||||
my $mock_uniqueext = '';
|
||||
my $result_dir = '';
|
||||
my $log_dir = '';
|
||||
my $packages_csv = '';
|
||||
my $jobs = 0;
|
||||
my $skip_install = 0;
|
||||
my $allow_erasing = 0;
|
||||
|
||||
GetOptions(
|
||||
'work-dir=s' => \$work_dir,
|
||||
'mock-cfg=s' => \$mock_cfg,
|
||||
'mock-uniqueext=s' => \$mock_uniqueext,
|
||||
'result-dir=s' => \$result_dir,
|
||||
'log-dir=s' => \$log_dir,
|
||||
'packages=s' => \$packages_csv,
|
||||
'jobs=i' => \$jobs,
|
||||
'skip-install!' => \$skip_install,
|
||||
'allow-erasing!' => \$allow_erasing,
|
||||
) or die usage();
|
||||
|
||||
die "Run as root (current uid=$>)\n" if $> != 0;
|
||||
|
||||
for my $bin (qw(mock rpmbuild rpm dnf perl bash grep)) {
|
||||
run("command -v " . sh_quote($bin) . " >/dev/null 2>&1");
|
||||
}
|
||||
|
||||
my $arch = capture('uname -m');
|
||||
if (!$mock_cfg) {
|
||||
my $os_id = capture(q{bash -lc 'source /etc/os-release; echo $ID'});
|
||||
$mock_cfg = "${os_id}+epel-10-${arch}";
|
||||
}
|
||||
my $mock_uniqueext_opt = $mock_uniqueext ne ''
|
||||
? ' --uniqueext ' . sh_quote($mock_uniqueext)
|
||||
: '';
|
||||
if (!$result_dir) {
|
||||
$result_dir = "$repo_root/build-output/list6/perl/$arch";
|
||||
}
|
||||
if (!$log_dir) {
|
||||
$log_dir = "$repo_root/build-logs/list6/perl/$arch";
|
||||
}
|
||||
|
||||
my %meta = (
|
||||
'perl-Crypt-SSLeay' => {
|
||||
mode => 'spec',
|
||||
pkg_dir => "$repo_root/perl-Crypt-SSLeay",
|
||||
spec => "$repo_root/perl-Crypt-SSLeay/perl-Crypt-SSLeay.spec",
|
||||
rpm_name => 'perl-Crypt-SSLeay',
|
||||
rpm_arch => 'native',
|
||||
module => 'Crypt::SSLeay',
|
||||
},
|
||||
'perl-HTML-Form' => {
|
||||
mode => 'srpm',
|
||||
pkg_dir => "$repo_root/perl-HTML-Form",
|
||||
srpm_globs => [
|
||||
"$repo_root/perl-HTML-Form/perl-HTML-Form-6.07-4.fc34.src.rpm",
|
||||
"$repo_root/perl-HTML-Form/perl-HTML-Form-*.src.rpm",
|
||||
],
|
||||
rpm_name => 'perl-HTML-Form',
|
||||
rpm_arch => 'noarch',
|
||||
module => 'HTML::Form',
|
||||
},
|
||||
'perl-HTTP-Async' => {
|
||||
mode => 'spec',
|
||||
pkg_dir => "$repo_root/perl-HTTP-Async",
|
||||
spec => "$repo_root/perl-HTTP-Async/perl-HTTP-Async.spec",
|
||||
rpm_name => 'perl-HTTP-Async',
|
||||
rpm_arch => 'noarch',
|
||||
module => 'HTTP::Async',
|
||||
},
|
||||
'perl-IO-Stty' => {
|
||||
mode => 'srpm',
|
||||
pkg_dir => "$repo_root/perl-IO-Stty",
|
||||
srpm_globs => [
|
||||
"$repo_root/perl-IO-Stty/perl-IO-Stty-0.04-5.fc34.src.rpm",
|
||||
"$repo_root/perl-IO-Stty/perl-IO-Stty-*.src.rpm",
|
||||
],
|
||||
rpm_name => 'perl-IO-Stty',
|
||||
rpm_arch => 'noarch',
|
||||
module => 'IO::Stty',
|
||||
},
|
||||
'perl-Net-HTTPS-NB' => {
|
||||
mode => 'spec',
|
||||
pkg_dir => "$repo_root/perl-Net-HTTPS-NB",
|
||||
spec => "$repo_root/perl-Net-HTTPS-NB/perl-Net-HTTPS-NB.spec",
|
||||
rpm_name => 'perl-Net-HTTPS-NB',
|
||||
rpm_arch => 'noarch',
|
||||
module => 'Net::HTTPS::NB',
|
||||
},
|
||||
'perl-Net-Telnet' => {
|
||||
mode => 'srpm',
|
||||
pkg_dir => "$repo_root/perl-Net-Telnet",
|
||||
srpm_globs => [
|
||||
"$repo_root/perl-Net-Telnet/perl-Net-Telnet-3.04-16.fc34.src.rpm",
|
||||
"$repo_root/perl-Net-Telnet/perl-Net-Telnet-*.src.rpm",
|
||||
],
|
||||
rpm_name => 'perl-Net-Telnet',
|
||||
rpm_arch => 'noarch',
|
||||
module => 'Net::Telnet',
|
||||
},
|
||||
'perl-Sys-Virt' => {
|
||||
mode => 'spec',
|
||||
pkg_dir => "$repo_root/perl-Sys-Virt",
|
||||
spec => "$repo_root/perl-Sys-Virt/Sys-Virt.spec",
|
||||
rpm_name => 'perl-Sys-Virt',
|
||||
rpm_arch => 'native',
|
||||
module => 'Sys::Virt',
|
||||
},
|
||||
);
|
||||
|
||||
my @default_order = qw(
|
||||
perl-Crypt-SSLeay
|
||||
perl-HTML-Form
|
||||
perl-HTTP-Async
|
||||
perl-IO-Stty
|
||||
perl-Net-HTTPS-NB
|
||||
perl-Net-Telnet
|
||||
perl-Sys-Virt
|
||||
);
|
||||
|
||||
my @packages = @default_order;
|
||||
if ($packages_csv ne '') {
|
||||
@packages = grep { $_ ne '' } map { s/^\s+|\s+$//gr } split /,/, $packages_csv;
|
||||
}
|
||||
|
||||
for my $pkg (@packages) {
|
||||
die "Unknown package in --packages: $pkg\n" if !exists $meta{$pkg};
|
||||
}
|
||||
|
||||
if ($jobs <= 0) {
|
||||
$jobs = scalar(@packages);
|
||||
}
|
||||
$jobs = 1 if $jobs < 1;
|
||||
if (@packages && $jobs > scalar(@packages)) {
|
||||
$jobs = scalar(@packages);
|
||||
}
|
||||
if (!$skip_install && $jobs > 1) {
|
||||
print "INFO: --skip-install is disabled; forcing --jobs 1 to avoid host dnf lock contention\n";
|
||||
$jobs = 1;
|
||||
}
|
||||
|
||||
make_path($result_dir);
|
||||
make_path($log_dir);
|
||||
make_path($work_dir);
|
||||
|
||||
print_step("Configuration");
|
||||
print "repo_root: $repo_root\n";
|
||||
print "work_dir: $work_dir\n";
|
||||
print "result_dir: $result_dir\n";
|
||||
print "log_dir: $log_dir\n";
|
||||
print "arch: $arch\n";
|
||||
print "mock_cfg: $mock_cfg\n";
|
||||
print "mock_uniqueext: " . ($mock_uniqueext ne '' ? $mock_uniqueext : '(none)') . "\n";
|
||||
print "packages: " . join(', ', @packages) . "\n";
|
||||
print "jobs: $jobs\n";
|
||||
print "skip_install:$skip_install\n";
|
||||
print "allow_erasing:$allow_erasing\n";
|
||||
|
||||
print_step("Mock config check");
|
||||
run("mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt . " --print-root-path >/dev/null");
|
||||
|
||||
my @failed;
|
||||
my @passed;
|
||||
my @summary_lines;
|
||||
|
||||
print_step("Build packages");
|
||||
print "parallel jobs: $jobs\n";
|
||||
my $pm = Parallel::ForkManager->new($jobs);
|
||||
$pm->run_on_finish(
|
||||
sub {
|
||||
my ($pid, $exit_code, $ident) = @_;
|
||||
my $label = defined $ident ? $ident : "pid=$pid";
|
||||
my $state = $exit_code == 0 ? 'PASS' : "FAIL(rc=$exit_code)";
|
||||
print "[$label] $state\n";
|
||||
}
|
||||
);
|
||||
|
||||
for my $idx (0 .. $#packages) {
|
||||
my $pkg = $packages[$idx];
|
||||
my $cfg = $meta{$pkg};
|
||||
my $pkg_uniqueext = package_uniqueext($mock_uniqueext, $idx + 1, $pkg);
|
||||
|
||||
my $pid = $pm->start($pkg);
|
||||
next if $pid;
|
||||
my $ok = build_package(
|
||||
pkg => $pkg,
|
||||
cfg => $cfg,
|
||||
work_dir => $work_dir,
|
||||
result_dir => $result_dir,
|
||||
log_dir => $log_dir,
|
||||
mock_cfg => $mock_cfg,
|
||||
mock_uniqueext => $pkg_uniqueext,
|
||||
arch => $arch,
|
||||
skip_install => $skip_install,
|
||||
allow_erasing => $allow_erasing,
|
||||
);
|
||||
$pm->finish($ok ? 0 : 1);
|
||||
}
|
||||
$pm->wait_all_children;
|
||||
|
||||
for my $pkg (@packages) {
|
||||
my $status_file = "$log_dir/$pkg/status.txt";
|
||||
if (!-f $status_file) {
|
||||
push @failed, $pkg;
|
||||
push @summary_lines, "$pkg FAIL missing status file ($status_file)";
|
||||
next;
|
||||
}
|
||||
my $line = slurp($status_file);
|
||||
$line =~ s/\r?\n.*$//s;
|
||||
my ($status, $summary) = split /\t/, $line, 2;
|
||||
if (!defined $status || !defined $summary || ($status ne 'PASS' && $status ne 'FAIL')) {
|
||||
$status = 'FAIL';
|
||||
$summary = "$pkg FAIL malformed status line in $status_file";
|
||||
}
|
||||
if ($status eq 'PASS') {
|
||||
push @passed, $pkg;
|
||||
} else {
|
||||
push @failed, $pkg;
|
||||
}
|
||||
push @summary_lines, $summary;
|
||||
}
|
||||
|
||||
open my $sfh, '>', "$log_dir/build-summary.txt"
|
||||
or die "Cannot write $log_dir/build-summary.txt: $!\n";
|
||||
print {$sfh} "mock_cfg=$mock_cfg\n";
|
||||
print {$sfh} "mock_uniqueext=$mock_uniqueext\n" if $mock_uniqueext ne '';
|
||||
print {$sfh} "arch=$arch\n";
|
||||
print {$sfh} "result_dir=$result_dir\n";
|
||||
print {$sfh} "log_dir=$log_dir\n";
|
||||
print {$sfh} "packages=" . join(',', @packages) . "\n";
|
||||
print {$sfh} "passed=" . join(',', @passed) . "\n";
|
||||
print {$sfh} "failed=" . join(',', @failed) . "\n";
|
||||
print {$sfh} "$_\n" for @summary_lines;
|
||||
close $sfh;
|
||||
|
||||
print_step("Completed");
|
||||
print "Passed: " . join(', ', @passed) . "\n" if @passed;
|
||||
print "Failed: " . join(', ', @failed) . "\n" if @failed;
|
||||
print "Artifacts: $result_dir\n";
|
||||
print "Logs: $log_dir\n";
|
||||
|
||||
exit(@failed ? 1 : 0);
|
||||
|
||||
sub build_package {
|
||||
my (%args) = @_;
|
||||
my $pkg = $args{pkg};
|
||||
my $cfg = $args{cfg};
|
||||
my $work_dir = $args{work_dir};
|
||||
my $result_dir = $args{result_dir};
|
||||
my $log_dir = $args{log_dir};
|
||||
my $mock_cfg = $args{mock_cfg};
|
||||
my $mock_uniqueext = $args{mock_uniqueext};
|
||||
my $arch = $args{arch};
|
||||
my $skip_install = $args{skip_install};
|
||||
my $allow_erasing = $args{allow_erasing};
|
||||
|
||||
my $pkg_run_dir = "$work_dir/$pkg";
|
||||
my $pkg_result = "$result_dir/$pkg";
|
||||
my $pkg_log = "$log_dir/$pkg";
|
||||
my $status_file = "$pkg_log/status.txt";
|
||||
|
||||
remove_tree($pkg_run_dir) if -d $pkg_run_dir;
|
||||
make_path($pkg_run_dir);
|
||||
make_path($pkg_result);
|
||||
make_path($pkg_log);
|
||||
|
||||
my $run_log = "$pkg_log/run.log";
|
||||
open my $runfh, '>', $run_log or die "Cannot write $run_log: $!\n";
|
||||
open STDOUT, '>&', $runfh or die "Cannot redirect stdout to $run_log: $!\n";
|
||||
open STDERR, '>&', $runfh or die "Cannot redirect stderr to $run_log: $!\n";
|
||||
select(STDOUT);
|
||||
$| = 1;
|
||||
|
||||
my $mock_uniqueext_opt = ' --uniqueext ' . sh_quote($mock_uniqueext);
|
||||
print_step("Build $pkg");
|
||||
print "mock_uniqueext: $mock_uniqueext\n";
|
||||
|
||||
my $summary = '';
|
||||
my $ok = 0;
|
||||
|
||||
my $srpm_path = '';
|
||||
my $rebuild_result = "$pkg_run_dir/rpm";
|
||||
make_path($rebuild_result);
|
||||
|
||||
eval {
|
||||
if ($cfg->{mode} eq 'srpm') {
|
||||
$srpm_path = select_srpm($cfg->{srpm_globs});
|
||||
die "Could not locate source RPM for $pkg\n" if !$srpm_path;
|
||||
} else {
|
||||
my $spec = $cfg->{spec};
|
||||
die "Missing spec for $pkg: $spec\n" if !-f $spec;
|
||||
my $source_dir = $cfg->{pkg_dir};
|
||||
die "Missing source directory for $pkg: $source_dir\n" if !-d $source_dir;
|
||||
|
||||
my ($version, @assets) = parse_spec($spec);
|
||||
die "Could not parse Version from $spec\n" if !$version;
|
||||
for my $asset (@assets) {
|
||||
my $asset_path = "$source_dir/$asset";
|
||||
die "Missing Source/Patch asset for $pkg: $asset_path\n" if !-f $asset_path;
|
||||
}
|
||||
|
||||
my $prep_top = "$pkg_run_dir/prep";
|
||||
for my $d (qw(BUILD BUILDROOT RPMS SOURCES SPECS SRPMS)) {
|
||||
make_path("$prep_top/$d");
|
||||
}
|
||||
my $prep_spec = "$prep_top/SPECS/" . basename($spec);
|
||||
copy($spec, $prep_spec) or die "Failed to copy prep spec for $pkg: $!\n";
|
||||
for my $asset (@assets) {
|
||||
copy("$source_dir/$asset", "$prep_top/SOURCES/$asset")
|
||||
or die "Failed to stage prep asset $asset for $pkg: $!\n";
|
||||
}
|
||||
run(
|
||||
"rpmbuild --define " . sh_quote("_topdir $prep_top") .
|
||||
" -bp --nodeps " . sh_quote($prep_spec) .
|
||||
" > " . sh_quote("$pkg_log/prep.log") . " 2>&1"
|
||||
);
|
||||
|
||||
my $srpm_result = "$pkg_run_dir/srpm";
|
||||
make_path($srpm_result);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --buildsrpm --spec " . sh_quote($spec) .
|
||||
" --sources " . sh_quote($source_dir) .
|
||||
" --resultdir " . sh_quote($srpm_result) .
|
||||
" > " . sh_quote("$pkg_log/mock-buildsrpm.log") . " 2>&1"
|
||||
);
|
||||
my @srpms = sort glob("$srpm_result/*.src.rpm");
|
||||
die "No SRPM produced for $pkg in $srpm_result\n" if !@srpms;
|
||||
$srpm_path = $srpms[-1];
|
||||
}
|
||||
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --rebuild " . sh_quote($srpm_path) .
|
||||
" --resultdir " . sh_quote($rebuild_result) .
|
||||
" > " . sh_quote("$pkg_log/mock-rebuild.log") . " 2>&1"
|
||||
);
|
||||
|
||||
my @rpms = sort glob("$rebuild_result/*.rpm");
|
||||
die "No RPMs generated for $pkg in $rebuild_result\n" if !@rpms;
|
||||
|
||||
my $main_rpm = '';
|
||||
for my $rpm (@rpms) {
|
||||
next if $rpm =~ /\.src\.rpm$/;
|
||||
my $name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($rpm));
|
||||
my $rarch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($rpm));
|
||||
next if $name ne $cfg->{rpm_name};
|
||||
if ($cfg->{rpm_arch} eq 'noarch' && $rarch eq 'noarch') {
|
||||
$main_rpm = $rpm;
|
||||
last;
|
||||
}
|
||||
if ($cfg->{rpm_arch} eq 'native' && $rarch eq $arch) {
|
||||
$main_rpm = $rpm;
|
||||
last;
|
||||
}
|
||||
}
|
||||
die "Could not find main RPM for $pkg in $rebuild_result\n" if !$main_rpm;
|
||||
|
||||
run("rpm -qpl " . sh_quote($main_rpm) . " > " . sh_quote("$pkg_log/payload.list"));
|
||||
my $payload = slurp("$pkg_log/payload.list");
|
||||
die "Empty payload list for $pkg main RPM\n" if $payload !~ m{^/}m;
|
||||
|
||||
for my $rpm (@rpms) {
|
||||
copy($rpm, $pkg_result) or die "Failed to copy $rpm to $pkg_result: $!\n";
|
||||
}
|
||||
copy($srpm_path, $pkg_result) or die "Failed to copy $srpm_path to $pkg_result: $!\n";
|
||||
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$rebuild_result/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$pkg_log/$log") or die "Failed to copy $src to $pkg_log: $!\n";
|
||||
}
|
||||
if (-d "$pkg_run_dir/srpm") {
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$pkg_run_dir/srpm/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$pkg_log/srpm-$log") or die "Failed to copy $src to $pkg_log: $!\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!$skip_install) {
|
||||
my $install_cmd = "dnf -y install ";
|
||||
$install_cmd .= "--allowerasing " if $allow_erasing;
|
||||
run($install_cmd . sh_quote($main_rpm));
|
||||
my $module = $cfg->{module};
|
||||
my $rc_mod = run_capture_rc("perl -M$module -e 1", "$pkg_log/smoke-perl-module.log");
|
||||
die "Perl module import failed for $pkg ($module), rc=$rc_mod\n" if $rc_mod != 0;
|
||||
}
|
||||
|
||||
$summary = "$pkg PASS main_rpm=" . basename($main_rpm);
|
||||
$ok = 1;
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
my $err = $@;
|
||||
chomp $err;
|
||||
$err =~ s/\s+/ /g;
|
||||
$summary = "$pkg FAIL $err";
|
||||
open my $efh, '>', "$pkg_log/error.txt" or die "Cannot write $pkg_log/error.txt: $!\n";
|
||||
print {$efh} "$err\n";
|
||||
close $efh;
|
||||
print "ERROR: $err\n";
|
||||
}
|
||||
|
||||
open my $sfh, '>', $status_file or die "Cannot write $status_file: $!\n";
|
||||
print {$sfh} (($ok ? 'PASS' : 'FAIL') . "\t$summary\n");
|
||||
close $sfh;
|
||||
return $ok;
|
||||
}
|
||||
|
||||
sub package_uniqueext {
|
||||
my ($base, $index, $pkg) = @_;
|
||||
my $tag = lc $pkg;
|
||||
$tag =~ s/[^a-z0-9]+/-/g;
|
||||
$tag =~ s/^-+|-+$//g;
|
||||
$tag = "pkg$index" if $tag eq '';
|
||||
my $prefix = $base ne '' ? $base : "perl-list6-$$";
|
||||
my $value = "${prefix}-${index}-${tag}";
|
||||
$value =~ s/[^A-Za-z0-9_.-]+/-/g;
|
||||
return $value;
|
||||
}
|
||||
|
||||
sub usage {
|
||||
return <<"USAGE";
|
||||
Usage: $0 [options]
|
||||
--work-dir PATH Temporary work dir (default: $work_dir)
|
||||
--mock-cfg NAME Mock config (default: <ID>+epel-10-<ARCH>)
|
||||
--mock-uniqueext TXT Optional mock --uniqueext suffix to isolate concurrent builds
|
||||
--jobs N Number of parallel package workers (default: selected package count)
|
||||
--result-dir PATH Output directory (default: build-output/list6/perl/<ARCH>)
|
||||
--log-dir PATH Log directory (default: build-logs/list6/perl/<ARCH>)
|
||||
--packages LIST Comma-separated subset of packages to build
|
||||
--skip-install Skip dnf install + perl module import checks
|
||||
--allow-erasing Allow dnf to erase conflicting packages during install smoke tests
|
||||
USAGE
|
||||
}
|
||||
|
||||
sub select_srpm {
|
||||
my ($globs_ref) = @_;
|
||||
for my $g (@{$globs_ref}) {
|
||||
my @matches = sort glob($g);
|
||||
next if !@matches;
|
||||
return $matches[-1];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
sub parse_spec {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot open spec $path: $!\n";
|
||||
|
||||
my $version = '';
|
||||
my %macros;
|
||||
my @assets;
|
||||
while (my $line = <$fh>) {
|
||||
if ($line =~ /^\s*%(?:global|define)\s+([A-Za-z0-9_]+)\s+(.+?)\s*$/) {
|
||||
my ($k, $v) = ($1, $2);
|
||||
$v =~ s/\s+#.*$//;
|
||||
$macros{$k} = $v;
|
||||
}
|
||||
if ($line =~ /^Version:\s*(\S+)/i) {
|
||||
$version = $1;
|
||||
}
|
||||
if ($line =~ /^(?:Source|Patch)\d*:\s*(\S+)/i) {
|
||||
my $asset = $1;
|
||||
push @assets, $asset;
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
|
||||
$macros{version} = $version if $version ne '';
|
||||
$macros{ver} = $version if $version ne '';
|
||||
|
||||
@assets = map {
|
||||
my $v = $_;
|
||||
for my $i (1 .. 6) {
|
||||
my $changed = 0;
|
||||
for my $k (keys %macros) {
|
||||
my $before = $v;
|
||||
$v =~ s/%\{$k\}/$macros{$k}/g;
|
||||
$changed = 1 if $v ne $before;
|
||||
}
|
||||
last if !$changed;
|
||||
}
|
||||
if ($v =~ m{^[a-zA-Z][a-zA-Z0-9+.-]*://}) {
|
||||
$v = basename($v);
|
||||
}
|
||||
$v =~ s/\?.*$//;
|
||||
$v;
|
||||
} @assets;
|
||||
|
||||
return ($version, @assets);
|
||||
}
|
||||
|
||||
sub print_step {
|
||||
my ($msg) = @_;
|
||||
print "\n== $msg ==\n";
|
||||
}
|
||||
|
||||
sub sh_quote {
|
||||
my ($s) = @_;
|
||||
$s =~ s/'/'"'"'/g;
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $rc = system($cmd);
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub capture {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $out = `$cmd`;
|
||||
my $rc = $?;
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\nOutput:\n$out\n";
|
||||
}
|
||||
chomp $out;
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub run_capture_rc {
|
||||
my ($cmd, $log_file) = @_;
|
||||
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
|
||||
print "+ $full\n";
|
||||
my $rc = system($full);
|
||||
return $rc == -1 ? 255 : ($rc >> 8);
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot read $path: $!\n";
|
||||
local $/;
|
||||
my $content = <$fh>;
|
||||
close $fh;
|
||||
return $content;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
From 1c725e333e9d20b87346fb394a1d01fa5be4fbaf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
||||
Date: Wed, 12 Oct 2016 10:46:22 +0200
|
||||
Subject: [PATCH] Do not use SSLv2_client_method() with OpenSSL >= 1.1.0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
SSLv2 support was removed from OpenSSL 1.1.0.
|
||||
|
||||
CPAN RT#118343
|
||||
|
||||
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
||||
---
|
||||
SSLeay.xs | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/SSLeay.xs b/SSLeay.xs
|
||||
index 1560604..ba0dd24 100644
|
||||
--- a/SSLeay.xs
|
||||
+++ b/SSLeay.xs
|
||||
@@ -152,7 +152,7 @@ SSL_CTX_new(packname, ssl_version)
|
||||
ctx = SSL_CTX_new(SSLv3_client_method());
|
||||
}
|
||||
else {
|
||||
-#ifndef OPENSSL_NO_SSL2
|
||||
+#if !defined OPENSSL_NO_SSL2 && OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
/* v2 is the default */
|
||||
ctx = SSL_CTX_new(SSLv2_client_method());
|
||||
#else
|
||||
--
|
||||
2.7.4
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
diff -up Crypt-SSLeay-0.72/Makefile.PL.orig Crypt-SSLeay-0.72/Makefile.PL
|
||||
--- Crypt-SSLeay-0.72/Makefile.PL.orig 2017-05-16 13:44:37.511126314 +0200
|
||||
+++ Crypt-SSLeay-0.72/Makefile.PL 2017-05-16 13:45:31.141903223 +0200
|
||||
@@ -8,6 +8,7 @@ use Getopt::Long qw( GetOptionsFromArray
|
||||
use Path::Class;
|
||||
use Try::Tiny;
|
||||
|
||||
+BEGIN { push @INC, '.'; }
|
||||
use inc::IO::Interactive::Tiny;
|
||||
|
||||
caller
|
||||
@@ -0,0 +1,21 @@
|
||||
--- a/SSLeay.xs
|
||||
+++ b/SSLeay.xs
|
||||
@@ -149,14 +149,14 @@
|
||||
if(ssl_version == 23) {
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
}
|
||||
else if(ssl_version == 3) {
|
||||
- ctx = SSL_CTX_new(SSLv3_client_method());
|
||||
+ ctx = SSL_CTX_new(TLS_client_method());
|
||||
}
|
||||
else {
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
/* v2 is the default */
|
||||
ctx = SSL_CTX_new(SSLv2_client_method());
|
||||
#else
|
||||
/* v3 is the default */
|
||||
- ctx = SSL_CTX_new(SSLv3_client_method());
|
||||
+ ctx = SSL_CTX_new(TLS_client_method());
|
||||
#endif
|
||||
}
|
||||
EOF
|
||||
390
perl-Crypt-SSLeay/perl-Crypt-SSLeay.spec
Normal file
390
perl-Crypt-SSLeay/perl-Crypt-SSLeay.spec
Normal file
@@ -0,0 +1,390 @@
|
||||
# Disable network tests by default
|
||||
%bcond_with perl_Crypt_SSLeay_enables_network_test
|
||||
|
||||
Name: perl-Crypt-SSLeay
|
||||
Summary: OpenSSL glue that provides LWP with HTTPS support
|
||||
Version: 0.72
|
||||
Release: 24%{?dist}
|
||||
License: Artistic 2.0
|
||||
Source0: https://cpan.metacpan.org/authors/id/N/NA/NANIS/Crypt-SSLeay-%{version}.tar.gz
|
||||
# Adapt to OpenSSL 1.1.0, bug #1383756, CPAN RT#118343
|
||||
Patch0: Crypt-SSLeay-0.72-Do-not-use-SSLv2_client_method-with-OpenSSL-1.1.0.patch
|
||||
Patch1: Crypt-SSLeay-0.72-Fix-building-on-Perl-without-dot-in-INC.patch
|
||||
URL: https://metacpan.org/release/Crypt-SSLeay
|
||||
BuildRequires: coreutils
|
||||
BuildRequires: findutils
|
||||
BuildRequires: gcc
|
||||
BuildRequires: make
|
||||
BuildRequires: openssl-devel
|
||||
BuildRequires: zlib-devel
|
||||
BuildRequires: perl-interpreter
|
||||
BuildRequires: perl-devel
|
||||
BuildRequires: perl-generators
|
||||
BuildRequires: perl(ExtUtils::CBuilder) >= 0.280205
|
||||
BuildRequires: perl(ExtUtils::MakeMaker)
|
||||
# ExtUtils::MakeMaker::Coverage is useless
|
||||
BuildRequires: perl(Getopt::Long)
|
||||
BuildRequires: perl(Path::Class)
|
||||
BuildRequires: perl(strict)
|
||||
BuildRequires: perl(warnings)
|
||||
BuildRequires: pkgconf-pkg-config
|
||||
# Run-time:
|
||||
BuildRequires: /etc/pki/tls/certs/ca-bundle.crt
|
||||
BuildRequires: perl(Carp)
|
||||
# DynaLoader not needed if XSLoader is available
|
||||
BuildRequires: perl(Exporter)
|
||||
BuildRequires: perl(IO::Socket)
|
||||
BuildRequires: perl(MIME::Base64)
|
||||
BuildRequires: perl(Socket)
|
||||
BuildRequires: perl(vars)
|
||||
BuildRequires: perl(XSLoader)
|
||||
# Tests:
|
||||
BuildRequires: perl(Test::More) >= 0.88
|
||||
BuildRequires: perl(Try::Tiny) >= 0.19
|
||||
# Optional tests:
|
||||
BuildRequires: perl(Test::Pod)
|
||||
BuildRequires: perl(Test::Pod::Coverage)
|
||||
%if %{with perl_Crypt_SSLeay_enables_network_test}
|
||||
# Network tests:
|
||||
BuildRequires: perl(constant)
|
||||
BuildRequires: perl(HTTP::Request)
|
||||
BuildRequires: perl(LWP::Protocol::https) >= 6.02
|
||||
BuildRequires: perl(LWP::UserAgent)
|
||||
%endif
|
||||
Requires: perl(:MODULE_COMPAT_%(eval "`perl -V:version`"; echo $version))
|
||||
Requires: /etc/pki/tls/certs/ca-bundle.crt
|
||||
Requires: perl(XSLoader)
|
||||
|
||||
%global __provides_exclude %{?__provides_exclude:__provides_exclude|}^perl\\(DB\\)
|
||||
%{?perl_default_filter}
|
||||
|
||||
%description
|
||||
These Perl modules provide support for the HTTPS protocol under the World-Wide
|
||||
Web library for Perl (LWP), so that a LWP::UserAgent can make HTTPS GET, HEAD,
|
||||
and POST requests.
|
||||
|
||||
This package contains Net::SSL module which is automatically loaded by
|
||||
LWP::Protocol::https on HTTPS requests, and provides the necessary SSL glue
|
||||
for that module to work.
|
||||
|
||||
%prep
|
||||
%setup -q -n Crypt-SSLeay-%{version}
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
# OpenSSL 3 removed SSLv3 symbols; force TLS method for the old SSLv3 code path.
|
||||
sed -i 's/SSLv3_client_method()/TLS_client_method()/g' SSLeay.xs
|
||||
|
||||
# Placate rpmlint
|
||||
chmod -c -x lib/Net/SSL.pm
|
||||
|
||||
%build
|
||||
if pkg-config openssl ; then
|
||||
export INC="$CFLAGS `pkg-config --cflags-only-I openssl`"
|
||||
export LDFLAGS="$LDFLAGS `pkg-config --libs-only-L openssl`"
|
||||
fi
|
||||
|
||||
perl Makefile.PL --%{!?with_perl_Crypt_SSLeay_enables_network_test:no-}live-tests \
|
||||
INC="$INC" LDFLAGS="$LDFLAGS" INSTALLDIRS=vendor NO_PACKLIST=1 \
|
||||
OPTIMIZE="%{optflags}" </dev/null
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
make pure_install DESTDIR=%{buildroot}
|
||||
find %{buildroot} -type f -name '*.bs' -a -size 0 -delete
|
||||
%{_fixperms} %{buildroot}
|
||||
chmod -R u+w %{buildroot}/*
|
||||
chmod -R 644 eg/*
|
||||
chmod -R 644 certs/*
|
||||
rm certs/ca-bundle.crt
|
||||
ln -s /etc/pki/tls/certs/ca-bundle.crt certs/ca-bundle.crt
|
||||
|
||||
%check
|
||||
make test
|
||||
|
||||
%files
|
||||
%doc Changes eg/* certs/*
|
||||
%{perl_vendorarch}/auto/Crypt/
|
||||
%{perl_vendorarch}/Crypt/
|
||||
%{perl_vendorarch}/Net/
|
||||
%{_mandir}/man3/Crypt::SSLeay.3pm*
|
||||
%{_mandir}/man3/Crypt::SSLeay::Version.3pm*
|
||||
%{_mandir}/man3/Net::SSL.3pm*
|
||||
|
||||
%changelog
|
||||
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.72-20
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
||||
|
||||
* Thu Jun 28 2018 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-19
|
||||
- Perl 5.28 rebuild
|
||||
|
||||
* Thu Feb 08 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.72-18
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
|
||||
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.72-17
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
|
||||
|
||||
* Thu Jul 27 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.72-16
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
|
||||
|
||||
* Wed Jun 07 2017 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-15
|
||||
- Perl 5.26 re-rebuild of bootstrapped packages
|
||||
|
||||
* Mon Jun 05 2017 Petr Pisar <ppisar@redhat.com> - 0.72-14
|
||||
- Modernize spec file
|
||||
|
||||
* Mon Jun 05 2017 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-13
|
||||
- Perl 5.26 rebuild
|
||||
|
||||
* Tue May 16 2017 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-12
|
||||
- Fix building on Perl without '.' in @INC
|
||||
|
||||
* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.72-11
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
|
||||
|
||||
* Wed Oct 12 2016 Petr Pisar <ppisar@redhat.com> - 0.72-10
|
||||
- Adapt to OpenSSL 1.1.0 (bug #1383756)
|
||||
|
||||
* Sun May 15 2016 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-9
|
||||
- Perl 5.24 rebuild
|
||||
|
||||
* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.72-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
|
||||
|
||||
* Thu Jun 18 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.72-7
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
|
||||
|
||||
* Sat Jun 06 2015 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-6
|
||||
- Perl 5.22 rebuild
|
||||
|
||||
* Fri Aug 29 2014 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-5
|
||||
- Perl 5.20 rebuild
|
||||
|
||||
* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.72-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
|
||||
|
||||
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.72-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
|
||||
|
||||
* Mon Apr 28 2014 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-2
|
||||
- Correct License tag, which should be Artistic 2.0
|
||||
|
||||
* Mon Apr 28 2014 Jitka Plesnikova <jplesnik@redhat.com> - 0.72-1
|
||||
- 0.72 bump
|
||||
|
||||
* Wed Apr 16 2014 Petr Pisar <ppisar@redhat.com> - 0.64-6
|
||||
- Make build script non-interactive
|
||||
- Update package description
|
||||
- Specify all dependencies
|
||||
|
||||
* Sat Aug 03 2013 Petr Pisar <ppisar@redhat.com> - 0.64-5
|
||||
- Perl 5.18 rebuild
|
||||
|
||||
* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.64-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||
|
||||
* Wed Aug 8 2012 Paul Howarth <paul@city-fan.org> - 0.64-3
|
||||
- Remove circular BR: perl(Net::SSL) provided by this package
|
||||
- Placate rpmlint regarding file permissions
|
||||
- Don't need to remove empty directories from the buildroot
|
||||
|
||||
* Tue Aug 07 2012 Petr Šabata <contyk@redhat.com> - 0.64-1
|
||||
- 0.64 bump
|
||||
|
||||
* Mon Jul 30 2012 Petr Šabata <contyk@redhat.com> - 0.60-1
|
||||
- 0.60 bugfix bump
|
||||
- Drop command macros and modernize the spec a bit
|
||||
|
||||
* Fri Jul 20 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.58-11
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
|
||||
|
||||
* Fri Jul 20 2012 Marcela Mašláňová <mmaslano@redhat.com> - 0.58-10
|
||||
- Conditionalize ExtUtils::MakeMaker::Coverage
|
||||
|
||||
* Mon Jun 25 2012 Petr Pisar <ppisar@redhat.com> - 0.58-9
|
||||
- Perl 5.16 rebuild
|
||||
|
||||
* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.58-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
|
||||
|
||||
* Wed Sep 07 2011 Petr Sabata <contyk@redhat.com> - 0.58-7
|
||||
- Link to the ca-certificates ca-bundle.crt instead of shipping our own,
|
||||
outdated copy (#734385)
|
||||
|
||||
* Fri Jul 22 2011 Petr Pisar <ppisar@redhat.com> - 0.58-6
|
||||
- RPM 4.9 dependency filtering added
|
||||
|
||||
* Wed Jul 20 2011 Petr Sabata <contyk@redhat.com> - 0.58-5
|
||||
- Perl mass rebuild
|
||||
|
||||
* Tue Apr 19 2011 Paul Howarth <paul@city-fan.org> - 0.58-4
|
||||
- Remove buildroot specification and cleaning, not needed for modern rpmbuild
|
||||
- Use %%{?perl_default_filter}
|
||||
- Filter the perl(DB) provide in a way that works with rpm >= 4.9
|
||||
- Use DESTDIR rather than PERL_INSTALL_ROOT
|
||||
- Fix line endings on documentation
|
||||
- Fix upstream source URL
|
||||
- Fix argument order for find with -depth
|
||||
|
||||
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.58-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
|
||||
|
||||
* Thu Dec 16 2010 Marcela Maslanova <mmaslano@redhat.com> - 0.58-2
|
||||
- Rebuild to fix problems with vendorarch/lib (#661697)
|
||||
|
||||
* Wed Sep 1 2010 Petr Sabata <psabata@redhat.com> - 0.58-1
|
||||
- New upstream release, v0.58
|
||||
- removing perl-Crypt-SSLeay-0.57-live-tests.patch, fixed in upstream
|
||||
- removing perl-Crypt-SSLeay-Makefile_ssl1.patch, fixed in upstream
|
||||
|
||||
* Fri Apr 30 2010 Marcela Maslanova <mmaslano@redhat.com> - 0.57-17
|
||||
- Mass rebuild with perl-5.12.0
|
||||
|
||||
* Mon Dec 7 2009 Stepan Kasal <skasal@redhat.com> - 0.57-16
|
||||
- rebuild against perl 5.10.1
|
||||
|
||||
* Wed Nov 25 2009 Marcela Mašláňová <mmaslano@redhat.com> - 0.57-14
|
||||
- change Makefile for openssl 1.0, which couldn't be found properly before
|
||||
|
||||
* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 0.57-13
|
||||
- rebuilt with new openssl
|
||||
|
||||
* Sat Jul 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.57-12
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
|
||||
|
||||
* Thu Feb 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.57-11
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
|
||||
|
||||
* Sat Jan 17 2009 Tomas Mraz <tmraz@redhat.com> - 0.57-10
|
||||
- rebuild with new openssl
|
||||
|
||||
* Mon Oct 6 2008 Marcela Maslanova <mmaslano@redhat.com> - 0.57-9
|
||||
- add examples into doc
|
||||
|
||||
* Wed Sep 24 2008 Marcela Maslanova <mmaslano@redhat.com> - 0.57-8
|
||||
- fix patches for fuzz
|
||||
|
||||
* Wed Mar 5 2008 Tom "spot" Callaway <tcallawa@redhat.com> - 0.57-7
|
||||
- rebuild for new perl
|
||||
|
||||
* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 0.57-6
|
||||
- Autorebuild for GCC 4.3
|
||||
|
||||
* Wed Dec 05 2007 Release Engineering <rel-eng at fedoraproject dot org> - 0.57-5
|
||||
- Rebuild for deps
|
||||
|
||||
* Wed Dec 5 2007 Robin Norwood <rnorwood@redhat.com> - 0.57-4
|
||||
- Rebuild for new openssl
|
||||
|
||||
* Sat Oct 27 2007 Robin Norwood <rnorwood@redhat.com> - 0.57-3
|
||||
- Remove unnecessary BR: pkgconfig
|
||||
|
||||
* Fri Oct 26 2007 Robin Norwood <rnorwood@redhat.com> - 0.57-2
|
||||
- Fix buildroot per package review
|
||||
- Resolves: bz#226248
|
||||
|
||||
* Thu Oct 25 2007 Robin Norwood <rnorwood@redhat.com> - 0.57-1
|
||||
- Update to latest upstream version.
|
||||
- Remove old patch (patch applied to upstream)
|
||||
- Several fixes for package review:
|
||||
- Fixed BuildRequires (added Test::Pod and LWP::UserAgent)
|
||||
- Apply patch to avoid prompting for input when building Makefile
|
||||
- Fix defattr line
|
||||
- Resolves: bz#226248
|
||||
|
||||
* Mon Aug 27 2007 Robin Norwood <rnorwood@redhat.com> - 0.56-2
|
||||
- perl(ExtUtils::MakeMaker::Coverage) is now available
|
||||
|
||||
* Mon Aug 13 2007 Robin Norwood <rnorwood@redhat.com> - 0.56-1
|
||||
- 0.56 is the latest CPAN version, not 0.55
|
||||
|
||||
* Mon Aug 13 2007 Robin Norwood <rnorwood@redhat.com> - 0.55-2
|
||||
- Update to latest version from CPAN: 0.55
|
||||
- Remove two old patches, update lib64 patch for Makefile.PL changes.
|
||||
|
||||
* Tue Feb 13 2007 Robin Norwood <rnorwood@redhat.com> - 0.53-1
|
||||
- New version: 0.53
|
||||
|
||||
* Mon Nov 27 2006 Robin Norwood <rnorwood@redhat.com> - 0.51-12
|
||||
- Resolves: bug#217138
|
||||
- fix a segfault on x86_64
|
||||
|
||||
* Tue Oct 17 2006 Robin Norwood <rnorwood@redhat.com> - 0.51-10
|
||||
- Filter out Provides perl(DB)
|
||||
- bug #205562
|
||||
|
||||
* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 0.51-9.2.2.1
|
||||
- rebuild
|
||||
|
||||
* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 0.51-9.2.2
|
||||
- bump again for double-long bug on ppc(64)
|
||||
|
||||
* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 0.51-9.2.1
|
||||
- rebuilt for new gcc4.1 snapshot and glibc changes
|
||||
|
||||
* Fri Feb 03 2006 Jason Vas Dias <jvdias@redhat.com> - 0.51-9.2
|
||||
- rebuild for new perl-5.8.8 / gcc / glibc
|
||||
|
||||
* Fri Dec 16 2005 Jesse Keating <jkeating@redhat.com>
|
||||
- rebuilt for new gcc
|
||||
|
||||
* Fri Dec 16 2005 Jesse Keating <jkeating@redhat.com>
|
||||
- rebuilt for new gcj
|
||||
|
||||
* Thu Nov 10 2005 Tomas Mraz <tmraz@redhat.com> 0.51-9
|
||||
- rebuilt against new openssl
|
||||
- added missing SSL_library_init()
|
||||
|
||||
* Sat Sep 24 2005 Ville Skyttä <ville.skytta at iki.fi> 0.51-8
|
||||
- Own more installed dirs (#73908).
|
||||
- Enable rpmbuild's internal dependency generator, drop unneeded dependencies.
|
||||
- Require perl(:MODULE_COMPAT_*).
|
||||
- Run tests in the %%check section.
|
||||
- Fix License, Source0, URL, and Group tags.
|
||||
|
||||
* Wed Mar 30 2005 Warren Togami <wtogami@redhat.com> 0.51-7
|
||||
- remove brp-compress
|
||||
|
||||
* Tue Mar 8 2005 Joe Orton <jorton@redhat.com> 0.51-6
|
||||
- rebuild
|
||||
|
||||
* Tue Aug 31 2004 Chip Turner <cturner@redhat.com> 0.51-5
|
||||
- build for FC3
|
||||
|
||||
* Tue Aug 31 2004 Chip Turner <cturner@redhat.com> 0.51-4
|
||||
- build for RHEL3 U4
|
||||
|
||||
* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
|
||||
- rebuilt
|
||||
|
||||
* Tue Mar 02 2004 Elliot Lee <sopwith@redhat.com>
|
||||
- rebuilt
|
||||
|
||||
* Fri Feb 13 2004 Chip Turner <cturner@redhat.com> 0.51-1
|
||||
- update to upstream 0.51
|
||||
|
||||
* Thu Jun 05 2003 Elliot Lee <sopwith@redhat.com>
|
||||
- rebuilt
|
||||
|
||||
* Tue Jan 7 2003 Nalin Dahyabhai <nalin@redhat.com>
|
||||
- pass openssl includes to make as INC and ldflags in as LDFLAGS
|
||||
|
||||
* Thu Nov 21 2002 Chip Turner <cturner@redhat.com>
|
||||
- patch to support /usr/lib64 before /usr/lib
|
||||
|
||||
* Wed Nov 20 2002 Chip Turner <cturner@redhat.com>
|
||||
- rebuild
|
||||
|
||||
* Tue Aug 6 2002 Chip Turner <cturner@redhat.com>
|
||||
- automated release bump and build
|
||||
|
||||
* Thu Jun 27 2002 Chip Turner <cturner@redhat.com>
|
||||
- description update
|
||||
|
||||
* Tue Jun 25 2002 Chip Turner <cturner@redhat.com>
|
||||
- move to 0.39
|
||||
|
||||
* Wed Jan 09 2002 Tim Powers <timp@redhat.com>
|
||||
- automated rebuild
|
||||
|
||||
* Fri Dec 7 2001 root <root@redhat.com>
|
||||
- Spec file was autogenerated.
|
||||
@@ -5,16 +5,20 @@
|
||||
|
||||
Name: perl-%{upstream_name}
|
||||
Version: %{upstream_version}
|
||||
Release: 2
|
||||
Release: 3%{?dist}
|
||||
|
||||
Summary: Politely process multiple HTTP requests
|
||||
License: GPL+ or Artistic
|
||||
Group: Development/Perl
|
||||
Url: http://search.cpan.org/dist/%{upstream_name}
|
||||
Source0: http://www.cpan.org/modules/by-module/HTTP/%{upstream_name}-%{upstream_version}.tar.gz
|
||||
Patch: HTTP-Async-0.30.patch
|
||||
Patch0: HTTP-Async-0.30.patch
|
||||
BuildArch: noarch
|
||||
|
||||
BuildRequires: perl(ExtUtils::MakeMaker)
|
||||
BuildRequires: make
|
||||
BuildRequires: perl-generators
|
||||
|
||||
%description
|
||||
Although using the conventional 'LWP::UserAgent' is fast and easy it does
|
||||
have some drawbacks - the code execution blocks until the request has been
|
||||
@@ -35,7 +39,7 @@ using 'select' lists.
|
||||
%prep
|
||||
%setup -q -n %{upstream_name}-%{upstream_version}
|
||||
|
||||
%patch -p1
|
||||
%patch 0 -p1
|
||||
|
||||
%build
|
||||
CFLAGS="$RPM_OPT_FLAGS $CFLAGS" %__perl Makefile.PL
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
name: perl-IO-Tty
|
||||
summary: IO-Tty - Pseudo ttys and constants
|
||||
version: 1.07
|
||||
release: 1
|
||||
release: 2%{?dist}
|
||||
vendor: Roland Giersig <RGiersig@cpan.org>
|
||||
packager: Arix International <cpan2rpm@arix.com>
|
||||
license: Artistic
|
||||
@@ -24,6 +24,13 @@ buildroot: %{_tmppath}/%{name}-%{version}-%(id -u -n)
|
||||
prefix: %(echo %{_prefix})
|
||||
source: IO-Tty-1.07.tar.gz
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: make
|
||||
BuildRequires: perl-interpreter
|
||||
BuildRequires: perl-devel
|
||||
BuildRequires: perl(ExtUtils::MakeMaker)
|
||||
BuildRequires: perl-generators
|
||||
|
||||
%description
|
||||
"IO::Tty" is used internally by "IO::Pty" to create a pseudo-tty.
|
||||
You wouldn't want to use it directly except to import constants, use
|
||||
@@ -80,7 +87,7 @@ CFLAGS="$RPM_OPT_FLAGS"
|
||||
%install
|
||||
[ "%{buildroot}" != "/" ] && rm -rf %{buildroot}
|
||||
|
||||
%{makeinstall} `%{__perl} -MExtUtils::MakeMaker -e ' print \$ExtUtils::MakeMaker::VERSION <= 6.05 ? qq|PREFIX=%{buildroot}%{_prefix}| : qq|DESTDIR=%{buildroot}| '`
|
||||
%{__make} pure_install DESTDIR=%{buildroot}
|
||||
|
||||
cmd=/usr/share/spec-helper/compress_files
|
||||
[ -x $cmd ] || cmd=/usr/lib/rpm/brp-compress
|
||||
|
||||
@@ -5,20 +5,22 @@
|
||||
|
||||
Name: perl-%{upstream_name}
|
||||
Version: %{upstream_version}
|
||||
Release: 2
|
||||
Release: 3%{?dist}
|
||||
|
||||
Summary: Non-blocking HTTPS client
|
||||
License: GPL+ or Artistic
|
||||
Group: Development/Perl
|
||||
Url: http://search.cpan.org/dist/%{upstream_name}
|
||||
Source0: http://www.cpan.org/modules/by-module/Net/%{upstream_name}-%{upstream_version}.tar.gz
|
||||
Patch: Net-HTTPS-NB-0.14.patch
|
||||
Patch0: Net-HTTPS-NB-0.14.patch
|
||||
|
||||
BuildRequires: perl(Exporter)
|
||||
BuildRequires: perl(ExtUtils::MakeMaker)
|
||||
BuildRequires: perl(IO::Socket::SSL) >= 0.980.0
|
||||
BuildRequires: perl(Net::HTTP)
|
||||
BuildRequires: perl(Net::HTTPS)
|
||||
BuildRequires: make
|
||||
BuildRequires: perl-generators
|
||||
BuildArch: noarch
|
||||
|
||||
%description
|
||||
@@ -35,7 +37,7 @@ addition allows non-blocking connect.
|
||||
%prep
|
||||
%setup -q -n %{upstream_name}-%{upstream_version}
|
||||
|
||||
%patch -p1
|
||||
%patch 0 -p1
|
||||
|
||||
%build
|
||||
%__perl Makefile.PL
|
||||
|
||||
@@ -14,17 +14,24 @@
|
||||
name: perl-Sys-Virt
|
||||
summary: Sys-Virt - Represent and manage a libvirt hypervisor connection
|
||||
version: 0.2.0
|
||||
release: 2
|
||||
release: 3%{?dist}
|
||||
vendor: Daniel P. Berrange <berrange@redhat.com>
|
||||
packager: Arix International <cpan2rpm@arix.com>
|
||||
license: Artistic
|
||||
group: Applications/CPAN
|
||||
url: http://www.cpan.org
|
||||
buildroot: %{_tmppath}/%{name}-%{version}-%(id -u -n)
|
||||
buildarch: x86_64
|
||||
prefix: %(echo %{_prefix})
|
||||
source: Sys-Virt-0.2.0.tar.gz
|
||||
patch: Sys-Virt-fixes.patch
|
||||
patch0: Sys-Virt-fixes.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: make
|
||||
BuildRequires: perl-interpreter
|
||||
BuildRequires: perl-devel
|
||||
BuildRequires: perl(ExtUtils::MakeMaker)
|
||||
BuildRequires: perl-generators
|
||||
BuildRequires: libvirt-devel
|
||||
|
||||
%description
|
||||
The Sys::Virt module provides a Perl XS binding to the libvirt
|
||||
@@ -40,10 +47,11 @@ a consistent API.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{pkgname}-%{version}
|
||||
%patch
|
||||
%patch 0 -p0
|
||||
chmod -R u+w %{_builddir}/%{pkgname}-%{version}
|
||||
|
||||
%build
|
||||
export PERL_USE_UNSAFE_INC=1
|
||||
grep -rsl '^#!.*perl' . |
|
||||
grep -v '.bak$' |xargs --no-run-if-empty \
|
||||
%__perl -MExtUtils::MakeMaker -e 'MY->fixin(@ARGV)'
|
||||
@@ -57,7 +65,7 @@ CFLAGS="$RPM_OPT_FLAGS"
|
||||
%install
|
||||
[ "%{buildroot}" != "/" ] && rm -rf %{buildroot}
|
||||
|
||||
%{makeinstall} `%{__perl} -MExtUtils::MakeMaker -e ' print \$ExtUtils::MakeMaker::VERSION <= 6.05 ? qq|PREFIX=%{buildroot}%{_prefix}| : qq|DESTDIR=%{buildroot}| '`
|
||||
%{__make} pure_install DESTDIR=%{buildroot}
|
||||
|
||||
cmd=/usr/share/spec-helper/compress_files
|
||||
[ -x $cmd ] || cmd=/usr/lib/rpm/brp-compress
|
||||
|
||||
399
syslinux/mockbuild.pl
Executable file
399
syslinux/mockbuild.pl
Executable file
@@ -0,0 +1,399 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname basename);
|
||||
use File::Copy qw(copy);
|
||||
use File::Path qw(make_path remove_tree);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
|
||||
my $script_dir = abs_path(dirname(__FILE__));
|
||||
my $repo_root = abs_path("$script_dir/..");
|
||||
my $pkg_dir = "$repo_root/syslinux";
|
||||
my $spec_file = "$pkg_dir/syslinux-xcat.spec";
|
||||
|
||||
my $source_url = 'https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.xz';
|
||||
my $source_file = '';
|
||||
my $work_dir = '/tmp/syslinux-xcat-mockbuild';
|
||||
my $mock_cfg = '';
|
||||
my $mock_uniqueext = '';
|
||||
my $result_dir = "$repo_root/build-output/list3/syslinux-xcat";
|
||||
my $log_dir = "$repo_root/build-logs/list3/syslinux-xcat";
|
||||
my $skip_install = 0;
|
||||
my $skip_upstream_download = 0;
|
||||
|
||||
GetOptions(
|
||||
'source-url=s' => \$source_url,
|
||||
'source-file=s' => \$source_file,
|
||||
'work-dir=s' => \$work_dir,
|
||||
'mock-cfg=s' => \$mock_cfg,
|
||||
'mock-uniqueext=s' => \$mock_uniqueext,
|
||||
'result-dir=s' => \$result_dir,
|
||||
'log-dir=s' => \$log_dir,
|
||||
'skip-install!' => \$skip_install,
|
||||
'skip-upstream-download!' => \$skip_upstream_download,
|
||||
) or die usage();
|
||||
|
||||
die "Run as root (current uid=$>)\n" if $> != 0;
|
||||
die "Missing spec file: $spec_file\n" if !-f $spec_file;
|
||||
|
||||
for my $bin (qw(wget mock rpmbuild rpm dnf file bash grep cut)) {
|
||||
run("command -v " . sh_quote($bin) . " >/dev/null 2>&1");
|
||||
}
|
||||
|
||||
my ($pkg_name, $version, $source_assets_ref, $patch_assets_ref, $all_assets_ref) = parse_spec($spec_file);
|
||||
my @source_assets = @{$source_assets_ref};
|
||||
my @patch_assets = @{$patch_assets_ref};
|
||||
my @all_assets = @{$all_assets_ref};
|
||||
|
||||
die "Could not parse Name/Version from $spec_file\n" if !$pkg_name || !$version;
|
||||
die "No Source assets found in $spec_file\n" if !@source_assets;
|
||||
|
||||
if (!$source_file) {
|
||||
$source_file = $source_assets[0];
|
||||
}
|
||||
|
||||
my $source_path = "$pkg_dir/$source_file";
|
||||
my $arch = capture('uname -m');
|
||||
if (!$mock_cfg) {
|
||||
my $os_id = capture(q{bash -lc 'source /etc/os-release; echo $ID'});
|
||||
$mock_cfg = "${os_id}+epel-10-${arch}";
|
||||
}
|
||||
my $mock_uniqueext_opt = $mock_uniqueext ne ''
|
||||
? ' --uniqueext ' . sh_quote($mock_uniqueext)
|
||||
: '';
|
||||
|
||||
print_step("Configuration");
|
||||
print "repo_root: $repo_root\n";
|
||||
print "pkg_dir: $pkg_dir\n";
|
||||
print "work_dir: $work_dir\n";
|
||||
print "result_dir: $result_dir\n";
|
||||
print "log_dir: $log_dir\n";
|
||||
print "spec_file: $spec_file\n";
|
||||
print "pkg_name: $pkg_name\n";
|
||||
print "version: $version\n";
|
||||
print "mock_cfg: $mock_cfg\n";
|
||||
print "mock_uniqueext: " . ($mock_uniqueext ne '' ? $mock_uniqueext : '(none)') . "\n";
|
||||
print "source_url: $source_url\n";
|
||||
print "source_file:$source_file\n";
|
||||
print "skip_install: $skip_install\n";
|
||||
print "skip_upstream_download: $skip_upstream_download\n";
|
||||
|
||||
make_path($result_dir);
|
||||
make_path($log_dir);
|
||||
|
||||
print_step("Mock config check");
|
||||
run("mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt . " --print-root-path >/dev/null");
|
||||
|
||||
if (!$skip_upstream_download) {
|
||||
print_step("Download upstream source");
|
||||
run("wget --spider " . sh_quote($source_url));
|
||||
run("wget -O " . sh_quote($source_path) . " " . sh_quote($source_url));
|
||||
|
||||
my $sha = capture("sha256sum " . sh_quote($source_path) . " | cut -d ' ' -f1");
|
||||
my $meta_file = "$log_dir/upstream-source.txt";
|
||||
open my $mfh, '>', $meta_file or die "Cannot write $meta_file: $!\n";
|
||||
print {$mfh} "url=$source_url\n";
|
||||
print {$mfh} "file=$source_path\n";
|
||||
print {$mfh} "sha256=$sha\n";
|
||||
close $mfh;
|
||||
print "Downloaded source: $source_path\n";
|
||||
print "SHA256: $sha\n";
|
||||
}
|
||||
|
||||
print_step("Verify spec assets");
|
||||
for my $asset (@all_assets) {
|
||||
my $path = "$pkg_dir/$asset";
|
||||
die "Missing required spec asset: $path\n" if !-f $path;
|
||||
}
|
||||
print "Verified Sources=" . scalar(@source_assets) . ", Patches=" . scalar(@patch_assets) . "\n";
|
||||
|
||||
print_step("Stage files for patch-application check");
|
||||
remove_tree($work_dir) if -d $work_dir;
|
||||
my $prep_top = "$work_dir/prep";
|
||||
for my $d (qw(BUILD BUILDROOT RPMS SOURCES SPECS SRPMS)) {
|
||||
make_path("$prep_top/$d");
|
||||
}
|
||||
copy($spec_file, "$prep_top/SPECS/syslinux-xcat.spec")
|
||||
or die "Failed to copy spec to prep topdir: $!\n";
|
||||
for my $asset (@all_assets) {
|
||||
copy("$pkg_dir/$asset", "$prep_top/SOURCES/$asset")
|
||||
or die "Failed to copy $asset into prep SOURCES: $!\n";
|
||||
}
|
||||
|
||||
print_step("Apply patches in %prep");
|
||||
my $prep_log = "$log_dir/prep.log";
|
||||
run(
|
||||
"rpmbuild --define " . sh_quote("_topdir $prep_top") .
|
||||
" -bp --nodeps " . sh_quote("$prep_top/SPECS/syslinux-xcat.spec") .
|
||||
" > " . sh_quote($prep_log) . " 2>&1"
|
||||
);
|
||||
my $patch_count = capture("grep -c '^Patch #' " . sh_quote($prep_log) . " || true");
|
||||
print "Patch application check passed. Applied patches: $patch_count\n";
|
||||
|
||||
print_step("Build SRPM with mock");
|
||||
my $srpm_out = "$work_dir/srpm";
|
||||
make_path($srpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --buildsrpm --spec " . sh_quote($spec_file) .
|
||||
" --sources " . sh_quote($pkg_dir) .
|
||||
" --resultdir " . sh_quote($srpm_out)
|
||||
);
|
||||
|
||||
my @srpms = sort glob("$srpm_out/*.src.rpm");
|
||||
die "SRPM not generated in $srpm_out\n" if !@srpms;
|
||||
my $srpm = $srpms[-1];
|
||||
print "SRPM: $srpm\n";
|
||||
|
||||
print_step("Rebuild RPM with mock");
|
||||
my $rpm_out = "$work_dir/rpm";
|
||||
make_path($rpm_out);
|
||||
run(
|
||||
"mock -r " . sh_quote($mock_cfg) . $mock_uniqueext_opt .
|
||||
" --rebuild " . sh_quote($srpm) .
|
||||
" --resultdir " . sh_quote($rpm_out)
|
||||
);
|
||||
|
||||
my @all_rpms = sort glob("$rpm_out/*.rpm");
|
||||
die "No RPMs generated in $rpm_out\n" if !@all_rpms;
|
||||
|
||||
my $xcat_rpm = '';
|
||||
my $main_rpm = '';
|
||||
for my $rpm (@all_rpms) {
|
||||
next if $rpm =~ /\.src\.rpm$/;
|
||||
my $name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($rpm));
|
||||
my $rarch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($rpm));
|
||||
if ($name eq 'syslinux-xcat' && $rarch eq 'noarch') {
|
||||
$xcat_rpm = $rpm;
|
||||
}
|
||||
if ($name eq 'syslinux' && $rarch eq $arch) {
|
||||
$main_rpm = $rpm;
|
||||
}
|
||||
}
|
||||
die "Could not find main syslinux-xcat noarch RPM in $rpm_out\n" if !$xcat_rpm;
|
||||
|
||||
print_step("Verify generated RPM");
|
||||
my $rpm_name = capture("rpm -qp --qf '%{NAME}' " . sh_quote($xcat_rpm));
|
||||
my $rpm_arch = capture("rpm -qp --qf '%{ARCH}' " . sh_quote($xcat_rpm));
|
||||
die "Unexpected RPM name: $rpm_name\n" if $rpm_name ne 'syslinux-xcat';
|
||||
die "Unexpected RPM arch: $rpm_arch (expected noarch)\n" if $rpm_arch ne 'noarch';
|
||||
run(
|
||||
"rpm -qpl " . sh_quote($xcat_rpm) .
|
||||
" | grep -F '/opt/xcat/share/xcat/netboot/syslinux/' >/dev/null"
|
||||
);
|
||||
run(
|
||||
"rpm -qpl " . sh_quote($xcat_rpm) .
|
||||
" | grep -Fx /opt/xcat/share/xcat/netboot/syslinux/pxelinux.0 >/dev/null"
|
||||
);
|
||||
print "Verified RPM name/arch/payload: $xcat_rpm\n";
|
||||
|
||||
print_step("Copy artifacts and logs");
|
||||
for my $rpm (@all_rpms) {
|
||||
copy($rpm, $result_dir) or die "Failed to copy $rpm to $result_dir: $!\n";
|
||||
}
|
||||
copy($srpm, $result_dir) or die "Failed to copy $srpm to $result_dir: $!\n";
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$rpm_out/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$log_dir/$log")
|
||||
or die "Failed to copy $src to $log_dir: $!\n";
|
||||
}
|
||||
for my $log (qw(build.log root.log state.log hw_info.log installed_pkgs.log)) {
|
||||
my $src = "$srpm_out/$log";
|
||||
next if !-f $src;
|
||||
copy($src, "$log_dir/srpm-$log")
|
||||
or die "Failed to copy $src to $log_dir: $!\n";
|
||||
}
|
||||
|
||||
if (!$skip_install) {
|
||||
print_step("Install RPM(s) and run smoke tests");
|
||||
run("dnf -y install " . sh_quote($xcat_rpm));
|
||||
if ($main_rpm) {
|
||||
run("dnf -y install " . sh_quote($main_rpm));
|
||||
}
|
||||
|
||||
my $pxe_file = '/opt/xcat/share/xcat/netboot/syslinux/pxelinux.0';
|
||||
die "Missing installed PXE file: $pxe_file\n" if !-f $pxe_file;
|
||||
|
||||
my $file_log = "$log_dir/smoke-file.log";
|
||||
my $qf_log = "$log_dir/smoke-rpm-qf.log";
|
||||
my $rc_file = run_capture_rc("file $pxe_file", $file_log);
|
||||
my $rc_qf = run_capture_rc("rpm -qf $pxe_file", $qf_log);
|
||||
|
||||
die "Smoke check failed: file returned $rc_file\n" if $rc_file != 0;
|
||||
die "Smoke check failed: rpm -qf returned $rc_qf\n" if $rc_qf != 0;
|
||||
|
||||
my $qf_out = slurp($qf_log);
|
||||
die "Installed file is not owned by syslinux-xcat:\n$qf_out\n"
|
||||
if $qf_out !~ /^syslinux-xcat-/m;
|
||||
|
||||
my $syslinux_help_log = "$log_dir/smoke-syslinux-help.log";
|
||||
if (-x '/usr/bin/syslinux') {
|
||||
my $rc_help = run_capture_rc("/usr/bin/syslinux --help", $syslinux_help_log);
|
||||
my $help_out = slurp($syslinux_help_log);
|
||||
die "syslinux --help returned unexpected rc=$rc_help\n"
|
||||
if $rc_help != 0 && $rc_help != 1;
|
||||
die "syslinux --help output missing expected usage text\n"
|
||||
if $help_out !~ /usage|syslinux/i;
|
||||
}
|
||||
|
||||
my $summary = "$log_dir/smoke-summary.txt";
|
||||
open my $sfh, '>', $summary or die "Cannot write $summary: $!\n";
|
||||
print {$sfh} "pxe_file=$pxe_file\n";
|
||||
print {$sfh} "rc_file=$rc_file\n";
|
||||
print {$sfh} "rc_qf=$rc_qf\n";
|
||||
print {$sfh} "main_rpm_installed=" . ($main_rpm ? 1 : 0) . "\n";
|
||||
close $sfh;
|
||||
}
|
||||
|
||||
print_step("Completed");
|
||||
print "syslinux-xcat RPM: $xcat_rpm\n";
|
||||
print "Artifacts: $result_dir\n";
|
||||
print "Logs: $log_dir\n";
|
||||
exit 0;
|
||||
|
||||
sub usage {
|
||||
return <<"USAGE";
|
||||
Usage: $0 [options]
|
||||
--source-url URL Upstream tarball URL (default: $source_url)
|
||||
--source-file FILE Source filename stored in syslinux/ (default: inferred from spec)
|
||||
--work-dir PATH Temporary work dir (default: $work_dir)
|
||||
--mock-cfg NAME Mock config (default: <ID>+epel-10-<ARCH>)
|
||||
--mock-uniqueext TXT Optional mock --uniqueext suffix to isolate concurrent builds
|
||||
--result-dir PATH Output RPM/SRPM directory (default: $result_dir)
|
||||
--log-dir PATH Log directory (default: $log_dir)
|
||||
--skip-upstream-download Skip wget download step
|
||||
--skip-install Skip dnf install + smoke tests
|
||||
USAGE
|
||||
}
|
||||
|
||||
sub parse_spec {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot open spec $path: $!\n";
|
||||
|
||||
my %macros;
|
||||
my $name = '';
|
||||
my $version = '';
|
||||
my @sources;
|
||||
my @patches;
|
||||
|
||||
while (my $line = <$fh>) {
|
||||
if ($line =~ /^\s*%(?:define|global)\s+([A-Za-z0-9_]+)\s+(.+?)\s*$/) {
|
||||
my ($k, $v) = (lc($1), $2);
|
||||
$v =~ s/\s+#.*$//;
|
||||
$macros{$k} = $v;
|
||||
next;
|
||||
}
|
||||
if ($line =~ /^Name:\s*(\S+)/) {
|
||||
$name = $1;
|
||||
$macros{name} = $name;
|
||||
next;
|
||||
}
|
||||
if ($line =~ /^Version:\s*(\S+)/) {
|
||||
$version = $1;
|
||||
$macros{version} = $version;
|
||||
next;
|
||||
}
|
||||
if ($line =~ /^Source\d*:\s*(\S+)/) {
|
||||
push @sources, $1;
|
||||
next;
|
||||
}
|
||||
if ($line =~ /^Patch\d*:\s*(\S+)/) {
|
||||
push @patches, $1;
|
||||
next;
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
|
||||
$name = expand_macros($name, \%macros);
|
||||
$macros{name} = $name if $name;
|
||||
$version = expand_macros($version, \%macros);
|
||||
$macros{version} = $version if $version;
|
||||
|
||||
@sources = map { normalize_asset(expand_macros($_, \%macros)) } @sources;
|
||||
@patches = map { normalize_asset(expand_macros($_, \%macros)) } @patches;
|
||||
|
||||
my @assets = (@sources, @patches);
|
||||
return ($name, $version, \@sources, \@patches, \@assets);
|
||||
}
|
||||
|
||||
sub expand_macros {
|
||||
my ($text, $macros) = @_;
|
||||
return '' if !defined $text;
|
||||
|
||||
for (1..30) {
|
||||
my $prev = $text;
|
||||
$text =~ s/%\{([^}]+)\}/
|
||||
exists $macros->{lc($1)} ? $macros->{lc($1)} : "%{$1}"
|
||||
/ge;
|
||||
last if $text eq $prev;
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
sub normalize_asset {
|
||||
my ($asset) = @_;
|
||||
$asset //= '';
|
||||
$asset =~ s/^["']//;
|
||||
$asset =~ s/["']$//;
|
||||
$asset =~ s/\?.*$//;
|
||||
|
||||
if ($asset =~ m{^[A-Za-z][A-Za-z0-9+.-]*://}) {
|
||||
$asset =~ s{.*/}{};
|
||||
}
|
||||
$asset =~ s{^\./}{};
|
||||
return $asset;
|
||||
}
|
||||
|
||||
sub print_step {
|
||||
my ($msg) = @_;
|
||||
print "\n== $msg ==\n";
|
||||
}
|
||||
|
||||
sub sh_quote {
|
||||
my ($s) = @_;
|
||||
$s =~ s/'/'"'"'/g;
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $rc = system($cmd);
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub capture {
|
||||
my ($cmd) = @_;
|
||||
print "+ $cmd\n";
|
||||
my $out = `$cmd`;
|
||||
my $rc = $?;
|
||||
if ($rc != 0) {
|
||||
my $exit = $rc == -1 ? 255 : ($rc >> 8);
|
||||
die "Command failed (rc=$exit): $cmd\nOutput:\n$out\n";
|
||||
}
|
||||
chomp $out;
|
||||
return $out;
|
||||
}
|
||||
|
||||
sub run_capture_rc {
|
||||
my ($cmd, $log_file) = @_;
|
||||
my $full = "$cmd > " . sh_quote($log_file) . " 2>&1";
|
||||
print "+ $full\n";
|
||||
my $rc = system($full);
|
||||
return $rc == -1 ? 255 : ($rc >> 8);
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my ($path) = @_;
|
||||
open my $fh, '<', $path or die "Cannot read $path: $!\n";
|
||||
local $/;
|
||||
my $content = <$fh>;
|
||||
close $fh;
|
||||
return $content;
|
||||
}
|
||||
53
syslinux/syslinux-6.03-multibootif.patch
Normal file
53
syslinux/syslinux-6.03-multibootif.patch
Normal file
@@ -0,0 +1,53 @@
|
||||
--- a/com32/mboot/mboot.c 2014-10-06 09:29:01.000000000 -0700
|
||||
+++ b/com32/mboot/mboot.c 2026-03-02 00:00:00.000000000 +0000
|
||||
@@ -93,9 +93,18 @@ static int get_modules(char **argv, struct module_data **mdp)
|
||||
char **argp, **argx;
|
||||
struct module_data *mp;
|
||||
int rv;
|
||||
+ int firstmod = 1;
|
||||
int module_count = 1;
|
||||
int arglen;
|
||||
const char module_separator[] = "---";
|
||||
+ com32sys_t reg;
|
||||
+ const char *bootifstr = "";
|
||||
+
|
||||
+ reg.eax.w[0] = 0x000f; /* Get IPAPPEND strings */
|
||||
+ __intcall(0x22, ®, ®);
|
||||
+ if (!(reg.eflags.l & EFLAGS_CF))
|
||||
+ bootifstr = MK_PTR(reg.es,
|
||||
+ *(uint16_t *)MK_PTR(reg.es, reg.ebx.w[0] + 2));
|
||||
|
||||
for (argp = argv; *argp; argp++) {
|
||||
if (!strcmp(*argp, module_separator))
|
||||
@@ -130,15 +139,29 @@ static int get_modules(char **argv, struct module_data **mdp)
|
||||
arglen += strlen(*argx) + 1;
|
||||
|
||||
if (arglen == 0) {
|
||||
- mp->cmdline = strdup("");
|
||||
+ if (firstmod) {
|
||||
+ firstmod = 0;
|
||||
+ mp->cmdline = strdup(bootifstr);
|
||||
+ } else {
|
||||
+ mp->cmdline = strdup("");
|
||||
+ }
|
||||
} else {
|
||||
char *p;
|
||||
+ if (firstmod)
|
||||
+ arglen += strlen(bootifstr) + 1;
|
||||
+
|
||||
mp->cmdline = p = malloc(arglen);
|
||||
for (; *argp && strcmp(*argp, module_separator); argp++) {
|
||||
p = stpcpy(p, *argp);
|
||||
*p++ = ' ';
|
||||
}
|
||||
- *--p = '\0';
|
||||
+ if (firstmod) {
|
||||
+ firstmod = 0;
|
||||
+ p = stpcpy(p, bootifstr);
|
||||
+ *p = '\0';
|
||||
+ } else {
|
||||
+ *--p = '\0';
|
||||
+ }
|
||||
}
|
||||
mp++;
|
||||
if (*argp)
|
||||
@@ -1,30 +1,34 @@
|
||||
# -*- rpm -*-
|
||||
%define RPMVERSION 3.86
|
||||
%define VERSION 3.86
|
||||
%define RPMVERSION 6.03
|
||||
%define VERSION 6.03
|
||||
Summary: Kernel loader which uses a FAT, ext2/3 or iso9660 filesystem or a PXE network
|
||||
Name: syslinux
|
||||
Version: %{RPMVERSION}
|
||||
Release: 2
|
||||
Release: 1
|
||||
License: GPL
|
||||
Group: System/Boot
|
||||
Source0: ftp://ftp.kernel.org/pub/linux/utils/boot/syslinux/%{name}-%{VERSION}.tar.bz2
|
||||
Patch0: syslinux-3.86-multibootif.patch
|
||||
ExclusiveArch: i386 i486 i586 i686 athlon pentium4 x86_64
|
||||
Source0: https://www.kernel.org/pub/linux/utils/boot/syslinux/%{name}-%{VERSION}.tar.xz
|
||||
Patch0: syslinux-6.03-multibootif.patch
|
||||
ExclusiveArch: i386 i486 i586 i686 athlon pentium4 x86_64 ppc64le
|
||||
Packager: H. Peter Anvin <hpa@zytor.com>
|
||||
Buildroot: %{_tmppath}/%{name}-%{VERSION}-root
|
||||
BuildPrereq: nasm >= 0.98.39, perl
|
||||
Autoreq: 0
|
||||
BuildRequires: mtools, libc.so.6()(64bit)
|
||||
BuildRequires: nasm >= 2.03, perl
|
||||
BuildRequires: mtools, libc.so.6()(64bit), python3
|
||||
BuildRequires: git
|
||||
BuildRequires: libuuid-devel
|
||||
%define my_cc gcc
|
||||
|
||||
# NOTE: extlinux belongs in /sbin, not in /usr/sbin, since it is typically
|
||||
# a system bootloader, and may be necessary for system recovery.
|
||||
%define _sbindir /sbin
|
||||
|
||||
%ifnarch ppc64le
|
||||
%package devel
|
||||
Summary: Development environment for SYSLINUX add-on modules
|
||||
Group: Development/Libraries
|
||||
Requires: syslinux
|
||||
%endif
|
||||
|
||||
%description
|
||||
SYSLINUX is a suite of bootloaders, currently supporting DOS FAT
|
||||
@@ -32,10 +36,12 @@ filesystems, Linux ext2/ext3 filesystems (EXTLINUX), PXE network boots
|
||||
(PXELINUX), or ISO 9660 CD-ROMs (ISOLINUX). It also includes a tool,
|
||||
MEMDISK, which loads legacy operating systems from these media.
|
||||
|
||||
%ifnarch ppc64le
|
||||
%description devel
|
||||
The SYSLINUX boot loader contains an API, called COM32, for writing
|
||||
sophisticated add-on modules. This package contains the libraries
|
||||
necessary to compile such modules.
|
||||
%endif
|
||||
|
||||
%package extlinux
|
||||
Summary: The EXTLINUX bootloader, for booting the local system.
|
||||
@@ -58,24 +64,43 @@ booting in the /opt/xcat/share/xcat/netboot/syslinux directory.
|
||||
%prep
|
||||
%setup -q -n syslinux-%{VERSION}
|
||||
%patch0 -p1
|
||||
# Source tarballs do not include .git metadata; skip submodule refresh in that case.
|
||||
sed -i 's/^[[:space:]]*git submodule update --init$/[ -d .git ] \&\& git submodule update --init || :/' efi/clean-gnu-efi.sh
|
||||
# GCC/glibc compatibility for major()/minor() declarations.
|
||||
sed -i '/#include <sys\/types.h>/a #include <sys/sysmacros.h>' extlinux/main.c
|
||||
# GCC14 strict prototype fix in COM32 syslinux debug helper.
|
||||
sed -i '/#include <stdbool.h>/a #include <stdio.h>' com32/lib/syslinux/debug.c
|
||||
# GCC >= 10 defaults to -fno-common; legacy syslinux code expects common symbols.
|
||||
for f in mk/lib.mk mk/com32.mk mk/elf.mk mk/embedded.mk; do \
|
||||
sed -i '/fno-strict-aliasing/a GCCOPT += $(call gcc_ok,-fcommon,)' "$f"; \
|
||||
done
|
||||
|
||||
%build
|
||||
make CC='%{my_cc}' clean
|
||||
make CC='%{my_cc}' -C com32
|
||||
make CC='%{my_cc}' installer
|
||||
make CC='%{my_cc}' -C sample tidy
|
||||
make CC='%{my_cc}' PYTHON=python3 clean
|
||||
make CC='%{my_cc}' PYTHON=python3 installer
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
make CC='%{my_cc}' install-all \
|
||||
%ifarch ppc64le
|
||||
make CC='%{my_cc}' PYTHON=python3 install \
|
||||
INSTALLROOT=%{buildroot} BINDIR=%{_bindir} SBINDIR=%{_sbindir} \
|
||||
LIBDIR=%{_libdir} DATADIR=%{_datadir} \
|
||||
MANDIR=%{_mandir} INCDIR=%{_includedir} \
|
||||
TFTPBOOT=/opt/xcat/share/xcat/netboot/syslinux EXTLINUXDIR=/boot/extlinux
|
||||
rm %{buildroot}/usr/share/syslinux/dosutil/copybs.com
|
||||
rm %{buildroot}/usr/share/syslinux/dosutil/eltorito.sys
|
||||
rm %{buildroot}/usr/share/syslinux/dosutil/mdiskchk.com
|
||||
make CC='%{my_cc}' -C sample tidy
|
||||
INSTALLSUBDIRS=
|
||||
%else
|
||||
make CC='%{my_cc}' PYTHON=python3 install \
|
||||
INSTALLROOT=%{buildroot} BINDIR=%{_bindir} SBINDIR=%{_sbindir} \
|
||||
LIBDIR=%{_libdir} DATADIR=%{_datadir} \
|
||||
MANDIR=%{_mandir} INCDIR=%{_includedir}
|
||||
%endif
|
||||
make CC='%{my_cc}' PYTHON=python3 netinstall \
|
||||
INSTALLROOT=%{buildroot} TFTPBOOT=/opt/xcat/share/xcat/netboot/syslinux
|
||||
if make -n extbootinstall >/dev/null 2>&1; then \
|
||||
make CC='%{my_cc}' PYTHON=python3 extbootinstall \
|
||||
INSTALLROOT=%{buildroot} EXTLINUXDIR=/boot/extlinux; \
|
||||
else \
|
||||
mkdir -p %{buildroot}/boot/extlinux; \
|
||||
fi
|
||||
mkdir -p %{buildroot}/etc
|
||||
( cd %{buildroot}/etc && ln -s ../boot/extlinux/extlinux.conf . )
|
||||
|
||||
@@ -94,9 +119,17 @@ rm -rf %{buildroot}
|
||||
%{_datadir}/syslinux/*.bin
|
||||
%{_datadir}/syslinux/*.0
|
||||
%{_datadir}/syslinux/memdisk
|
||||
%ifnarch ppc64le
|
||||
%{_datadir}/syslinux/dosutil/*
|
||||
%endif
|
||||
%{_datadir}/syslinux/diag/*
|
||||
%{_datadir}/syslinux/efi32
|
||||
%{_datadir}/syslinux/efi64
|
||||
|
||||
%ifnarch ppc64le
|
||||
%files devel
|
||||
%{_datadir}/syslinux/com32
|
||||
%endif
|
||||
|
||||
%files extlinux
|
||||
%{_sbindir}/extlinux
|
||||
@@ -255,7 +288,7 @@ fi
|
||||
* Wed Jul 12 2000 Prospector <bugzilla@redhat.com>
|
||||
- automatic rebuild
|
||||
|
||||
* Thu Jul 06 2000 Trond Eivind Glomsrød <teg@redhat.com>
|
||||
* Thu Jul 06 2000 Trond Eivind Glomsrod <teg@redhat.com>
|
||||
- use %%{_tmppath}
|
||||
- change application group (Applications/Internet doesn't seem
|
||||
right to me)
|
||||
|
||||
274
xnba/ipxe-binutils-2.41-compat.patch
Normal file
274
xnba/ipxe-binutils-2.41-compat.patch
Normal file
@@ -0,0 +1,274 @@
|
||||
diff -urN xnba-1.21.1/src/arch/x86/core/patch_cf.S xnba-1.21.1.mod/src/arch/x86/core/patch_cf.S
|
||||
--- xnba-1.21.1/src/arch/x86/core/patch_cf.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/core/patch_cf.S 2026-03-02 16:08:49.051016121 -0300
|
||||
@@ -23,8 +23,8 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.code16
|
||||
+ .arch i386
|
||||
|
||||
/****************************************************************************
|
||||
* Set/clear CF on the stack as appropriate, assumes stack is as it should
|
||||
diff -urN xnba-1.21.1/src/arch/x86/core/stack.S xnba-1.21.1.mod/src/arch/x86/core/stack.S
|
||||
--- xnba-1.21.1/src/arch/x86/core/stack.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/core/stack.S 2026-03-02 16:08:49.051016121 -0300
|
||||
@@ -1,6 +1,5 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
- .arch i386
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define STACK_SIZE 8192
|
||||
diff -urN xnba-1.21.1/src/arch/x86/core/stack16.S xnba-1.21.1.mod/src/arch/x86/core/stack16.S
|
||||
--- xnba-1.21.1/src/arch/x86/core/stack16.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/core/stack16.S 2026-03-02 16:08:49.051016121 -0300
|
||||
@@ -1,6 +1,5 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
- .arch i386
|
||||
|
||||
/****************************************************************************
|
||||
* Internal stack
|
||||
diff -urN xnba-1.21.1/src/arch/x86/drivers/net/undiisr.S xnba-1.21.1.mod/src/arch/x86/drivers/net/undiisr.S
|
||||
--- xnba-1.21.1/src/arch/x86/drivers/net/undiisr.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/drivers/net/undiisr.S 2026-03-02 16:08:49.051016121 -0300
|
||||
@@ -11,8 +11,8 @@
|
||||
#define PIC2_ICR 0xa0
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.code16
|
||||
+ .arch i386
|
||||
|
||||
.section ".text16", "ax", @progbits
|
||||
.globl undiisr
|
||||
diff -urN xnba-1.21.1/src/arch/x86/interface/pcbios/e820mangler.S xnba-1.21.1.mod/src/arch/x86/interface/pcbios/e820mangler.S
|
||||
--- xnba-1.21.1/src/arch/x86/interface/pcbios/e820mangler.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/interface/pcbios/e820mangler.S 2026-03-02 16:08:49.051016121 -0300
|
||||
@@ -24,8 +24,8 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.code16
|
||||
+ .arch i386
|
||||
|
||||
#define SMAP 0x534d4150
|
||||
|
||||
diff -urN xnba-1.21.1/src/arch/x86/interface/pxe/pxe_entry.S xnba-1.21.1.mod/src/arch/x86/interface/pxe/pxe_entry.S
|
||||
--- xnba-1.21.1/src/arch/x86/interface/pxe/pxe_entry.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/interface/pxe/pxe_entry.S 2026-03-02 16:08:49.051016121 -0300
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <librm.h>
|
||||
|
||||
- .arch i386
|
||||
|
||||
/****************************************************************************
|
||||
* !PXE structure
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/bootpart.S xnba-1.21.1.mod/src/arch/x86/prefix/bootpart.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/bootpart.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/bootpart.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -6,7 +6,6 @@
|
||||
#define STACK_SIZE 0x2000
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.section ".prefix", "awx", @progbits
|
||||
.code16
|
||||
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/dskprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/dskprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/dskprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/dskprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -25,7 +25,6 @@
|
||||
.equ SYSSEG, 0x1000 /* system loaded at SYSSEG<<4 */
|
||||
|
||||
.org 0
|
||||
- .arch i386
|
||||
.text
|
||||
.section ".prefix", "ax", @progbits
|
||||
.code16
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/exeprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/exeprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/exeprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/exeprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -37,7 +37,6 @@
|
||||
#define PSP_CMDLINE_START 0x81
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.org 0
|
||||
.code16
|
||||
.section ".prefix", "awx", @progbits
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/hdprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/hdprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/hdprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/hdprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <librm.h>
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.section ".prefix", "awx", @progbits
|
||||
.code16
|
||||
.org 0
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/libprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/libprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/libprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/libprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <librm.h>
|
||||
|
||||
- .arch i386
|
||||
|
||||
/* Image compression enabled */
|
||||
#define COMPRESS 1
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/lkrnprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/lkrnprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/lkrnprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/lkrnprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -5,8 +5,8 @@
|
||||
#define BZI_LOAD_HIGH_ADDR 0x100000
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.code16
|
||||
+ .arch i386
|
||||
.section ".prefix", "ax", @progbits
|
||||
.globl _lkrn_start
|
||||
_lkrn_start:
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/mbr.S xnba-1.21.1.mod/src/arch/x86/prefix/mbr.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/mbr.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/mbr.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -1,7 +1,6 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.section ".prefix", "awx", @progbits
|
||||
.code16
|
||||
.org 0
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/mromprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/mromprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/mromprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/mromprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -42,8 +42,8 @@
|
||||
#include "pciromprefix.S"
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.code16
|
||||
+ .arch i386
|
||||
|
||||
/* Obtain access to payload by exposing the expansion ROM BAR at the
|
||||
* address currently used by a suitably large memory BAR on the same
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/nbiprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/nbiprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/nbiprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/nbiprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <librm.h>
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.code16
|
||||
+ .arch i386
|
||||
.section ".prefix", "ax", @progbits
|
||||
.org 0
|
||||
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/nullprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/nullprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/nullprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/nullprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
.org 0
|
||||
.text
|
||||
- .arch i386
|
||||
|
||||
.section ".prefix", "ax", @progbits
|
||||
.code16
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/pxeprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/pxeprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/pxeprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/pxeprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -12,7 +12,6 @@
|
||||
#define PXE_HACK_EB54 0x0001
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.org 0
|
||||
.code16
|
||||
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/rawprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/rawprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/rawprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/rawprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -9,7 +9,6 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.org 0
|
||||
.code16
|
||||
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/romprefix.S xnba-1.21.1.mod/src/arch/x86/prefix/romprefix.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/romprefix.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/romprefix.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -56,7 +56,6 @@
|
||||
|
||||
.text
|
||||
.code16
|
||||
- .arch i386
|
||||
.section ".prefix", "ax", @progbits
|
||||
.globl _rom_start
|
||||
_rom_start:
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/undiloader.S xnba-1.21.1.mod/src/arch/x86/prefix/undiloader.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/undiloader.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/undiloader.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
.text
|
||||
.code16
|
||||
- .arch i386
|
||||
.section ".prefix", "ax", @progbits
|
||||
|
||||
/* UNDI loader
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/unlzma.S xnba-1.21.1.mod/src/arch/x86/prefix/unlzma.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/unlzma.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/unlzma.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -44,7 +44,6 @@
|
||||
*/
|
||||
|
||||
.text
|
||||
- .arch i486
|
||||
.section ".prefix.lib", "ax", @progbits
|
||||
|
||||
#ifdef CODE16
|
||||
diff -urN xnba-1.21.1/src/arch/x86/prefix/usbdisk.S xnba-1.21.1.mod/src/arch/x86/prefix/usbdisk.S
|
||||
--- xnba-1.21.1/src/arch/x86/prefix/usbdisk.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/prefix/usbdisk.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <config/console.h>
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.section ".prefix", "awx", @progbits
|
||||
.code16
|
||||
.org 0
|
||||
diff -urN xnba-1.21.1/src/arch/x86/transitions/liba20.S xnba-1.21.1.mod/src/arch/x86/transitions/liba20.S
|
||||
--- xnba-1.21.1/src/arch/x86/transitions/liba20.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/transitions/liba20.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
- .arch i386
|
||||
|
||||
/****************************************************************************
|
||||
* test_a20_short, test_a20_long
|
||||
diff -urN xnba-1.21.1/src/arch/x86/transitions/libkir.S xnba-1.21.1.mod/src/arch/x86/transitions/libkir.S
|
||||
--- xnba-1.21.1/src/arch/x86/transitions/libkir.S 2021-09-23 14:29:02.000000000 -0300
|
||||
+++ xnba-1.21.1.mod/src/arch/x86/transitions/libkir.S 2026-03-02 16:08:49.054349513 -0300
|
||||
@@ -32,7 +32,6 @@
|
||||
#define BOCHSBP xchgw %bx, %bx
|
||||
|
||||
.text
|
||||
- .arch i386
|
||||
.section ".text16", "awx", @progbits
|
||||
.code16
|
||||
|
||||
@@ -20,6 +20,13 @@ Patch2: ipxe-machyp.patch
|
||||
Patch3: ipxe-xnbaclass.patch
|
||||
Patch4: ipxe-dhcp.patch
|
||||
Patch5: ipxe-verbump.patch
|
||||
Patch6: ipxe-binutils-2.41-compat.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: gcc
|
||||
BuildRequires: binutils
|
||||
BuildRequires: perl
|
||||
BuildRequires: xz-devel
|
||||
|
||||
%description
|
||||
The xCAT Network Boot Agent is a slightly modified version of iPXE. It provides enhanced boot features for any UNDI compliant x86 host. This includes iSCSI, http/ftp downloads, and iPXE script based booting.
|
||||
@@ -32,14 +39,15 @@ The xCAT Network Boot Agent is a slightly modified version of iPXE. It provides
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
|
||||
%build
|
||||
|
||||
rm -rf %{buildroot}
|
||||
|
||||
cd src
|
||||
make bin/undionly.kkpxe
|
||||
make bin-x86_64-efi/snponly.efi
|
||||
make NO_WERROR=1 bin/undionly.kkpxe
|
||||
make NO_WERROR=1 bin-x86_64-efi/snponly.efi
|
||||
|
||||
|
||||
%install
|
||||
|
||||
Reference in New Issue
Block a user