Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions cloudinit/config/cc_install_hotplug.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@


HOTPLUG_UDEV_PATH = "/etc/udev/rules.d/10-cloud-init-hook-hotplug.rules"
HOTPLUG_UDEV_RULES = """\
HOTPLUG_UDEV_RULES_TEMPLATE = """\
# Installed by cloud-init due to network hotplug userdata
ACTION!="add|remove", GOTO="cloudinit_end"
LABEL="cloudinit_hook"
SUBSYSTEM=="net", RUN+="/usr/lib/cloud-init/hook-hotplug"
SUBSYSTEM=="net", RUN+="{libexecdir}/hook-hotplug"
LABEL="cloudinit_end"
"""

Expand Down Expand Up @@ -129,8 +129,12 @@ def handle(_name, cfg, cloud, log, _args):
log.debug("Skipping hotplug install, udevadm not found")
return

# This may need to turn into a distro property at some point
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 I'm good with this approach. Checking /usr/libexec dir first would allow us to prefer that on distros that have installed cloud-init to that path.

libexecdir = "/usr/libexec/cloud-init"
if not os.path.exists(libexecdir):
libexecdir = "/usr/lib/cloud-init"
util.write_file(
filename=HOTPLUG_UDEV_PATH,
content=HOTPLUG_UDEV_RULES,
content=HOTPLUG_UDEV_RULES_TEMPLATE.format(libexecdir=libexecdir),
)
subp.subp(["udevadm", "control", "--reload-rules"])
1 change: 1 addition & 0 deletions cloudinit/sources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
EventType.BOOT_NEW_INSTANCE,
EventType.BOOT,
EventType.BOOT_LEGACY,
EventType.HOTPLUG,
}}
default_update_events = {EventScope.NETWORK: {
EventType.BOOT_NEW_INSTANCE,
Expand Down
7 changes: 0 additions & 7 deletions packages/redhat/cloud-init.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,6 @@ version_pys=$(cd "$RPM_BUILD_ROOT" && find . -name version.py -type f)
( cd "$RPM_BUILD_ROOT" &&
sed -i "s,@@PACKAGED_VERSION@@,%{version}-%{release}," $version_pys )

# patch hotplug /usr/libexec script path
hotplug_file=$(cd "$RPM_BUILD_ROOT" && find . -name 10-cloud-init-hook-hotplug.rules -type f)

( cd "$RPM_BUILD_ROOT" &&
sed -i "s,/usr/lib,%{_libexecdir}," $hotplug_file )

%clean
rm -rf $RPM_BUILD_ROOT

Expand Down Expand Up @@ -178,7 +172,6 @@ fi
%files

/lib/udev/rules.d/66-azure-ephemeral.rules
/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules

%if "%{init_system}" == "systemd"
/usr/lib/systemd/system-generators/cloud-init-generator
Expand Down
10 changes: 8 additions & 2 deletions tests/unittests/test_datasource/test_ovf.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,10 +518,16 @@ def test_get_data_vmware_seed_platform_info(self):
'vmware (%s/seed/ovf-env.xml)' % self.tdir,
ds.subplatform)

def test_get_data_vmware_guestinfo_with_network_config(self):
@mock.patch('cloudinit.subp.subp')
@mock.patch('cloudinit.sources.DataSource.persist_instance_data')
def test_get_data_vmware_guestinfo_with_network_config(
self, m_persist, m_subp
):
self._test_get_data_with_network_config(guestinfo=False, iso=True)

def test_get_data_iso9660_with_network_config(self):
@mock.patch('cloudinit.subp.subp')
@mock.patch('cloudinit.sources.DataSource.persist_instance_data')
def test_get_data_iso9660_with_network_config(self, m_persist, m_subp):
self._test_get_data_with_network_config(guestinfo=True, iso=False)

def _test_get_data_with_network_config(self, guestinfo, iso):
Expand Down
23 changes: 16 additions & 7 deletions tests/unittests/test_handler/test_handler_install_hotplug.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from cloudinit.config.cc_install_hotplug import (
handle,
HOTPLUG_UDEV_PATH,
HOTPLUG_UDEV_RULES,
HOTPLUG_UDEV_RULES_TEMPLATE,
)
from cloudinit.event import EventScope, EventType

Expand Down Expand Up @@ -38,19 +38,28 @@ def mocks():


class TestInstallHotplug:
def test_rules_installed_when_supported_and_enabled(self, mocks):
@pytest.mark.parametrize('libexec_exists', [True, False])
def test_rules_installed_when_supported_and_enabled(
self, mocks, libexec_exists
):
mocks.m_which.return_value = 'udevadm'
mocks.m_update_enabled.return_value = True
m_cloud = mock.MagicMock()
m_cloud.datasource.get_supported_events.return_value = {
EventScope.NETWORK: {EventType.HOTPLUG}
}

handle(None, {}, m_cloud, mock.Mock(), None)
mocks.m_write.assert_called_once_with(
filename=HOTPLUG_UDEV_PATH,
content=HOTPLUG_UDEV_RULES,
)
if libexec_exists:
libexecdir = "/usr/libexec/cloud-init"
else:
libexecdir = "/usr/lib/cloud-init"
with mock.patch('os.path.exists', return_value=libexec_exists):
handle(None, {}, m_cloud, mock.Mock(), None)
mocks.m_write.assert_called_once_with(
filename=HOTPLUG_UDEV_PATH,
content=HOTPLUG_UDEV_RULES_TEMPLATE.format(
libexecdir=libexecdir),
)
assert mocks.m_subp.call_args_list == [mock.call([
'udevadm', 'control', '--reload-rules',
])]
Expand Down