From 9b073cc18640dd2c3c8f263623fede601352d55e Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Sun, 7 Sep 2025 10:17:40 -0600 Subject: [PATCH] feat(bsd): add FreeBSD support to Meson build Add sysvinit_freebsd support to meson.build to enable generating rc.d scripts from templates and installing into the proper /usr/local/etc/rc.d directory. Update meson_options.txt to limit init_system choices to sysvinit_openrc, systemd or sysvinit_freebsd. Also, update tools/build-on-freebsd to use meson build operations. Update tools/read-dependencies and pkg-deps.json for freebsd support. --- doc/rtd/development/package_testing.rst | 5 ++--- meson.build | 19 +++++++++++++++++ meson_options.txt | 2 +- packages/pkg-deps.json | 11 ++++++++++ tools/build-on-freebsd | 25 +++------------------- tools/read-dependencies | 28 +++++++++++++++++++------ 6 files changed, 58 insertions(+), 32 deletions(-) diff --git a/doc/rtd/development/package_testing.rst b/doc/rtd/development/package_testing.rst index 9097731dbc0..ffca601b5a3 100644 --- a/doc/rtd/development/package_testing.rst +++ b/doc/rtd/development/package_testing.rst @@ -21,6 +21,5 @@ OR if LXD is present, the full package build can be run in a container: ./tools/run-container rockylinux/9 --package --keep -.. note:: - - meson support has not yet been added to the BSDs in :file:`tools/build-on-*bsd` or :file:`meson.build`. +Additionally, :file:`tools/build-on-freebsd` supports build and install +of cloud-init on FreeBSD systems. diff --git a/meson.build b/meson.build index 6dc157d540f..773c136e26a 100644 --- a/meson.build +++ b/meson.build @@ -185,6 +185,25 @@ elif init_system == 'sysvinit_openrc' install_mode: 'rwxr-xr-x', install_tag: 'bin', ) +elif init_system == 'sysvinit_freebsd' + rcd_templates = run_command(find, 'sysvinit/freebsd', '-type', 'f', check: true) + foreach template : rcd_templates.stdout().strip().split('\n') + custom_target( + input: template, + output: '@BASENAME@', + command: [ + render_tmpl, + '@INPUT@', + meson.current_build_dir() / '@OUTPUT@', + ], + install: true, + install_dir: sysconfdir / 'rc.d', + install_mode: 'r-xr-xr-x', + install_tag: 'sysvinit', + ) + endforeach + # Enable cloud-init on reboot + meson.add_install_script('sh', '-c', '/usr/sbin/sysrc cloudinit_enable=YES') endif custom_target( diff --git a/meson_options.txt b/meson_options.txt index 13de1f8cd39..3a7bfb47660 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,4 @@ -option('init_system', type: 'string', value: 'systemd', description: 'Set target init system.') +option('init_system', type: 'combo', value: 'systemd', choices: ['systemd', 'sysvinit_openrc', 'sysvinit_freebsd'], description: 'Set target init system.') option('distro_templates', type: 'array', value: [], description: 'Distro template files to install. WARNING: Templates may change in the future. If using this option, be sure to check new releases for template file changes.') option('disable_sshd_keygen', type: 'boolean', value: false, description: 'Provide systemd service to disable sshd-keygen if present to avoid races with cloud-init.') option('bash_completion', type: 'boolean', value: true, description: 'Bash completion for cloud-init.') diff --git a/packages/pkg-deps.json b/packages/pkg-deps.json index 86c2871442c..2d7b7947307 100644 --- a/packages/pkg-deps.json +++ b/packages/pkg-deps.json @@ -88,6 +88,17 @@ "hostname" ] }, + "freebsd": { + "build-requires" : [ + "bash-completion", + "meson", + "pkgconf" + ], + "requires" : [ + "e2fsprogs", + "sudo" + ] + }, "suse" : { "renames" : { "jinja2" : "python3-Jinja2", diff --git a/tools/build-on-freebsd b/tools/build-on-freebsd index 4fb45e0d632..d7b3e354062 100755 --- a/tools/build-on-freebsd +++ b/tools/build-on-freebsd @@ -15,34 +15,15 @@ if [ ! $(which ${PYTHON}) ]; then echo "Please install python first." exit 1 fi -py_prefix=$(${PYTHON} -c 'import sys; print("py%d%d" % (sys.version_info.major, sys.version_info.minor))') # Check dependencies: depschecked=/tmp/c-i.dependencieschecked -pkgs=" - bash - e2fsprogs - $py_prefix-Jinja2 - $py_prefix-configobj - $py_prefix-jsonpatch - $py_prefix-jsonpointer - $py_prefix-jsonschema - $py_prefix-oauthlib - $py_prefix-requests - $py_prefix-pyserial - $py_prefix-pyyaml - sudo -" -[ -f "$depschecked" ] || pkg install --yes ${pkgs} || fail "install packages" +[ -f "$depschecked" ] || ./tools/read-dependencies --distro freebsd -t || fail "install packages" touch $depschecked # Build the code and install in /usr/local/: -${PYTHON} setup.py build -${PYTHON} setup.py install -O1 --skip-build --prefix /usr/local/ --init-system sysvinit_freebsd - -# Enable cloud-init in /etc/rc.conf: -sed -i.bak -e "/cloudinit_enable=.*/d" /etc/rc.conf -echo 'cloudinit_enable="YES"' >> /etc/rc.conf +meson setup builddir -Dinit_system=sysvinit_freebsd +meson install -C builddir echo "Installation completed." diff --git a/tools/read-dependencies b/tools/read-dependencies index 8f58908df5e..f0e21124c63 100755 --- a/tools/read-dependencies +++ b/tools/read-dependencies @@ -21,11 +21,15 @@ import sys DEFAULT_REQUIREMENTS = "requirements.txt" +DEFAULT_PKG_PREFIX = "python3-" +FREEBSD_PKG_PREFIX = f"py{sys.version_info.major}{sys.version_info.minor}-" + # Map the appropriate package dir needed for each distro choice DISTRO_PKG_TYPE_MAP = { "centos": "redhat", "eurolinux": "redhat", "miraclelinux": "redhat", + "freebsd": "freebsd", "fedora": "fedora", "rocky": "redhat", "redhat": "redhat", @@ -108,31 +112,36 @@ ZYPPER_INSTALL = [ DRYRUN_DISTRO_INSTALL_PKG_CMD = { "redhat": ["yum", "install", "--assumeyes"], "fedora": ["yum", "install", "--assumeyes"], + "freebsd": ["pkg", "install", "--yes"], } DISTRO_INSTALL_PKG_CMD = { "redhat": MAYBE_RELIABLE_YUM_INSTALL, "fedora": MAYBE_RELIABLE_YUM_INSTALL, + "freebsd": ["pkg", "install", "--yes"], "debian": ["apt", "install", "-y"], "suse": ZYPPER_INSTALL, } DISTRO_UPDATE_PKG_CMD = { "redhat": ["yum", "update"], + "freebsd": ["pkg", "update"], "debian": ["apt", "update", "-q"], "suse": ["zypper", "update"], } # List of base system packages required to enable ci automation CI_SYSTEM_BASE_PKGS = { - "common": ["make", "sudo", "tar"], + "common": ["sudo"], + "linux_common": ["make", "tar"], "eurolinux": ["python3-tox"], "miraclelinux": ["python3-tox"], "fedora": ["python3-tox"], + "freebsd": [f"{FREEBSD_PKG_PREFIX}tox"], "redhat": ["python3-tox"], "centos": ["python3-tox"], - "ubuntu": ["devscripts", "python3-dev", "libssl-dev", "tox", "sbuild"], - "debian": ["devscripts", "python3-dev", "libssl-dev", "tox", "sbuild"], + "ubuntu": ["make", "devscripts", "python3-dev", "libssl-dev", "tox", "sbuild"], + "debian": ["make", "devscripts", "python3-dev", "libssl-dev", "tox", "sbuild"], } @@ -252,14 +261,17 @@ def parse_pip_requirements(requirements_path): return dep_names -def translate_pip_to_system_pkg(pip_requires, renames): +def translate_pip_to_system_pkg(distro, pip_requires, renames): """Translate pip package names to distro-specific package names. @param pip_requires: List of versionless pip package names to translate. @param renames: Dict containing special case renames from pip name to system package name for the distro. """ - prefix = "python3-" + if distro in ("freebsd",): + prefix = FREEBSD_PKG_PREFIX + else: + prefix = DEFAULT_PKG_PREFIX standard_pkg_name = "{0}{1}" translated_names = [] for pip_name in pip_requires: @@ -315,7 +327,9 @@ def main(distro): pip_pkg_names.update(set(parse_pip_requirements(req_path))) deps_from_json = get_package_deps_from_json(topd, args.distro) renames = deps_from_json.get("renames", {}) - translated_pip_names = translate_pip_to_system_pkg(pip_pkg_names, renames) + translated_pip_names = translate_pip_to_system_pkg( + args.distro, pip_pkg_names, renames + ) all_deps = [] select_requires = [args.build_requires, args.runtime_requires] if args.distro: @@ -348,6 +362,8 @@ def pkg_install(pkg_list, distro, test_distro=False, dry_run=False): """Install a list of packages using the DISTRO_INSTALL_PKG_CMD.""" if test_distro: pkg_list = list(pkg_list) + CI_SYSTEM_BASE_PKGS["common"] + if distro not in ("freebsd",): + pkg_list += CI_SYSTEM_BASE_PKGS["linux_common"] distro_base_pkgs = CI_SYSTEM_BASE_PKGS.get(distro, []) pkg_list += distro_base_pkgs print(