On Tue, 2015-09-08 at 17:29 +0100, Daniel P. Berrange wrote:
From: Eren Yagdiran <erenyagdiran(a)gmail.com>
Move the docker-related code to the DockerSource and use
the Source mechanism
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
libvirt-sandbox/image/cli.py | 76 +++++-----------------
libvirt-sandbox/image/sources/DockerSource.py | 90 +++++++++++++++++++++++++++
libvirt-sandbox/image/sources/Source.py | 15 +++++
3 files changed, 122 insertions(+), 59 deletions(-)
diff --git a/libvirt-sandbox/image/cli.py b/libvirt-sandbox/image/cli.py
index 7af617e..f3c0ab7 100755
--- a/libvirt-sandbox/image/cli.py
+++ b/libvirt-sandbox/image/cli.py
@@ -118,59 +118,6 @@ def delete_template(name, destdir):
parent = None
imagetagid = parent
-
-def get_image_list(name, destdir):
- imageparent = {}
- imagenames = {}
- imagedirs = os.listdir(destdir)
- for imagetagid in imagedirs:
- indexfile = destdir + "/" + imagetagid + "/index.json"
- if os.path.exists(indexfile):
- with open(indexfile, "r") as f:
- index = json.load(f)
- imagenames[index["name"]] = imagetagid
- jsonfile = destdir + "/" + imagetagid + "/template.json"
- if os.path.exists(jsonfile):
- with open(jsonfile, "r") as f:
- template = json.load(f)
-
- parent = template.get("parent", None)
- if parent:
- imageparent[imagetagid] = parent
-
- if not name in imagenames:
- raise ValueError(["Image %s does not exist locally" % name])
-
- imagetagid = imagenames[name]
- imagelist = []
- while imagetagid != None:
- imagelist.append(imagetagid)
- parent = imageparent.get(imagetagid, None)
- imagetagid = parent
-
- return imagelist
-
-def create_template(name, imagepath, format, destdir):
- if not format in ["qcow2"]:
- raise ValueError(["Unsupported image format %s" % format])
-
- imagelist = get_image_list(name, destdir)
- imagelist.reverse()
-
- parentImage = None
- for imagetagid in imagelist:
- templateImage = destdir + "/" + imagetagid + "/template." +
format
- cmd = ["qemu-img", "create", "-f",
"qcow2"]
- if parentImage is not None:
- cmd.append("-o")
- cmd.append("backing_fmt=qcow2,backing_file=%s" % parentImage)
- cmd.append(templateImage)
- if parentImage is None:
- cmd.append("10G")
- debug("Run %s\n" % " ".join(cmd))
- subprocess.call(cmd)
- parentImage = templateImage
-
def download(args):
try:
dynamic_source_loader(args.source).download_template(templatename=args.template,
@@ -188,8 +135,13 @@ def delete(args):
delete_template(args.template, default_template_dir)
def create(args):
- info("Creating %s from %s in format %s\n" % (args.imagepath,
args.template, args.format))
- create_template(args.template, args.imagepath, args.format, default_template_dir)
+ try:
+ dynamic_source_loader(args.source).create_template(templatename=args.template,
+
templatedir=args.template_dir,
+ connect=args.connect,
+ format=args.format)
+ except Exception,e:
+ print "Create Error %s" % str(e)
def requires_template(parser):
parser.add_argument("template",
@@ -200,6 +152,10 @@ def requires_source(parser):
default="docker",
help=_("name of the template"))
+def requires_connect(parser):
+ parser.add_argument("-c","--connect",
+ help=_("Connect string for libvirt"))
+
def requires_auth_conn(parser):
parser.add_argument("-r","--registry",
help=_("Url of the custom registry"))
@@ -233,10 +189,12 @@ def gen_create_args(subparser):
parser = subparser.add_parser("create",
help=_("Create image from template data"))
requires_template(parser)
- parser.add_argument("imagepath",
- help=_("path for image"))
- parser.add_argument("format",
- help=_("format"))
+ requires_source(parser)
+ requires_connect(parser)
+ requires_template_dir(parser)
+ parser.add_argument("-f","--format",
+ default="qcow2",
+ help=_("format format for image"))
parser.set_defaults(func=create)
def main():
diff --git a/libvirt-sandbox/image/sources/DockerSource.py
b/libvirt-sandbox/image/sources/DockerSource.py
index 37b40dc..c1c8a7d 100644
--- a/libvirt-sandbox/image/sources/DockerSource.py
+++ b/libvirt-sandbox/image/sources/DockerSource.py
@@ -205,5 +205,95 @@ class DockerSource(Source):
debug("FAIL %s\n" % str(e))
raise
+ def create_template(self, templatename, templatedir, connect=None, format=None):
+ if format is None:
+ format = self.default_disk_format
+ self._check_disk_format(format)
+ imagelist = self._get_image_list(templatename,templatedir)
+ imagelist.reverse()
+
+ parentImage = None
+ for imagetagid in imagelist:
+ templateImage = templatedir + "/" + imagetagid +
"/template." + format
+ cmd =
["qemu-img","create","-f","qcow2"]
+ if parentImage is not None:
+ cmd.append("-o")
+ cmd.append("backing_fmt=qcow2,backing_file=%s" % parentImage)
+ cmd.append(templateImage)
+ if parentImage is None:
+ cmd.append("10G")
+ subprocess.call(cmd)
+
+ if parentImage is None:
+ self._format_disk(templateImage,format,connect)
+
+ self._extract_tarballs(templatedir + "/" + imagetagid +
"/template.",format,connect)
+ parentImage = templateImage
+
+
+ def _check_disk_format(self,format):
+ supportedFormats = ['qcow2']
+ if not format in supportedFormats:
+ raise ValueError(["Unsupported image format %s" % format])
+
+ def _get_image_list(self,templatename,destdir):
+ imageparent = {}
+ imagenames = {}
+ imagedirs = os.listdir(destdir)
+ for imagetagid in imagedirs:
+ indexfile = destdir + "/" + imagetagid + "/index.json"
+ if os.path.exists(indexfile):
+ with open(indexfile,"r") as f:
+ index = json.load(f)
+ imagenames[index["name"]] = imagetagid
+ jsonfile = destdir + "/" + imagetagid +
"/template.json"
+ if os.path.exists(jsonfile):
+ with open(jsonfile,"r") as f:
+ template = json.load(f)
+ parent = template.get("parent",None)
+ if parent:
+ imageparent[imagetagid] = parent
+ if not templatename in imagenames:
+ raise ValueError(["Image %s does not exist locally"
%templatename])
+ imagetagid = imagenames[templatename]
+ imagelist = []
+ while imagetagid != None:
+ imagelist.append(imagetagid)
+ parent = imageparent.get(imagetagid,None)
+ imagetagid = parent
+ return imagelist
+
+ def _format_disk(self,disk,format,connect):
+ cmd = ['virt-sandbox']
+ if connect is not None:
+ cmd.append("-c")
+ cmd.append(connect)
+ cmd.append("-p")
+ params = ['--disk=file:disk_image=%s,format=%s' %(disk,format),
+ '/sbin/mkfs.ext3',
+ '/dev/disk/by-tag/disk_image']
+ cmd = cmd + params
+ subprocess.call(cmd)
+
+ def _extract_tarballs(self,directory,format,connect):
+ tempdir = "/mnt"
Is it safe to assume we'll be able to use /mnt as a temporary mount
folder? I'ld be more inclined in using a really temporary folder.
--
Cedric
+ tarfile = directory + "tar.gz"
+ diskfile = directory + "qcow2"
+ cmd = ['virt-sandbox']
+ if connect is not None:
+ cmd.append("-c")
+ cmd.append(connect)
+ cmd.append("-p")
+ params = ['-m',
+ 'host-image:/mnt=%s,format=%s' %(diskfile,format),
+ '--',
+ '/bin/tar',
+ 'zxf',
+ '%s' %tarfile,
+ '-C',
+ '/mnt']
+ cmd = cmd + params
+ subprocess.call(cmd)
+
def debug(msg):
sys.stderr.write(msg)
diff --git a/libvirt-sandbox/image/sources/Source.py
b/libvirt-sandbox/image/sources/Source.py
index 81f5176..436eef6 100644
--- a/libvirt-sandbox/image/sources/Source.py
+++ b/libvirt-sandbox/image/sources/Source.py
@@ -46,3 +46,18 @@ class Source():
filesystem
"""
pass
+
+ @abstractmethod
+ def create_template(self, templatename, templatedir,
+ connect=None, format=None):
+ """
+ :param templatename: name of the template image to create
+ :param templatedir: local directory path in which to store the template
+ :param connect: libvirt connection URI
+ :param format: disk image format
+
+ Create a set of local disk images populated with the content
+ of a template. The images creation process will be isolated
+ inside a sandbox using the requested libvirt connection URI.
+ """
+ pass