Fixed 'privileged' instance creation using config-drive

Exsiting config drive creation flow assume that LXD
ALWAYS return UID mapping for instance.
For privieged this is not true, as not UID mapping perfomed.
Existing code which try simply split JSON answer and
lookup in it failed as result.
Parser switched to JSON based parsing and have fallback
to zero UID if no mapping found in LXD answer.

Change-Id: If11bf72a9fdeeaff4f55cfca0ec0bc0a1bc6ce3c
Closes-Bug: 1707101
This commit is contained in:
Alexander Kharkov 2017-08-02 06:51:29 +00:00 committed by Alex Kavanagh
parent d9bcbd598e
commit 5512808831
1 changed files with 40 additions and 7 deletions

View File

@ -1201,9 +1201,40 @@ class LXDDriver(driver.ComputeDriver):
format=CONF.config_drive_format)
container = self.client.containers.get(instance.name)
container_id_map = container.config[
'volatile.last_state.idmap'].split(',')
storage_id = container_id_map[2].split(':')[1]
storage_id = 0
"""
Determine UID shift used for container uid mapping
Sample JSON config from LXD
{
"volatile.apply_template": "create",
...
"volatile.last_state.idmap": "[
{
\"Isuid\":true,
\"Isgid\":false,
\"Hostid\":100000,
\"Nsid\":0,
\"Maprange\":65536
},
{
\"Isuid\":false,
\"Isgid\":true,
\"Hostid\":100000,
\"Nsid\":0,
\"Maprange\":65536
}] ",
"volatile.tap5fd6808a-7b.name": "eth0"
}
"""
container_id_map = json.loads(
container.config['volatile.last_state.idmap'])
uid_map = filter(lambda id_map: id_map.get("Isuid"), container_id_map)
if uid_map:
storage_id = uid_map[0].get("Hostid", 0)
else:
# privileged containers does not have uid/gid mapping
# LXD API return nothing
pass
extra_md = {}
if admin_password:
@ -1249,10 +1280,12 @@ class LXDDriver(driver.ComputeDriver):
for ent in os.listdir(tmpdir):
shutil.copytree(os.path.join(tmpdir, ent),
os.path.join(configdrive_dir, ent))
utils.execute('chmod', '-R', '775', configdrive_dir,
run_as_root=True)
utils.execute('chown', '-R', storage_id, configdrive_dir,
run_as_root=True)
utils.execute('chmod', '-R', '775', configdrive_dir,
run_as_root=True)
utils.execute('chown', '-R',
'%s:%s' % (storage_id, storage_id),
configdrive_dir, run_as_root=True)
finally:
if mounted:
utils.execute('umount', tmpdir, run_as_root=True)