summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--cloudinit/config/cc_growpart.py4
-rw-r--r--cloudinit/config/cc_resizefs.py5
-rw-r--r--cloudinit/distros/dragonflybsd.py12
-rw-r--r--cloudinit/distros/freebsd.py15
-rw-r--r--cloudinit/net/__init__.py6
-rw-r--r--cloudinit/net/freebsd.py11
-rw-r--r--cloudinit/util.py46
-rw-r--r--config/cloud.cfg.tmpl22
-rw-r--r--doc/rtd/topics/availability.rst5
-rwxr-xr-xsetup.py2
-rwxr-xr-xsysvinit/freebsd/cloudinit2
-rw-r--r--tests/unittests/test_distros/test_dragonflybsd.py25
-rw-r--r--tests/unittests/test_util.py18
14 files changed, 157 insertions, 18 deletions
diff --git a/README.md b/README.md
index c382b592..02b2f666 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@ get in contact with that distribution and send them our way!
| Supported OSes | Supported Public Clouds | Supported Private Clouds |
| --- | --- | --- |
-| Alpine Linux<br />ArchLinux<br />Debian<br />Fedora<br />FreeBSD<br />Gentoo Linux<br />NetBSD<br />OpenBSD<br />RHEL/CentOS/AlmaLinux/Rocky<br />SLES/openSUSE<br />Ubuntu<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> | Amazon Web Services<br />Microsoft Azure<br />Google Cloud Platform<br />Oracle Cloud Infrastructure<br />Softlayer<br />Rackspace Public Cloud<br />IBM Cloud<br />Digital Ocean<br />Bigstep<br />Hetzner<br />Joyent<br />CloudSigma<br />Alibaba Cloud<br />OVH<br />OpenNebula<br />Exoscale<br />Scaleway<br />CloudStack<br />AltCloud<br />SmartOS<br />HyperOne<br />Vultr<br />Rootbox<br /> | Bare metal installs<br />OpenStack<br />LXD<br />KVM<br />Metal-as-a-Service (MAAS)<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />|
+| Alpine Linux<br />ArchLinux<br />Debian<br />DragonFlyBSD<br />Fedora<br />FreeBSD<br />Gentoo Linux<br />NetBSD<br />OpenBSD<br />RHEL/CentOS/AlmaLinux/Rocky<br />SLES/openSUSE<br />Ubuntu<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> | Amazon Web Services<br />Microsoft Azure<br />Google Cloud Platform<br />Oracle Cloud Infrastructure<br />Softlayer<br />Rackspace Public Cloud<br />IBM Cloud<br />Digital Ocean<br />Bigstep<br />Hetzner<br />Joyent<br />CloudSigma<br />Alibaba Cloud<br />OVH<br />OpenNebula<br />Exoscale<br />Scaleway<br />CloudStack<br />AltCloud<br />SmartOS<br />HyperOne<br />Vultr<br />Rootbox<br /> | Bare metal installs<br />OpenStack<br />LXD<br />KVM<br />Metal-as-a-Service (MAAS)<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />|
## To start developing cloud-init
diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py
index 9f338ad1..9f5525a1 100644
--- a/cloudinit/config/cc_growpart.py
+++ b/cloudinit/config/cc_growpart.py
@@ -224,6 +224,10 @@ def device_part_info(devpath):
freebsd_part = "/dev/" + util.find_freebsd_part(devpath)
m = re.search('^(/dev/.+)p([0-9])$', freebsd_part)
return (m.group(1), m.group(2))
+ elif util.is_DragonFlyBSD():
+ dragonflybsd_part = "/dev/" + util.find_dragonflybsd_part(devpath)
+ m = re.search('^(/dev/.+)s([0-9])$', dragonflybsd_part)
+ return (m.group(1), m.group(2))
if not os.path.exists(syspath):
raise ValueError("%s had no syspath (%s)" % (devpath, syspath))
diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py
index 9afbb847..990a6939 100644
--- a/cloudinit/config/cc_resizefs.py
+++ b/cloudinit/config/cc_resizefs.py
@@ -85,6 +85,10 @@ def _resize_zfs(mount_point, devpth):
return ('zpool', 'online', '-e', mount_point, devpth)
+def _resize_hammer2(mount_point, devpth):
+ return ('hammer2', 'growfs', mount_point)
+
+
def _can_skip_resize_ufs(mount_point, devpth):
# possible errors cases on the code-path to growfs -N following:
# https://github.com/freebsd/freebsd/blob/HEAD/sbin/growfs/growfs.c
@@ -113,6 +117,7 @@ RESIZE_FS_PREFIXES_CMDS = [
('xfs', _resize_xfs),
('ufs', _resize_ufs),
('zfs', _resize_zfs),
+ ('hammer2', _resize_hammer2),
]
RESIZE_FS_PRECHECK_CMDS = {
diff --git a/cloudinit/distros/dragonflybsd.py b/cloudinit/distros/dragonflybsd.py
new file mode 100644
index 00000000..2d825518
--- /dev/null
+++ b/cloudinit/distros/dragonflybsd.py
@@ -0,0 +1,12 @@
+# Copyright (C) 2020-2021 Gonéri Le Bouder
+#
+# This file is part of cloud-init. See LICENSE file for license information.
+
+import cloudinit.distros.freebsd
+
+
+class Distro(cloudinit.distros.freebsd.Distro):
+ home_dir = '/home'
+
+
+# vi: ts=4 expandtab
diff --git a/cloudinit/distros/freebsd.py b/cloudinit/distros/freebsd.py
index 9659843f..d94a52b8 100644
--- a/cloudinit/distros/freebsd.py
+++ b/cloudinit/distros/freebsd.py
@@ -18,6 +18,12 @@ LOG = logging.getLogger(__name__)
class Distro(cloudinit.distros.bsd.BSD):
+ """
+ Distro subclass for FreeBSD.
+
+ (N.B. DragonFlyBSD inherits from this class.)
+ """
+
usr_lib_exec = '/usr/local/lib'
login_conf_fn = '/etc/login.conf'
login_conf_fn_bak = '/etc/login.conf.orig'
@@ -28,6 +34,7 @@ class Distro(cloudinit.distros.bsd.BSD):
pkg_cmd_update_prefix = ["pkg", "update"]
pkg_cmd_upgrade_prefix = ["pkg", "upgrade"]
prefer_fqdn = True # See rc.conf(5) in FreeBSD
+ home_dir = '/usr/home'
def _get_add_member_to_group_cmd(self, member_name, group_name):
return ['pw', 'usermod', '-n', member_name, '-G', group_name]
@@ -66,9 +73,12 @@ class Distro(cloudinit.distros.bsd.BSD):
pw_useradd_cmd.append('-d/nonexistent')
log_pw_useradd_cmd.append('-d/nonexistent')
else:
- pw_useradd_cmd.append('-d/usr/home/%s' % name)
+ pw_useradd_cmd.append('-d{home_dir}/{name}'.format(
+ home_dir=self.home_dir, name=name))
pw_useradd_cmd.append('-m')
- log_pw_useradd_cmd.append('-d/usr/home/%s' % name)
+ log_pw_useradd_cmd.append('-d{home_dir}/{name}'.format(
+ home_dir=self.home_dir, name=name))
+
log_pw_useradd_cmd.append('-m')
# Run the command
@@ -155,4 +165,5 @@ class Distro(cloudinit.distros.bsd.BSD):
"update-sources", self.package_command,
["update"], freq=PER_INSTANCE)
+
# vi: ts=4 expandtab
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index 6b3b84f7..b827d41a 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -351,7 +351,7 @@ def device_devid(devname):
def get_devicelist():
- if util.is_FreeBSD():
+ if util.is_FreeBSD() or util.is_DragonFlyBSD():
return list(get_interfaces_by_mac().values())
try:
@@ -376,7 +376,7 @@ def is_disabled_cfg(cfg):
def find_fallback_nic(blacklist_drivers=None):
"""Return the name of the 'fallback' network device."""
- if util.is_FreeBSD():
+ if util.is_FreeBSD() or util.is_DragonFlyBSD():
return find_fallback_nic_on_freebsd(blacklist_drivers)
elif util.is_NetBSD() or util.is_OpenBSD():
return find_fallback_nic_on_netbsd_or_openbsd(blacklist_drivers)
@@ -816,7 +816,7 @@ def get_ib_interface_hwaddr(ifname, ethernet_format):
def get_interfaces_by_mac(blacklist_drivers=None) -> dict:
- if util.is_FreeBSD():
+ if util.is_FreeBSD() or util.is_DragonFlyBSD():
return get_interfaces_by_mac_on_freebsd(
blacklist_drivers=blacklist_drivers)
elif util.is_NetBSD():
diff --git a/cloudinit/net/freebsd.py b/cloudinit/net/freebsd.py
index c843d792..f8faf240 100644
--- a/cloudinit/net/freebsd.py
+++ b/cloudinit/net/freebsd.py
@@ -32,6 +32,13 @@ class Renderer(cloudinit.net.bsd.BSDRenderer):
LOG.debug("freebsd generate postcmd disabled")
return
+ for dhcp_interface in self.dhcp_interfaces():
+ # Observed on DragonFlyBSD 6. If we use the "restart" parameter,
+ # the routes are not recreated.
+ subp.subp(['service', 'dhclient', 'stop', dhcp_interface],
+ rcs=[0, 1],
+ capture=True)
+
subp.subp(['service', 'netif', 'restart'], capture=True)
# On FreeBSD 10, the restart of routing and dhclient is likely to fail
# because
@@ -42,7 +49,7 @@ class Renderer(cloudinit.net.bsd.BSDRenderer):
subp.subp(['service', 'routing', 'restart'], capture=True, rcs=[0, 1])
for dhcp_interface in self.dhcp_interfaces():
- subp.subp(['service', 'dhclient', 'restart', dhcp_interface],
+ subp.subp(['service', 'dhclient', 'start', dhcp_interface],
rcs=[0, 1],
capture=True)
@@ -57,4 +64,4 @@ class Renderer(cloudinit.net.bsd.BSDRenderer):
def available(target=None):
- return util.is_FreeBSD()
+ return util.is_FreeBSD() or util.is_DragonFlyBSD()
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 2de1123e..f95dc435 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -392,7 +392,11 @@ def is_Linux():
@lru_cache()
def is_BSD():
- return 'BSD' in platform.system()
+ if 'BSD' in platform.system():
+ return True
+ if platform.system() == 'DragonFly':
+ return True
+ return False
@lru_cache()
@@ -401,6 +405,11 @@ def is_FreeBSD():
@lru_cache()
+def is_DragonFlyBSD():
+ return system_info()['variant'] == "dragonfly"
+
+
+@lru_cache()
def is_NetBSD():
return system_info()['variant'] == "netbsd"
@@ -534,7 +543,9 @@ def system_info():
var = 'suse'
else:
var = 'linux'
- elif system in ('windows', 'darwin', "freebsd", "netbsd", "openbsd"):
+ elif system in (
+ 'windows', 'darwin', "freebsd", "netbsd",
+ "openbsd", "dragonfly"):
var = system
info['variant'] = var
@@ -1195,6 +1206,23 @@ def find_devs_with_openbsd(criteria=None, oformat='device',
return ['/dev/' + i for i in devlist]
+def find_devs_with_dragonflybsd(criteria=None, oformat='device',
+ tag=None, no_cache=False, path=None):
+ out, _err = subp.subp(['sysctl', '-n', 'kern.disks'], rcs=[0])
+ devlist = [i for i in sorted(out.split(), reverse=True)
+ if not i.startswith("md") and not i.startswith("vn")]
+
+ if criteria == "TYPE=iso9660":
+ devlist = [i for i in devlist
+ if i.startswith('cd') or i.startswith('acd')]
+ elif criteria in ["LABEL=CONFIG-2", "TYPE=vfat"]:
+ devlist = [i for i in devlist
+ if not (i.startswith('cd') or i.startswith('acd'))]
+ elif criteria:
+ LOG.debug("Unexpected criteria: %s", criteria)
+ return ['/dev/' + i for i in devlist]
+
+
def find_devs_with(criteria=None, oformat='device',
tag=None, no_cache=False, path=None):
"""
@@ -1213,6 +1241,9 @@ def find_devs_with(criteria=None, oformat='device',
elif is_OpenBSD():
return find_devs_with_openbsd(criteria, oformat,
tag, no_cache, path)
+ elif is_DragonFlyBSD():
+ return find_devs_with_dragonflybsd(criteria, oformat,
+ tag, no_cache, path)
blk_id_cmd = ['blkid']
options = []
@@ -2211,6 +2242,14 @@ def find_freebsd_part(fs):
LOG.warning("Unexpected input in find_freebsd_part: %s", fs)
+def find_dragonflybsd_part(fs):
+ splitted = fs.split('/')
+ if len(splitted) == 3 and splitted[1] == 'dev':
+ return splitted[2]
+ else:
+ LOG.warning("Unexpected input in find_dragonflybsd_part: %s", fs)
+
+
def get_path_dev_freebsd(path, mnt_list):
path_found = None
for line in mnt_list.split("\n"):
@@ -2264,6 +2303,9 @@ def parse_mount(path):
# https://regex101.com/r/T2en7a/1
regex = (r'^(/dev/[\S]+|.*zroot\S*?) on (/[\S]*) '
r'(?=(?:type)[\s]+([\S]+)|\(([^,]*))')
+ if is_DragonFlyBSD():
+ regex = (r'^(/dev/[\S]+|\S*?) on (/[\S]*) '
+ r'(?=(?:type)[\s]+([\S]+)|\(([^,]*))')
for line in mount_locs:
m = re.search(regex, line)
if not m:
diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
index 2f6c3a7d..586384e4 100644
--- a/config/cloud.cfg.tmpl
+++ b/config/cloud.cfg.tmpl
@@ -1,8 +1,8 @@
## template:jinja
# The top level settings are used as module
# and system configuration.
-
-{% if variant.endswith("bsd") %}
+{% set is_bsd = variant in ["dragonfly", "freebsd", "netbsd", "openbsd"] %}
+{% if is_bsd %}
syslog_fix_perms: root:wheel
{% elif variant in ["suse"] %}
syslog_fix_perms: root:root
@@ -61,11 +61,11 @@ cloud_init_modules:
{% endif %}
- bootcmd
- write-files
-{% if variant not in ["netbsd"] %}
+{% if variant not in ["netbsd", "openbsd"] %}
- growpart
- resizefs
{% endif %}
-{% if variant not in ["freebsd", "netbsd"] %}
+{% if not is_bsd %}
- disk_setup
- mounts
{% endif %}
@@ -158,6 +158,8 @@ system_info:
"fedora", "freebsd", "netbsd", "openbsd", "rhel", "rocky",
"suse", "ubuntu"] %}
distro: {{ variant }}
+{% elif variant in ["dragonfly"] %}
+ distro: dragonflybsd
{% else %}
# Unknown/fallback distro.
distro: ubuntu
@@ -249,6 +251,15 @@ system_info:
groups: [wheel]
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
shell: /bin/tcsh
+{% elif variant in ["dragonfly"] %}
+ # Default user name + that default users groups (if added/used)
+ default_user:
+ name: dragonfly
+ lock_passwd: True
+ gecos: DragonFly
+ groups: [wheel]
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
+ shell: /bin/sh
{% elif variant in ["netbsd"] %}
default_user:
name: netbsd
@@ -269,4 +280,7 @@ system_info:
{% if variant in ["freebsd", "netbsd", "openbsd"] %}
network:
renderers: ['{{ variant }}']
+{% elif variant in ["dragonfly"] %}
+ network:
+ renderers: ['freebsd']
{% endif %}
diff --git a/doc/rtd/topics/availability.rst b/doc/rtd/topics/availability.rst
index f3e13edc..e4480754 100644
--- a/doc/rtd/topics/availability.rst
+++ b/doc/rtd/topics/availability.rst
@@ -14,12 +14,13 @@ distributions and clouds, both public and private.
Distributions
=============
-Cloud-init has support across all major Linux distributions, FreeBSD, NetBSD
-and OpenBSD:
+Cloud-init has support across all major Linux distributions, FreeBSD, NetBSD,
+OpenBSD and DragonFlyBSD:
- Alpine Linux
- ArchLinux
- Debian
+- DragonFlyBSD
- Fedora
- FreeBSD
- Gentoo Linux
diff --git a/setup.py b/setup.py
index cbacf48e..dcbe0843 100755
--- a/setup.py
+++ b/setup.py
@@ -156,7 +156,7 @@ USR = "usr"
ETC = "etc"
USR_LIB_EXEC = "usr/lib"
LIB = "lib"
-if os.uname()[0] == 'FreeBSD':
+if os.uname()[0] in ['FreeBSD', 'DragonFly']:
USR = "usr/local"
USR_LIB_EXEC = "usr/local/lib"
elif os.path.isfile('/etc/redhat-release'):
diff --git a/sysvinit/freebsd/cloudinit b/sysvinit/freebsd/cloudinit
index aa5bd118..d26f3d0f 100755
--- a/sysvinit/freebsd/cloudinit
+++ b/sysvinit/freebsd/cloudinit
@@ -2,7 +2,7 @@
# PROVIDE: cloudinit
# REQUIRE: FILESYSTEMS NETWORKING cloudinitlocal ldconfig devd
-# BEFORE: cloudconfig cloudfinal
+# BEFORE: LOGIN cloudconfig cloudfinal
. /etc/rc.subr
diff --git a/tests/unittests/test_distros/test_dragonflybsd.py b/tests/unittests/test_distros/test_dragonflybsd.py
new file mode 100644
index 00000000..df2c00f4
--- /dev/null
+++ b/tests/unittests/test_distros/test_dragonflybsd.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+
+
+import cloudinit.util
+from cloudinit.tests.helpers import mock
+
+
+def test_find_dragonflybsd_part():
+ assert cloudinit.util.find_dragonflybsd_part("/dev/vbd0s3") == "vbd0s3"
+
+
+@mock.patch("cloudinit.util.is_DragonFlyBSD")
+@mock.patch("cloudinit.subp.subp")
+def test_parse_mount(mock_subp, m_is_DragonFlyBSD):
+ mount_out = """
+vbd0s3 on / (hammer2, local)
+devfs on /dev (devfs, nosymfollow, local)
+/dev/vbd0s0a on /boot (ufs, local)
+procfs on /proc (procfs, local)
+tmpfs on /var/run/shm (tmpfs, local)
+"""
+
+ mock_subp.return_value = (mount_out, "")
+ m_is_DragonFlyBSD.return_value = True
+ assert cloudinit.util.parse_mount("/") == ("vbd0s3", "hammer2", "/")
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index e5292001..2290cab7 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -999,4 +999,22 @@ class TestFindDevs:
devlist = util.find_devs_with_netbsd(criteria=criteria)
assert devlist == expected_devlist
+ @pytest.mark.parametrize(
+ 'criteria,expected_devlist', (
+ (None, ['/dev/vbd0', '/dev/cd0', '/dev/acd0']),
+ ('TYPE=iso9660', ['/dev/cd0', '/dev/acd0']),
+ ('TYPE=vfat', ['/dev/vbd0']),
+ ('LABEL_FATBOOT=A_LABEL', # lp: #1841466
+ ['/dev/vbd0', '/dev/cd0', '/dev/acd0']),
+ )
+ )
+ @mock.patch("cloudinit.subp.subp")
+ def test_find_devs_with_dragonflybsd(self, m_subp, criteria,
+ expected_devlist):
+ m_subp.return_value = (
+ 'md2 md1 cd0 vbd0 acd0 vn3 vn2 vn1 vn0 md0', ''
+ )
+ devlist = util.find_devs_with_dragonflybsd(criteria=criteria)
+ assert devlist == expected_devlist
+
# vi: ts=4 expandtab