diff --git a/build-in-container-inner.sh b/build-in-container-inner.sh index 3eef8b08a..2ae3086d8 100755 --- a/build-in-container-inner.sh +++ b/build-in-container-inner.sh @@ -137,14 +137,18 @@ fi run_step "04-configure" "$BASEDIR/buildscripts/build-scripts/configure" run_step "05-compile" "$BASEDIR/buildscripts/build-scripts/compile" run_step "06-package" "$BASEDIR/buildscripts/build-scripts/package" -run_step "07-masterfiles-tarballs" build_masterfiles_tarballs +# Masterfiles tarballs are platform-independent and irrelevant to a Windows MSI +# cross build, which only emits the .msi. Skip them when cross-compiling. +if [ -z "$CROSS_TARGET" ]; then + run_step "07-masterfiles-tarballs" build_masterfiles_tarballs +fi # === Copy output packages === # Packages are created under $BASEDIR// by dpkg-buildpackage / rpmbuild. # Exclude deps-packaging to avoid copying dependency packages. find "$BASEDIR" -maxdepth 4 \ -path "$BASEDIR/buildscripts/deps-packaging" -prune -o \ - \( -name '*.deb' -o -name '*.rpm' -o -name '*.pkg.tar.gz' \) -print \ + \( -name '*.deb' -o -name '*.rpm' -o -name '*.msi' -o -name '*.pkg.tar.gz' \) -print \ -exec cp {} /output/ \; echo "" diff --git a/build-in-container.py b/build-in-container.py index 64b140dee..642070772 100755 --- a/build-in-container.py +++ b/build-in-container.py @@ -298,6 +298,13 @@ def run_container(args, image_tag, source_dir, script_dir): if args.version: cmd.extend(["-e", f"EXPLICIT_VERSION={args.version}"]) + # Cross-compilation target (e.g. x64-mingw for Windows MSI builds). The + # build-scripts derive OS/PACKAGING/ARCH from CROSS_TARGET; an env-set value + # takes precedence over Jenkins label detection. + cross_target = get_config()[args.platform].get("cross_target") + if cross_target: + cmd.extend(["-e", f"CROSS_TARGET={cross_target}"]) + cmd.append(image_tag) if args.shell: @@ -417,6 +424,13 @@ def parse_args(): if not args.build_type: parser.error("missing required argument --build-type") + # Cross-compiled Windows (mingw) builds are always Enterprise agent builds. + if get_config()[args.platform].get("cross_target"): + if args.project != "nova": + parser.error(f"--platform {args.platform} requires --project nova") + if args.role != "agent": + parser.error(f"--platform {args.platform} requires --role agent") + return args @@ -481,6 +495,7 @@ def main(): packages = ( list(output_dir.glob("*.deb")) + list(output_dir.glob("*.rpm")) + + list(output_dir.glob("*.msi")) + list(output_dir.glob("*.tar.gz")) ) if packages: diff --git a/build-scripts/package-msi b/build-scripts/package-msi index fce07d99e..aa75bab81 100755 --- a/build-scripts/package-msi +++ b/build-scripts/package-msi @@ -1,6 +1,6 @@ #!/bin/sh # -# package-msi: Build Windows MSI installer package for CFEngine using WiX Toolset +# package-msi: Build Windows MSI installer package for CFEngine # This script creates a Windows installer (.msi) file for CFEngine Nova # It handles both x86 (32-bit) and x64 (64-bit) architectures @@ -10,57 +10,10 @@ . compile-options . version -# Path where WiX toolset binaries will be installed -WIXPATH="$HOME/wix" - -# Check if WiX tools are installed, install them if not present -log_debug "Checking for WiX tools at $WIXPATH" -if [ -f "$WIXPATH/candle.exe" ] && [ -f "$WIXPATH/light.exe" ]; then - log_debug "WiX tools found - candle.exe and light.exe are present" -else - log_debug "WiX tools not found - starting installation" - ( - # Download prerequisites from build artifacts cache server - cd /tmp || exit - echo ' -get /export/images/windows/wix310-binaries.zip -get /export/images/windows/wine-folder.tar.xz -' | sftp -b - jenkins_sftp_cache@build-artifacts-cache.cloud.cfengine.com - - # Verify downloaded files - sha256sum -c - < "update-binfmts command needed for build-scripts/package-msi script"; diff --git a/ci/fix-buildhost.sh b/ci/fix-buildhost.sh index 1a35098a7..a94f8b77d 100755 --- a/ci/fix-buildhost.sh +++ b/ci/fix-buildhost.sh @@ -73,3 +73,14 @@ if [ -f /etc/os-release ]; then fi fi fi + +# MinGW hosts build the MSI with wixl (build-scripts/package-msi) and inspect it +# with msiinfo (msitools). Installed by the build-host-setup policy at image +# time; install here too so not-yet-reimaged mingw hosts get them without a +# reimage. See ENT-13868. +if [ -f /etc/cfengine-mingw-build-host.flag ]; then + if ! command -v wixl >/dev/null 2>&1 || ! command -v msiinfo >/dev/null 2>&1; then + sudo apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y wixl msitools + fi +fi diff --git a/container/Dockerfile.mingw b/container/Dockerfile.mingw new file mode 100644 index 000000000..380da7d5e --- /dev/null +++ b/container/Dockerfile.mingw @@ -0,0 +1,55 @@ +ARG BASE_IMAGE=ubuntu:24.04 +FROM ${BASE_IMAGE} + +ENV DEBIAN_FRONTEND=noninteractive + +# Build tools extracted from ci/cfengine-build-host-setup.cf (debian|ubuntu section). +# MinGW builds are always Enterprise *agent* builds, so the Node.js/PHP/Composer +# hub tooling from Dockerfile.debian is intentionally omitted here. +RUN apt-get update && apt-get install -y \ + autoconf automake binutils bison build-essential curl debhelper \ + dpkg-dev expat fakeroot flex gdb git libexpat1-dev \ + libmodule-load-conditional-perl libpam0g-dev libtool \ + libncurses6 libncurses-dev \ + pkg-config psmisc python3-pip rsync sudo systemd-coredump unzip wget \ + && rm -rf /var/lib/apt/lists/* + +# MinGW-w64 cross toolchain. Provides x86_64-w64-mingw32-{gcc,g++,...} and the +# Windows runtime DLLs (e.g. /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll) +# that package-msi copies into the MSI. +RUN apt-get update && apt-get install -y \ + mingw-w64 \ + && rm -rf /var/lib/apt/lists/* + +# MSI tooling: wixl (GNOME msitools) builds Windows MSIs natively on Linux - no +# Windows and no Wine, so no i386 architecture is needed. The wixl binary is in +# the separate "wixl" package; "msitools" provides msiinfo/msibuild for +# inspecting the resulting .msi. +RUN apt-get update && apt-get install -y \ + wixl msitools \ + && rm -rf /var/lib/apt/lists/* + +# Remove system dev libraries that conflict with bundled deps +# (from cfengine-build-host-setup.cf lines 53-59) +RUN apt-get purge -y \ + libattr1-dev libssl-dev libpcre2-dev libacl1-dev \ + libyaml-dev libxml2-dev librsync-dev 2>/dev/null || true + +# Rust toolchain and protobuf compiler for building the cargo-based leech2 +# dependency. On mingw hosts leech2 is cross-compiled for Windows, so we also +# install the x86_64-pc-windows-gnu std (linux-install-rust.sh takes the target +# triple as an argument). +COPY --from=ci linux-install-protobuf.sh linux-install-rust.sh /tmp/ +RUN /tmp/linux-install-protobuf.sh +RUN /tmp/linux-install-rust.sh x86_64-pc-windows-gnu + +# Create build user with passwordless sudo (needed by install-dependencies, package, etc.) +RUN useradd -m -s /bin/bash builder \ + && echo "builder ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/builder + +USER builder +WORKDIR /home/builder + +# Pre-create the build directory so that when a named volume is mounted here, +# Docker initializes it with the correct ownership (builder:builder). +RUN mkdir -p /home/builder/build diff --git a/packaging/cfengine-nova/cfengine-nova.wxs b/packaging/cfengine-nova/cfengine-nova.wxs index 272466f73..85f10babd 100644 --- a/packaging/cfengine-nova/cfengine-nova.wxs +++ b/packaging/cfengine-nova/cfengine-nova.wxs @@ -1,193 +1,198 @@ - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + NOT NEWERVERSIONDETECTED - + - - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -240,129 +245,9 @@ - - Generating cryptographic key pair - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - NOT Installed - NOT Installed + NOT Installed - - NOT Installed - NOT Installed diff --git a/platforms.json b/platforms.json index 2aa4836a7..3a4f3c2af 100644 --- a/platforms.json +++ b/platforms.json @@ -75,5 +75,13 @@ "extra_build_args": { "EXTRA_PKGS": "patch" } + }, + "ubuntu-24-mingw": { + "image_name": "cfengine-builder-ubuntu-24-mingw", + "image_version": "latest", + "base_image": "ubuntu:24.04", + "base_image_sha": "sha256:4fbb8e6a8395de5a7550b33509421a2bafbc0aab6c06ba2cef9ebffbc7092d90", + "dockerfile": "Dockerfile.mingw", + "cross_target": "x64-mingw" } }