Fix detection of already initialised lxc storage pool

The related bug was caused because the charm did not detect when
the lxc storage had already been set up using the `lxc storage`
command which is used in the 3.x series, rather than the old way
with the 2.x series.

Also fixes issue on xenial where linux-image-extra-* has been renamed to
linux-modules-extra-* from from -4.4.0-145-generic onwards.  Otherwise,
the install fails on xenial.

Change-Id: If8bdad6f5641ee21fc7860dceeb4c3facbaecc76
Closes-Bug: #1825393
This commit is contained in:
Alex Kavanagh 2019-04-23 15:11:11 +01:00
parent 77e3b68731
commit 4bf72620c3
3 changed files with 76 additions and 7 deletions

View File

@ -188,8 +188,12 @@ def get_block_devices():
def configure_lxd_block():
'''Configure a block device for use by LXD for containers'''
log('Configuring LXD container storage')
if filesystem_mounted('/var/lib/lxd'):
log('Configuring LXD container storage if not configured')
# determine if the lxd block has already been configured
if has_storage(LXD_POOL):
log("LXD storage pool {} already configured".format(LXD_POOL))
return
elif filesystem_mounted('/var/lib/lxd'):
log('/var/lib/lxd already configured, skipping')
return
@ -308,9 +312,20 @@ def config_zfs(dev):
check_call(cmd)
def has_storage():
def has_storage(search_for_pool=None):
try:
check_call(['lxc', 'storage', 'list'])
pools = (check_output(['lxc', 'storage', 'list'])
.decode('utf-8')
.splitlines())
if search_for_pool is not None:
for pool in pools:
try:
name = pool.split(' ')[1]
if search_for_pool == name:
return True
except IndexError:
pass
return False
return True
except subprocess.CalledProcessError:
return False
@ -476,8 +491,12 @@ def configure_lxd_host():
# Configure live migration
if cmp_ubuntu_release == 'xenial':
apt_install('linux-image-extra-%s' % os.uname()[2],
fatal=True)
uname = os.uname()[2]
if uname > '4.4.0-122-generic':
pkg = "linux-modules-extra-{}"
else:
pkg = "linux-image-extra-{}"
apt_install(pkg.format(uname), fatal=True)
if cmp_ubuntu_release >= 'xenial':
modprobe('netlink_diag')

View File

@ -87,5 +87,5 @@ commands =
bundletester -vl DEBUG -r json -o func-results.json --test-pattern "dev-*" --no-destroy
[flake8]
ignore = E402,E226
ignore = E402,E226,W504
exclude = */charmhelpers

View File

@ -14,6 +14,7 @@
"""Tests for hooks.lxd_utils."""
import mock
import textwrap
import lxd_utils
import testing
@ -238,3 +239,52 @@ class TestConfigureUIDGID(testing.CharmTestCase):
mock.call('ubuntu:165536:65536\n')
])
self.service_restart.assert_called_with('lxd')
class MyProcessError(Exception):
pass
class TestHasStorage(testing.CharmTestCase):
"""Tests for hooks.lxd_utils.has_storage"""
TO_PATCH = [
'check_output',
]
def setUp(self):
super(TestHasStorage, self).setUp(lxd_utils, self.TO_PATCH)
def test_has_storage_default(self):
self.check_output.return_value = b""
self.assertTrue(lxd_utils.has_storage())
@mock.patch('subprocess.CalledProcessError', new=MyProcessError)
def test_has_storage_default_error(self):
def raise_error(*args, **kwargs):
raise MyProcessError()
self.check_output.side_effect = raise_error
self.assertFalse(lxd_utils.has_storage())
def test_has_storage_by_pool(self):
self.check_output.return_value = textwrap.dedent(
b"""
+---------+-------------+--------+--------------------------------+---------+
| NAME | DESCRIPTION | DRIVER | SOURCE | USED BY |
+---------+-------------+--------+--------------------------------+---------+
| default | | btrfs | /var/lib/lxd/disks/default.img | 1 |
+---------+-------------+--------+--------------------------------+---------+
""") # NOQA W501
self.assertTrue(lxd_utils.has_storage('default'))
def test_has_storage_missing_pool(self):
self.check_output.return_value = textwrap.dedent(
b"""
+---------+-------------+--------+--------------------------------+---------+
| NAME | DESCRIPTION | DRIVER | SOURCE | USED BY |
+---------+-------------+--------+--------------------------------+---------+
| default | | btrfs | /var/lib/lxd/disks/default.img | 1 |
+---------+-------------+--------+--------------------------------+---------+
""") # NOQA W501
self.assertFalse(lxd_utils.has_storage('btrfs'))