From 20677888fae3877e5d87bd8c88f0feebf38a7aa9 Mon Sep 17 00:00:00 2001 From: Jason Hollis <400979+CodeBleu@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:15:51 -0500 Subject: [PATCH] fix(openbsd): services & build tool * Added net/activator for `ifconfig` that is used with OpenBSD * Added sysvinit scripts for OpenBSD * Updated build-on-openbsd tool with additional dependencies and better logic --- cloudinit/net/activators.py | 28 +++++++++++++++++++++ cloudinit/net/ifconfig.py | 15 +++++++++++ setup.py | 6 +++++ sysvinit/openbsd/cloudconfig.tmpl | 36 +++++++++++++++++++++++++++ sysvinit/openbsd/cloudfinal.tmpl | 34 +++++++++++++++++++++++++ sysvinit/openbsd/cloudinit.tmpl | 34 +++++++++++++++++++++++++ sysvinit/openbsd/cloudinitlocal.tmpl | 37 ++++++++++++++++++++++++++++ tools/build-on-openbsd | 27 ++++++++++++++++---- 8 files changed, 212 insertions(+), 5 deletions(-) create mode 100644 cloudinit/net/ifconfig.py create mode 100755 sysvinit/openbsd/cloudconfig.tmpl create mode 100755 sysvinit/openbsd/cloudfinal.tmpl create mode 100755 sysvinit/openbsd/cloudinit.tmpl create mode 100755 sysvinit/openbsd/cloudinitlocal.tmpl diff --git a/cloudinit/net/activators.py b/cloudinit/net/activators.py index e69da40d371c..e6839f3ec09a 100644 --- a/cloudinit/net/activators.py +++ b/cloudinit/net/activators.py @@ -5,6 +5,7 @@ from cloudinit import subp, util from cloudinit.net.eni import available as eni_available +from cloudinit.net.ifconfig import available as ifconfig_available from cloudinit.net.netplan import available as netplan_available from cloudinit.net.network_manager import available as nm_available from cloudinit.net.network_state import NetworkState @@ -102,6 +103,31 @@ def bring_down_interface(device_name: str) -> bool: return _alter_interface(cmd, device_name) +class IfConfigActivator(NetworkActivator): + @staticmethod + def available(target: Optional[str] = None) -> bool: + """Return true if ifconfig can be used on this system.""" + return ifconfig_available(target=target) + + @staticmethod + def bring_up_interface(device_name: str) -> bool: + """Bring up interface using ifconfig up. + + Return True is successful, otherwise return False + """ + cmd = ["ifconfig", device_name, "up"] + return _alter_interface(cmd, device_name) + + @staticmethod + def bring_down_interface(device_name: str) -> bool: + """Bring up interface using ifconfig down. + + Return True is successful, otherwise return False + """ + cmd = ["ifconfig", device_name, "down"] + return _alter_interface(cmd, device_name) + + class NetworkManagerActivator(NetworkActivator): @staticmethod def available(target=None) -> bool: @@ -217,6 +243,7 @@ def bring_down_interface(device_name: str) -> bool: # version to encompass both seems overkill at this point DEFAULT_PRIORITY = [ "eni", + "ifconfig", "netplan", "network-manager", "networkd", @@ -224,6 +251,7 @@ def bring_down_interface(device_name: str) -> bool: NAME_TO_ACTIVATOR: Dict[str, Type[NetworkActivator]] = { "eni": IfUpDownActivator, + "ifconfig": IfConfigActivator, "netplan": NetplanActivator, "network-manager": NetworkManagerActivator, "networkd": NetworkdActivator, diff --git a/cloudinit/net/ifconfig.py b/cloudinit/net/ifconfig.py new file mode 100644 index 000000000000..b32f816d9604 --- /dev/null +++ b/cloudinit/net/ifconfig.py @@ -0,0 +1,15 @@ +# This file is part of cloud-init. See LICENSE file for license information. + +import logging + +from cloudinit import subp + +LOG = logging.getLogger(__name__) + + +def available(target=None): + expected = ["ifconfig"] + search = ["/sbin"] + if not subp.which(expected, search=search, target=target): + return False + return True diff --git a/setup.py b/setup.py index bff183624988..e40d730e5508 100644 --- a/setup.py +++ b/setup.py @@ -132,6 +132,11 @@ def render_tmpl(template, mode=None, is_yaml=False): for f in glob("sysvinit/netbsd/*") if is_f(f) ], + "sysvinit_openbsd": lambda: [ + render_tmpl(f, mode=0o755) + for f in glob("sysvinit/openbsd/*") + if is_f(f) + ], "sysvinit_deb": lambda: [f for f in glob("sysvinit/debian/*") if is_f(f)], "sysvinit_openrc": lambda: [ f for f in glob("sysvinit/gentoo/*") if is_f(f) @@ -156,6 +161,7 @@ def render_tmpl(template, mode=None, is_yaml=False): "sysvinit": "etc/rc.d/init.d", "sysvinit_freebsd": "usr/local/etc/rc.d", "sysvinit_netbsd": "usr/local/etc/rc.d", + "sysvinit_openbsd": "etc/rc.d", "sysvinit_deb": "etc/init.d", "sysvinit_openrc": "etc/init.d", "systemd": pkg_config_read("systemd", "systemdsystemunitdir"), diff --git a/sysvinit/openbsd/cloudconfig.tmpl b/sysvinit/openbsd/cloudconfig.tmpl new file mode 100755 index 000000000000..091f75f6ede9 --- /dev/null +++ b/sysvinit/openbsd/cloudconfig.tmpl @@ -0,0 +1,36 @@ +## template:jinja +#!/bin/ksh + +# PROVIDE: cloudconfig +# REQUIRE: cloudinit +# BEFORE: sshd + + +daemon="cloud-init" +daemon_execdir="{{prefix}}/bin" +daemon_flags="modules --mode config" +daemon_rtable=0 +daemon_timeout=1 +daemon_user=root + +. /etc/rc.d/rc.subr + +rc_bg="YES" # (undefined or "YES") +rc_usercheck="YES" # (undefined or "NO") + +rc_start() { + test -e /etc/cloud/cloud-init.disabled \ + && warn "cloud-init disabled by cloud-init.disabled file" \ + && exit 0 + rc_exec "${daemon_execdir}/${daemon} ${daemon_flags}" +} + +rc_check() { + pgrep -f "${daemon}" >/dev/null +} + +rc_stop() { + pkill -f "${daemon}" >/dev/null +} + +rc_cmd "$1" diff --git a/sysvinit/openbsd/cloudfinal.tmpl b/sysvinit/openbsd/cloudfinal.tmpl new file mode 100755 index 000000000000..e4ce1a48b95b --- /dev/null +++ b/sysvinit/openbsd/cloudfinal.tmpl @@ -0,0 +1,34 @@ +## template:jinja +#!/bin/ksh + +# PROVIDE: cloudfinal +# REQUIRE: LOGIN cloudconfig + +daemon="cloud-init" +daemon_execdir="{{prefix}}/bin" +daemon_flags="modules --mode final" +daemon_rtable=0 +daemon_timeout=1 +daemon_user=root + +. /etc/rc.d/rc.subr + +rc_bg="YES" # (undefined or "YES") +rc_usercheck="YES" # (undefined or "NO") + +rc_start() { + test -e /etc/cloud/cloud-init.disabled \ + && warn "cloud-init disabled by cloud-init.disabled file" \ + && exit 0 + rc_exec "${daemon_execdir}/${daemon} ${daemon_flags}" +} + +rc_check() { + pgrep -f "${daemon}" >/dev/null +} + +rc_stop() { + pkill -f "${daemon}" >/dev/null +} + +rc_cmd "$1" diff --git a/sysvinit/openbsd/cloudinit.tmpl b/sysvinit/openbsd/cloudinit.tmpl new file mode 100755 index 000000000000..d531d79581ba --- /dev/null +++ b/sysvinit/openbsd/cloudinit.tmpl @@ -0,0 +1,34 @@ +## template:jinja +#!/bin/ksh + +# PROVIDE: cloudinit +# REQUIRE: cloudinitlocal + +daemon="cloud-init" +daemon_execdir="{{prefix}}/bin" +daemon_flags="init" +daemon_rtable=0 +daemon_timeout=1 +daemon_user=root + +. /etc/rc.d/rc.subr + +rc_bg="YES" # (undefined or "YES") +rc_usercheck="YES" # (undefined or "NO") + +rc_start() { + test -e /etc/cloud/cloud-init.disabled \ + && warn "cloud-init disabled by cloud-init.disabled file" \ + && exit 0 + rc_exec "${daemon_execdir}/${daemon} ${daemon_flags}" +} + +rc_check() { + pgrep -f "${daemon}" >/dev/null +} + +rc_stop() { + pkill -f "${daemon}" >/dev/null +} + +rc_cmd "$1" diff --git a/sysvinit/openbsd/cloudinitlocal.tmpl b/sysvinit/openbsd/cloudinitlocal.tmpl new file mode 100755 index 000000000000..0de2ca3d59e4 --- /dev/null +++ b/sysvinit/openbsd/cloudinitlocal.tmpl @@ -0,0 +1,37 @@ +## template:jinja +#!/bin/ksh + +# PROVIDE: cloudinitlocal +# REQUIRE: NETWORKING + +# After NETWORKING because we don't want staticroute to wipe +# the route set by the DHCP client toward the meta-data server. + +daemon="cloud-init" +daemon_execdir="{{prefix}}/bin" +daemon_flags="init -l" +daemon_rtable=0 +daemon_timeout=1 +daemon_user=root + +. /etc/rc.d/rc.subr + +rc_bg="YES" # (undefined or "YES") +rc_usercheck="YES" + +rc_start() { + test -e /etc/cloud/cloud-init.disabled \ + && warn "cloud-init disabled by cloud-init.disabled file" \ + && exit 0 + rc_exec "${daemon_execdir}/${daemon} ${daemon_flags}" +} + +rc_check() { + pgrep -f "${daemon}" >/dev/null +} + +rc_stop() { + pkill -f "${daemon}" >/dev/null +} + +rc_cmd "$1" diff --git a/tools/build-on-openbsd b/tools/build-on-openbsd index fd038afa2d5f..7b647c1ae4c1 100755 --- a/tools/build-on-openbsd +++ b/tools/build-on-openbsd @@ -2,6 +2,12 @@ fail() { echo "FAILED:" "$@" 1>&2; exit 1; } +PYTHON=${PYTHON:-python3} +if [ ! $(which ${PYTHON}) ]; then + echo "Please install python first." + exit 1 +fi + # Check dependencies: depschecked=/tmp/c-i.dependencieschecked pkgs=" @@ -16,12 +22,23 @@ pkgs=" py3-setuptools py3-yaml sudo-- + wget " -[ -f "$depschecked" ] || pkg_add "${pkgs}" || fail "install packages" -touch $depschecked +[ -f $depschecked ] || echo "Installing the following packages: $pkgs"; output=$(pkg_add -zI $pkgs 2>&1) + + +if echo "$output" | grep -q -e "Can't find" -e "Ambiguous"; then + echo "Failed to find or install one or more packages" + echo "Failed Package(s):" + echo "$output" + exit 1 +else + echo Successfully installed packages + touch $depschecked -python3 setup.py build -python3 setup.py install -O1 --distro openbsd --skip-build + python3 setup.py build + python3 setup.py install -O1 --distro openbsd --skip-build --init-system sysvinit_openbsd -echo "Installation completed." + echo "Installation completed." +fi