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
19 changes: 0 additions & 19 deletions cloudinit/config/cc_snap.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,23 +182,6 @@ def run_commands(commands):
raise RuntimeError(msg)


# RELEASE_BLOCKER: Once LP: #1628289 is released on xenial, drop this function.
def maybe_install_squashfuse(cloud):
"""Install squashfuse if we are in a container."""
if not util.is_container():
return
try:
cloud.distro.update_package_sources()
except Exception:
util.logexc(LOG, "Package update failed")
raise
try:
cloud.distro.install_packages(["squashfuse"])
except Exception:
util.logexc(LOG, "Failed to install squashfuse")
raise


def handle(name, cfg, cloud, log, args):
cfgin = cfg.get("snap", {})
if not cfgin:
Expand All @@ -207,8 +190,6 @@ def handle(name, cfg, cloud, log, args):
)
return

if util.is_true(cfgin.get("squashfuse_in_container", False)):
maybe_install_squashfuse(cloud)
add_assertions(cfgin.get("assertions", []))
run_commands(cfgin.get("commands", []))

Expand Down
5 changes: 0 additions & 5 deletions cloudinit/config/cloud-init-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1819,11 +1819,6 @@
{"type": "array", "items": {"type": "string"}}
]
}
},
"squashfuse_in_container": {
"type": "boolean",
"default": false,
"description": "DEPRECATED: This key is no longer needed and will be removed in a future version of cloud-init."
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I guess the moment to drop it is now. Do we have to explicitly say something in the changelog or something else? Or should we keep this for backward compatibility?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'll let others weigh in here too, but I'm ok dropping it completely since the docs always specified development only.

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.

I think we are clear enough here to drop. It was an optional thing to use in containers until about 2018 with snapd version 2.32.3.1. It is unnecessary and anybody using this config option doesn't really need to anymore. The workaround if someone really wanted to install squashfuse in a container would be to provide packages: [squashfuse] in #cloud-config if necessary for their appllication (which it shouldn't be).

}
}
}
Expand Down
1 change: 0 additions & 1 deletion tests/integration_tests/modules/test_combined.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
- #
- logger "My test log"
snap:
squashfuse_in_container: true
commands:
- snap install hello-world
ssh_import_id:
Expand Down
113 changes: 0 additions & 113 deletions tests/unittests/config/test_cc_snap.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
ASSERTIONS_FILE,
add_assertions,
handle,
maybe_install_squashfuse,
run_commands,
)
from cloudinit.config.schema import (
Expand Down Expand Up @@ -348,62 +347,6 @@ def setUp(self):
super(TestHandle, self).setUp()
self.tmp = self.tmp_dir()

@mock.patch("cloudinit.config.cc_snap.run_commands")
@mock.patch("cloudinit.config.cc_snap.add_assertions")
@mock.patch("cloudinit.config.cc_snap.maybe_install_squashfuse")
def test_handle_skips_squashfuse_when_unconfigured(
self, m_squash, m_add, m_run
):
"""When squashfuse_in_container is unset, don't attempt to install."""
handle(
"snap", cfg={"snap": {}}, cloud=None, log=self.logger, args=None
)
handle(
"snap",
cfg={"snap": {"squashfuse_in_container": None}},
cloud=None,
log=self.logger,
args=None,
)
handle(
"snap",
cfg={"snap": {"squashfuse_in_container": False}},
cloud=None,
log=self.logger,
args=None,
)
self.assertEqual([], m_squash.call_args_list) # No calls
# snap configuration missing assertions and commands will default to []
self.assertIn(mock.call([]), m_add.call_args_list)
self.assertIn(mock.call([]), m_run.call_args_list)

@mock.patch("cloudinit.config.cc_snap.maybe_install_squashfuse")
def test_handle_tries_to_install_squashfuse(self, m_squash):
"""If squashfuse_in_container is True, try installing squashfuse."""
cfg = {"snap": {"squashfuse_in_container": True}}
mycloud = FakeCloud(None)
handle("snap", cfg=cfg, cloud=mycloud, log=self.logger, args=None)
self.assertEqual([mock.call(mycloud)], m_squash.call_args_list)

def test_handle_runs_commands_provided(self):
"""If commands are specified as a list, run them."""
outfile = self.tmp_path("output.log", dir=self.tmp)

cfg = {
"snap": {
"commands": [
'echo "HI" >> %s' % outfile,
'echo "MOM" >> %s' % outfile,
]
}
}
mock_path = "cloudinit.config.cc_snap.sys.stderr"
with self.allow_subp([CiTestCase.SUBP_SHELL_TRUE]):
with mock.patch(mock_path, new_callable=StringIO):
handle("snap", cfg=cfg, cloud=None, log=self.logger, args=None)

self.assertEqual("HI\nMOM\n", util.load_file(outfile))

@mock.patch("cloudinit.config.cc_snap.subp.subp")
def test_handle_adds_assertions(self, m_subp):
"""Any configured snap assertions are provided to add_assertions."""
Expand All @@ -429,60 +372,4 @@ def test_handle_adds_assertions(self, m_subp):
)


class TestMaybeInstallSquashFuse(CiTestCase):

with_logs = True

def setUp(self):
super(TestMaybeInstallSquashFuse, self).setUp()
self.tmp = self.tmp_dir()

@mock.patch("cloudinit.config.cc_snap.util.is_container")
def test_maybe_install_squashfuse_skips_non_containers(self, m_container):
"""maybe_install_squashfuse does nothing when not on a container."""
m_container.return_value = False
maybe_install_squashfuse(cloud=FakeCloud(None))
self.assertEqual([mock.call()], m_container.call_args_list)
self.assertEqual("", self.logs.getvalue())

@mock.patch("cloudinit.config.cc_snap.util.is_container")
def test_maybe_install_squashfuse_raises_install_errors(self, m_container):
"""maybe_install_squashfuse logs and raises package install errors."""
m_container.return_value = True
distro = mock.MagicMock()
distro.update_package_sources.side_effect = RuntimeError(
"Some apt error"
)
with self.assertRaises(RuntimeError) as context_manager:
maybe_install_squashfuse(cloud=FakeCloud(distro))
self.assertEqual("Some apt error", str(context_manager.exception))
self.assertIn("Package update failed\nTraceback", self.logs.getvalue())

@mock.patch("cloudinit.config.cc_snap.util.is_container")
def test_maybe_install_squashfuse_raises_update_errors(self, m_container):
"""maybe_install_squashfuse logs and raises package update errors."""
m_container.return_value = True
distro = mock.MagicMock()
distro.update_package_sources.side_effect = RuntimeError(
"Some apt error"
)
with self.assertRaises(RuntimeError) as context_manager:
maybe_install_squashfuse(cloud=FakeCloud(distro))
self.assertEqual("Some apt error", str(context_manager.exception))
self.assertIn("Package update failed\nTraceback", self.logs.getvalue())

@mock.patch("cloudinit.config.cc_snap.util.is_container")
def test_maybe_install_squashfuse_happy_path(self, m_container):
"""maybe_install_squashfuse logs and raises package install errors."""
m_container.return_value = True
distro = mock.MagicMock() # No errors raised
maybe_install_squashfuse(cloud=FakeCloud(distro))
self.assertEqual(
[mock.call()], distro.update_package_sources.call_args_list
)
self.assertEqual(
[mock.call(["squashfuse"])], distro.install_packages.call_args_list
)


# vi: ts=4 expandtab