Increase subuid/subgid range for root user

To support use of distinct subuid/subgid ranges per LXD container,
the default range for the root user must be increased to support
> 1 running container in this configuration.

Increase subuid/subgid range to support 5000 containers with distinct
ranges.  Restart LXD daemon if idmap configuration changes, to ensure
that the full range of subid's are used.

(also fix amulet tests for OpenStack Newton).

Change-Id: I8b87dad736abaffdbd7afac090429790d3b03c96
Closes-Bug: 1648056
(cherry picked from commit f0773c9952)
This commit is contained in:
James Page 2016-12-07 12:58:23 +00:00
parent a78a6bd77c
commit eb44a89495
4 changed files with 85 additions and 0 deletions

View File

@ -43,6 +43,7 @@ from charmhelpers.core.host import (
umount,
service_stop,
service_start,
service_restart,
pwgen,
lsb_release,
)
@ -431,6 +432,7 @@ def configure_lxd_host():
'Y\n' if config('enable-ext4-userns') else 'N\n'
)
configure_uid_mapping()
elif ubuntu_release == "vivid":
log('Vivid deployment - loading overlay kernel module', level=INFO)
cmd = ['modprobe', 'overlay']
@ -509,3 +511,30 @@ def zpools():
return pools
except CalledProcessError:
return []
SUBUID = '/etc/subuid'
SUBGID = '/etc/subgid'
DEFAULT_COUNT = '327680000' # 5000 containers
ROOT_USER = 'root'
def configure_uid_mapping():
'''Extend root user /etc/{subuid,subgid} mapping for LXD use'''
restart_lxd = False
for uidfile in (SUBUID, SUBGID):
with open(uidfile, 'r+') as f_id:
ids = []
for s_id in f_id.readlines():
_id = s_id.strip().split(':')
if (_id[0] == ROOT_USER and
_id[2] != DEFAULT_COUNT):
_id[2] = DEFAULT_COUNT
restart_lxd = True
ids.append(_id)
f_id.seek(0)
for _id in ids:
f_id.write('{}:{}:{}\n'.format(*_id))
f_id.truncate()
if restart_lxd:
# NOTE: restart LXD to pickup changes in id map config
service_restart('lxd')

View File

@ -183,6 +183,12 @@ class LXDBasicDeployment(OpenStackAmuletDeployment):
# Authenticate admin with glance endpoint
self.glance = u.authenticate_glance_admin(self.keystone)
# Authenticate admin with nova endpoint
self.nova = u.authenticate_nova_user(self.keystone,
user='admin',
password='openstack',
tenant='admin')
# Create a demo tenant/role/user
self.demo_tenant = 'demoTenant'
self.demo_role = 'demoRole'
@ -364,6 +370,10 @@ class LXDBasicDeployment(OpenStackAmuletDeployment):
if not image:
amulet.raise_status(amulet.FAIL, msg='Image create failed')
# NOTE(jamespage): ensure require flavor exists, required for >= newton
u.create_flavor(nova=self.nova,
name='m1.tiny', ram=512, vcpus=1, disk=1)
# Create nova instance
instance_name = 'lxd-instance-{}'.format(time.time())
instance = u.create_instance(self.nova_demo, LXD_IMAGE_NAME,

View File

@ -32,6 +32,8 @@ from charmhelpers.contrib.openstack.amulet.utils import (
OpenStackAmuletUtils
)
from novaclient import exceptions
DEBUG = logging.DEBUG
ERROR = logging.ERROR
@ -131,3 +133,13 @@ class LXDAmuletUtils(OpenStackAmuletUtils):
amulet.raise_status(amulet.FAIL, msg=msg)
return image
def create_flavor(self, nova, name, ram, vcpus, disk, flavorid="auto",
ephemeral=0, swap=0, rxtx_factor=1.0, is_public=True):
"""Create the specified flavor."""
try:
nova.flavors.find(name=name)
except (exceptions.NotFound, exceptions.NoUniqueMatch):
self.log.debug('Creating flavor ({})'.format(name))
nova.flavors.create(name, ram, vcpus, disk, flavorid,
ephemeral, swap, rxtx_factor, is_public)

View File

@ -204,3 +204,37 @@ class TestLXDUtilsAssessStatus(testing.CharmTestCase):
self.get_upstream_version.assert_called_with(
lxd_utils.VERSION_PACKAGE
)
class TestConfigureUIDGID(testing.CharmTestCase):
"""Tests for hooks.lxd_utils.configure_uid_mapping."""
TO_PATCH = [
'check_call',
'service_restart'
]
UIDMAP = [
'lxd:100000:65536',
'root:100000:65536',
'ubuntu:165536:65536',
]
def setUp(self):
super(TestConfigureUIDGID, self).setUp(
lxd_utils, self.TO_PATCH)
def test_configure_uid_mapping(self):
with testing.patch_open() as (_open, _file):
_file.readlines.return_value = self.UIDMAP
lxd_utils.configure_uid_mapping()
_open.assert_has_calls([
mock.call('/etc/subuid', 'r+'),
mock.call('/etc/subgid', 'r+')
])
_file.write.assert_has_calls([
mock.call('lxd:100000:65536\n'),
mock.call('root:100000:327680000\n'),
mock.call('ubuntu:165536:65536\n')
])
self.service_restart.assert_called_with('lxd')