Merge "Block nova-compute startup on mountpoint"

This commit is contained in:
Zuul 2021-10-08 16:08:30 +00:00 committed by Gerrit Code Review
commit c501f196d0
3 changed files with 57 additions and 4 deletions

View File

@ -123,6 +123,8 @@ from charmhelpers.contrib.storage.linux.utils import (
mkfs_xfs, mkfs_xfs,
) )
from charmhelpers.core.templating import render
CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt' CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
TEMPLATES = 'templates/' TEMPLATES = 'templates/'
@ -186,6 +188,9 @@ NOVA_COMPUTE_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'
NOVA_NETWORK_AA_PROFILE_PATH = ('/etc/apparmor.d/{}' NOVA_NETWORK_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'
''.format(NOVA_NETWORK_AA_PROFILE)) ''.format(NOVA_NETWORK_AA_PROFILE))
NOVA_COMPUTE_OVERRIDE_DIR = '/etc/systemd/system/nova-compute.service.d'
MOUNT_DEPENDENCY_OVERRIDE = '99-mount.conf'
LIBVIRT_TYPES = ['kvm', 'qemu', 'lxc'] LIBVIRT_TYPES = ['kvm', 'qemu', 'lxc']
USE_FQDN_KEY = 'nova-compute-charm-use-fqdn' USE_FQDN_KEY = 'nova-compute-charm-use-fqdn'
@ -1086,11 +1091,18 @@ def configure_local_ephemeral_storage():
level=DEBUG) level=DEBUG)
return return
mountpoint = '/var/lib/nova/instances'
db = kv() db = kv()
storage_configured = db.get('storage-configured', False) storage_configured = db.get('storage-configured', False)
if storage_configured: if storage_configured:
log("Ephemeral storage already configured, skipping", log("Ephemeral storage already configured, skipping",
level=DEBUG) level=DEBUG)
# NOTE(jamespage):
# Install mountpoint override to ensure that upgrades
# to the charm version which supports this change
# also start exhibiting the correct behaviour
install_mount_override(mountpoint)
return return
dev = determine_block_device() dev = determine_block_device()
@ -1132,10 +1144,10 @@ def configure_local_ephemeral_storage():
# If not cleaned and in use, mkfs should fail. # If not cleaned and in use, mkfs should fail.
mkfs_xfs(dev, force=True) mkfs_xfs(dev, force=True)
mountpoint = '/var/lib/nova/instances'
filesystem = "xfs" filesystem = "xfs"
mount(dev, mountpoint, filesystem=filesystem) mount(dev, mountpoint, filesystem=filesystem)
fstab_add(dev, mountpoint, filesystem, options=options) fstab_add(dev, mountpoint, filesystem, options=options)
install_mount_override(mountpoint)
check_call(['chown', '-R', 'nova:nova', mountpoint]) check_call(['chown', '-R', 'nova:nova', mountpoint])
check_call(['chmod', '-R', '0755', mountpoint]) check_call(['chmod', '-R', '0755', mountpoint])
@ -1146,6 +1158,16 @@ def configure_local_ephemeral_storage():
db.flush() db.flush()
def install_mount_override(mountpoint):
"""Install override for nova-compute for configured mountpoint"""
render(
MOUNT_DEPENDENCY_OVERRIDE,
os.path.join(NOVA_COMPUTE_OVERRIDE_DIR, MOUNT_DEPENDENCY_OVERRIDE),
{'mount_point': mountpoint.replace('/', '-')[1:]},
perms=0o644,
)
def get_availability_zone(): def get_availability_zone():
use_juju_az = config('customize-failure-domain') use_juju_az = config('customize-failure-domain')
juju_az = os.environ.get('JUJU_AVAILABILITY_ZONE') juju_az = os.environ.get('JUJU_AVAILABILITY_ZONE')

3
templates/99-mount.conf Normal file
View File

@ -0,0 +1,3 @@
[Unit]
Requires={{ mount_point }}.mount
After={{ mount_point }}.mount

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import tempfile import tempfile
import nova_compute_context as compute_context import nova_compute_context as compute_context
@ -996,6 +997,7 @@ class NovaComputeUtilsTests(CharmTestCase):
self.config.assert_called_with('ephemeral-device') self.config.assert_called_with('ephemeral-device')
self.storage_list.assert_called_with('ephemeral-device') self.storage_list.assert_called_with('ephemeral-device')
@patch.object(utils, 'install_mount_override')
@patch.object(utils, 'filter_installed_packages') @patch.object(utils, 'filter_installed_packages')
@patch.object(utils, 'uuid') @patch.object(utils, 'uuid')
@patch.object(utils, 'determine_block_device') @patch.object(utils, 'determine_block_device')
@ -1003,7 +1005,8 @@ class NovaComputeUtilsTests(CharmTestCase):
self, self,
determine_block_device, determine_block_device,
uuid, uuid,
filter_installed_packages): filter_installed_packages,
install_mount_override):
filter_installed_packages.return_value = [] filter_installed_packages.return_value = []
determine_block_device.return_value = '/dev/sdb' determine_block_device.return_value = '/dev/sdb'
uuid.uuid4.return_value = 'test' uuid.uuid4.return_value = 'test'
@ -1043,17 +1046,22 @@ class NovaComputeUtilsTests(CharmTestCase):
'x-systemd.requires=vaultlocker-decrypt@test.service,' 'x-systemd.requires=vaultlocker-decrypt@test.service,'
'comment=vaultlocker' 'comment=vaultlocker'
) )
install_mount_override.assert_called_with(
'/var/lib/nova/instances'
)
self.assertTrue(self.test_kv.get('storage-configured')) self.assertTrue(self.test_kv.get('storage-configured'))
self.vaultlocker.write_vaultlocker_conf.assert_called_with( self.vaultlocker.write_vaultlocker_conf.assert_called_with(
'test_context', 'test_context',
priority=80 priority=80
) )
@patch.object(utils, 'install_mount_override')
@patch.object(utils, 'uuid') @patch.object(utils, 'uuid')
@patch.object(utils, 'determine_block_device') @patch.object(utils, 'determine_block_device')
def test_configure_local_ephemeral_storage(self, def test_configure_local_ephemeral_storage(self,
determine_block_device, determine_block_device,
uuid): uuid,
install_mount_override):
determine_block_device.return_value = '/dev/sdb' determine_block_device.return_value = '/dev/sdb'
uuid.uuid4.return_value = 'test' uuid.uuid4.return_value = 'test'
@ -1088,12 +1096,17 @@ class NovaComputeUtilsTests(CharmTestCase):
'xfs', 'xfs',
options=None options=None
) )
install_mount_override.assert_called_with(
'/var/lib/nova/instances'
)
self.assertTrue(self.test_kv.get('storage-configured')) self.assertTrue(self.test_kv.get('storage-configured'))
self.vaultlocker.write_vaultlocker_conf.assert_not_called() self.vaultlocker.write_vaultlocker_conf.assert_not_called()
@patch.object(utils, 'install_mount_override')
@patch.object(utils, 'filter_installed_packages') @patch.object(utils, 'filter_installed_packages')
def test_configure_local_ephemeral_storage_done(self, def test_configure_local_ephemeral_storage_done(self,
filter_installed_packages): filter_installed_packages,
install_mount_override):
filter_installed_packages.return_value = [] filter_installed_packages.return_value = []
self.test_kv.set('storage-configured', True) self.test_kv.set('storage-configured', True)
@ -1113,6 +1126,10 @@ class NovaComputeUtilsTests(CharmTestCase):
priority=80 priority=80
) )
self.is_block_device.assert_not_called() self.is_block_device.assert_not_called()
# NOTE: called to deal with charm upgrades
install_mount_override.assert_called_with(
'/var/lib/nova/instances'
)
@patch.object(utils.os.environ, 'get') @patch.object(utils.os.environ, 'get')
def test_get_az_customize_with_env(self, os_environ_get_mock): def test_get_az_customize_with_env(self, os_environ_get_mock):
@ -1190,3 +1207,14 @@ class NovaComputeUtilsTests(CharmTestCase):
self.assertEquals(utils.use_fqdn_hint(), False) self.assertEquals(utils.use_fqdn_hint(), False)
_kv().get.return_value = True _kv().get.return_value = True
self.assertEquals(utils.use_fqdn_hint(), True) self.assertEquals(utils.use_fqdn_hint(), True)
@patch.object(utils, 'render')
def test_install_mount_override(self, render):
utils.install_mount_override('/srv/test')
render.assert_called_once_with(
utils.MOUNT_DEPENDENCY_OVERRIDE,
os.path.join(utils.NOVA_COMPUTE_OVERRIDE_DIR,
utils.MOUNT_DEPENDENCY_OVERRIDE),
{'mount_point': 'srv-test'},
perms=0o644,
)