Skip to content

Commit

Permalink
export: Backing file resolution fixes
Browse files Browse the repository at this point in the history
1. If the disk is a layer and the path to his backing
   file is correct, do nothing.

2. Avoid endless recursion when the disk and its backing file
   has the same name.

3. Safely parse the name and the version of the backing file.
   Raise exception if the format of the backing file is not name:version.

Signed-off-by: gbenhaim <[email protected]>
  • Loading branch information
gbenhaim committed Jul 2, 2017
1 parent 81f8a75 commit 5b34e51
Showing 1 changed file with 43 additions and 22 deletions.
65 changes: 43 additions & 22 deletions lago/prefix.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import os
import shutil
import subprocess
from textwrap import dedent
import urlparse
import urllib
import uuid
Expand Down Expand Up @@ -837,35 +838,55 @@ def resolve_parent(self, disk_path, template_store, template_repo):
"""
qemu_info = utils.get_qemu_info(disk_path)
parent = qemu_info.get('backing-filename')
if not parent:
return

if os.path.isfile(parent):
if os.path.samefile(
os.path.realpath(parent),
os.path.realpath(os.path.expandvars(disk_path))
):
raise LagoInitException(
dedent(
"""
Disk {} and its backing file are the same file.
""".format(disk_path)
)
)
# The parent exist and we have the correct pointer
return

if parent:
LOGGER.info('Resolving Parent')
LOGGER.info('Resolving Parent')
try:
name, version = os.path.basename(parent).split(':', 1)
if not (name and version):
raise RuntimeError(
'Unsupported backing-filename: {}'
'backing-filename should be in the format'
'name:version'.format(parent)
except ValueError:
raise LagoInitException(
dedent(
"""
Backing file resolution of disk {} failed.
Backing file {} is not a Lago image.
""".format(disk_path, parent)
)
_, _, base = self._handle_lago_template(
'', {'template_name': name,
'template_version': version}, template_store,
template_repo
)

# The child has the right pointer to his parent
base = os.path.expandvars(base)
if base == parent:
return
_, _, base = self._handle_lago_template(
'', {'template_name': name,
'template_version': version}, template_store, template_repo
)

# The child doesn't have the right pointer to his
# parent, We will fix it with a symlink
link_name = os.path.join(
os.path.dirname(disk_path), '{}:{}'.format(name, version)
)
link_name = os.path.expandvars(link_name)
# The child has the right pointer to his parent
base = os.path.expandvars(base)
if base == parent:
return

# The child doesn't have the right pointer to his
# parent, We will fix it with a symlink
link_name = os.path.join(
os.path.dirname(disk_path), '{}:{}'.format(name, version)
)
link_name = os.path.expandvars(link_name)

self._create_link_to_parent(base, link_name)
self._create_link_to_parent(base, link_name)

def _create_link_to_parent(self, base, link_name):
if not os.path.islink(link_name):
Expand Down

0 comments on commit 5b34e51

Please sign in to comment.