From nobody Fri May 3 08:01:38 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1524067870374235.47957855493542; Wed, 18 Apr 2018 09:11:10 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D4A19155DB; Wed, 18 Apr 2018 16:11:08 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 77FA27F63B; Wed, 18 Apr 2018 16:11:08 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E9CB31806102; Wed, 18 Apr 2018 16:11:07 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w3IGB4np020138 for ; Wed, 18 Apr 2018 12:11:04 -0400 Received: by smtp.corp.redhat.com (Postfix) id 82EC12166BDA; Wed, 18 Apr 2018 16:11:04 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 715542166BB2; Wed, 18 Apr 2018 16:11:03 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Wed, 18 Apr 2018 17:10:59 +0100 Message-Id: <20180418161059.30349-2-berrange@redhat.com> In-Reply-To: <20180418161059.30349-1-berrange@redhat.com> References: <20180418161059.30349-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-loop: libvir-list@redhat.com Cc: Cedric Bosdonnat , Radostin Stoyanov Subject: [libvirt] [PATCH sandbox 1/1] Delete virt-sandbox-image tool now in separate repo X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 18 Apr 2018 16:11:09 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 The virt-sandbox-image tool and its supporting code has been split into a separate libvirt-sandbox-image GIT repository. This allows its build system and distribution to work in the normal python way, and have a release lifecycle independent of the main libvirt-sandbox package. https://libvirt.org/git/?p=3Dlibvirt-sandbox-image.git;a=3Dsummary Signed-off-by: Daniel P. Berrang=C3=A9 --- autobuild.sh | 3 +- bin/virt-sandbox-image | 8 - configure.ac | 4 - libvirt-sandbox.spec.in | 9 - libvirt-sandbox/image/Makefile.am | 10 - libvirt-sandbox/image/__init__.py | 0 libvirt-sandbox/image/cli.py | 282 ----------- libvirt-sandbox/image/sources/Makefile.am | 10 - libvirt-sandbox/image/sources/__init__.py | 0 libvirt-sandbox/image/sources/base.py | 160 ------- libvirt-sandbox/image/sources/docker.py | 690 -----------------------= ---- libvirt-sandbox/image/sources/virtbuilder.py | 109 ----- libvirt-sandbox/image/template.py | 133 ------ m4/virt-win32.m4 | 5 - 14 files changed, 1 insertion(+), 1422 deletions(-) delete mode 100755 bin/virt-sandbox-image delete mode 100644 libvirt-sandbox/image/Makefile.am delete mode 100644 libvirt-sandbox/image/__init__.py delete mode 100644 libvirt-sandbox/image/cli.py delete mode 100644 libvirt-sandbox/image/sources/Makefile.am delete mode 100644 libvirt-sandbox/image/sources/__init__.py delete mode 100644 libvirt-sandbox/image/sources/base.py delete mode 100755 libvirt-sandbox/image/sources/docker.py delete mode 100755 libvirt-sandbox/image/sources/virtbuilder.py delete mode 100644 libvirt-sandbox/image/template.py diff --git a/autobuild.sh b/autobuild.sh index 9cd4ca2..c176fea 100755 --- a/autobuild.sh +++ b/autobuild.sh @@ -54,8 +54,7 @@ if [ -x /usr/bin/i686-pc-mingw32-gcc ]; then ../configure \ --build=3D$(uname -m)-pc-linux \ --host=3Di686-pc-mingw32 \ - --prefix=3D"$AUTOBUILD_INSTALL_ROOT/i686-pc-mingw32/sys-root/mingw" \ - --without-python + --prefix=3D"$AUTOBUILD_INSTALL_ROOT/i686-pc-mingw32/sys-root/mingw" =20 make make install diff --git a/bin/virt-sandbox-image b/bin/virt-sandbox-image deleted file mode 100755 index 61346ef..0000000 --- a/bin/virt-sandbox-image +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from libvirt_sandbox.image import cli -import sys - -if __name__ =3D=3D '__main__': - sys.exit(cli.main()) diff --git a/configure.ac b/configure.ac index 28305d2..19d4523 100644 --- a/configure.ac +++ b/configure.ac @@ -130,13 +130,9 @@ dnl Should be in m4/virt-gettext.m4 but intltoolize is= too dnl dumb to find it there IT_PROG_INTLTOOL([0.35.0]) =20 -AM_PATH_PYTHON([3]) - AC_OUTPUT(Makefile libvirt-sandbox/Makefile libvirt-sandbox/tests/Makefile - libvirt-sandbox/image/Makefile - libvirt-sandbox/image/sources/Makefile bin/Makefile examples/Makefile docs/Makefile diff --git a/libvirt-sandbox.spec.in b/libvirt-sandbox.spec.in index 125a361..0374d9e 100644 --- a/libvirt-sandbox.spec.in +++ b/libvirt-sandbox.spec.in @@ -36,14 +36,7 @@ BuildRequires: zlib-devel >=3D 1.2.0, zlib-static BuildRequires: libtirpc-devel BuildRequires: rpcgen %endif -Requires: python3-rpm -# For virsh lxc-enter-namespace command -Requires: libvirt-client >=3D %{libvirt_version} -Requires: systemd >=3D 198 -Requires: pygobject3-base -Requires: libselinux-python3 Requires: %{name}-libs =3D %{version}-%{release} -Requires: %{_bindir}/virt-builder =20 %package libs Group: Development/Libraries @@ -102,8 +95,6 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %{_bindir}/virt-sandbox -%{_bindir}/virt-sandbox-image -%{python3_sitelib}/libvirt_sandbox %{_mandir}/man1/virt-sandbox.1* =20 %files libs -f %{name}.lang diff --git a/libvirt-sandbox/image/Makefile.am b/libvirt-sandbox/image/Make= file.am deleted file mode 100644 index 60afbf3..0000000 --- a/libvirt-sandbox/image/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ - -SUBDIRS =3D sources - -pythonsandboxdir =3D $(pythondir)/libvirt_sandbox -pythonsandbox_DATA =3D __init__.py - -pythonimagedir =3D $(pythondir)/libvirt_sandbox/image -pythonimage_DATA =3D __init__.py cli.py template.py - -EXTRA_DIST =3D $(pythonimage_DATA) diff --git a/libvirt-sandbox/image/__init__.py b/libvirt-sandbox/image/__in= it__.py deleted file mode 100644 index e69de29..0000000 diff --git a/libvirt-sandbox/image/cli.py b/libvirt-sandbox/image/cli.py deleted file mode 100644 index 605183c..0000000 --- a/libvirt-sandbox/image/cli.py +++ /dev/null @@ -1,282 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Authors: Daniel P. Berrange -# Eren Yagdiran -# -# Copyright (C) 2013-2015 Red Hat, Inc. -# Copyright (C) 2015 Universitat Polit=C3=A8cnica de Catalunya. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -import argparse -import gettext -import hashlib -import json -import os -import os.path -import re -import shutil -import sys -import subprocess -import random -import string - -from libvirt_sandbox.image import template - -if os.geteuid() =3D=3D 0: - default_template_dir =3D "/var/lib/libvirt/templates" - default_image_dir =3D "/var/lib/libvirt/images" -else: - default_template_dir =3D os.environ['HOME'] + "/.local/share/libvirt/t= emplates" - default_image_dir =3D os.environ['HOME'] + "/.local/share/libvirt/imag= es" - -debug =3D False -verbose =3D False - -gettext.bindtextdomain("libvirt-sandbox", "/usr/share/locale") -gettext.textdomain("libvirt-sandbox") -try: - gettext.install("libvirt-sandbox", - localedir=3D"/usr/share/locale", - codeset =3D 'utf-8') -except IOError: - import __builtin__ - __builtin__.__dict__['_'] =3D unicode - - -def debug(msg): - sys.stderr.write(msg) - -def info(msg): - sys.stdout.write(msg) - -def get_template_dir(args): - tmpl =3D template.Template.from_uri(args.template) - return "%s/%s" % (args.template_dir, tmpl.source) - -def purge(args): - tmpl =3D template.Template.from_uri(args.template) - source =3D tmpl.get_source_impl() - source.delete_template(template=3Dtmpl, - templatedir=3Dget_template_dir(args)) - -def prepare(args): - tmpl =3D template.Template.from_uri(args.template) - source =3D tmpl.get_source_impl() - source.create_template(template=3Dtmpl, - templatedir=3Dget_template_dir(args), - connect=3Dargs.connect) - -def random_domain_name(tmpl): - randomid =3D ''.join(random.choice(string.ascii_lowercase) for i in ra= nge(10)) - return re.sub('[^a-z0-9-]', '_', tmpl.path[1:], re.I) + ":" + randomid - -def run(args): - if args.connect is not None: - check_connect(args.connect) - - tmpl =3D template.Template.from_uri(args.template) - source =3D tmpl.get_source_impl() - template_dir =3D get_template_dir(args) - - # Create the template image if needed - if not source.has_template(tmpl, template_dir): - prepare(args) - - name =3D args.name - if name is None: - name =3D random_domain_name(tmpl) - - diskfile =3D source.get_disk(template=3Dtmpl, - templatedir=3Dtemplate_dir, - imagedir=3Dargs.image_dir, - sandboxname=3Dname) - - commandToRun =3D source.get_command(tmpl, template_dir, args.args) - if len(commandToRun) =3D=3D 0: - commandToRun =3D ["/bin/sh"] - cmd =3D ['virt-sandbox', '--name', name] - if args.connect is not None: - cmd.append("-c") - cmd.append(args.connect) - params =3D ['-m','host-image:/=3D%s,format=3Dqcow2' % diskfile] - - networkArgs =3D args.network - if networkArgs is not None: - params.append('-N') - params.append(networkArgs) - - allEnvs =3D source.get_env(tmpl, template_dir) - envArgs =3D args.env - if envArgs is not None: - allEnvs =3D allEnvs + envArgs - for env in allEnvs: - envsplit =3D env.split("=3D") - envlen =3D len(envsplit) - if envlen =3D=3D 2: - params.append("--env") - params.append(env) - else: - pass - - cmd =3D cmd + params + ['--'] + commandToRun - subprocess.call(cmd) - os.unlink(diskfile) - source.post_run(tmpl, template_dir, name) - -def list_cached(args): - tmpls =3D [] - if args.source is not None: - tmpls.extend(template.Template.get_all(args.source, - "%s/%s" % (args.template_di= r, args.source))) - else: - for source in ["docker", "virt-builder"]: - tmpls.extend(template.Template.get_all(source, - "%s/%s" % (args.templat= e_dir, source))) - for tmpl in tmpls: - print (tmpl) - -def requires_template(parser): - parser.add_argument("template", - help=3D_("URI of the template")) - -def requires_name(parser): - parser.add_argument("-n","--name", - help=3D_("Name of the running sandbox")) - -def requires_debug(parser): - parser.add_argument("-d","--debug", - default=3DFalse, action=3D"store_true", - help=3D_("Run in debug mode")) - -def check_connect(connectstr): - supportedDrivers =3D ['lxc:///','qemu:///session','qemu:///system'] - if not connectstr in supportedDrivers: - raise ValueError("URI '%s' is not supported by virt-sandbox-image"= % connectstr) - return True - -def requires_connect(parser): - parser.add_argument("-c","--connect", - help=3D_("Connect string for libvirt")) - -def requires_template_dir(parser): - global default_template_dir - parser.add_argument("-t","--template-dir", - default=3Ddefault_template_dir, - help=3D_("Template directory for saving templates"= )) - -def requires_image_dir(parser): - global default_image_dir - parser.add_argument("-I","--image-dir", - default=3Ddefault_image_dir, - help=3D_("Image directory for saving images")) - -def gen_command_parser(subparser, name, helptext): - parser =3D subparser.add_parser( - name, help=3Dhelptext, - formatter_class=3Dargparse.RawDescriptionHelpFormatter, - epilog=3D""" - -Example supported URI formats: - - docker:///ubuntu?tag=3D15.04 - docker://username:password@index.docker.io/private/image - docker://registry.access.redhat.com/rhel6 - virt-builder:///fedora-20 -""") - return parser - -def gen_purge_args(subparser): - parser =3D gen_command_parser(subparser, "purge", - _("Purge cached template")) - requires_template(parser) - requires_template_dir(parser) - parser.set_defaults(func=3Dpurge) - -def gen_prepare_args(subparser): - parser =3D gen_command_parser(subparser, "prepare", - _("Prepare local template")) - requires_template(parser) - requires_connect(parser) - requires_template_dir(parser) - parser.set_defaults(func=3Dprepare) - -def gen_run_args(subparser): - parser =3D gen_command_parser(subparser, "run", - _("Run an instance of a template")) - requires_name(parser) - requires_template(parser) - requires_connect(parser) - requires_template_dir(parser) - requires_image_dir(parser) - parser.add_argument("args", - nargs=3Dargparse.REMAINDER, - help=3D_("command arguments to run")) - parser.add_argument("-N","--network", - help=3D_("Network params for running template")) - parser.add_argument("-e","--env",action=3D"append", - help=3D_("Environment params for running template"= )) - - parser.set_defaults(func=3Drun) - -def gen_list_args(subparser): - parser =3D gen_command_parser(subparser, "list", - _("List locally cached images")) - requires_template_dir(parser) - - parser.add_argument("-s","--source", - help=3D_("Name of the template source")) - - parser.set_defaults(func=3Dlist_cached) - -def main(): - parser =3D argparse.ArgumentParser(description=3D"Sandbox Container Im= age Tool") - - requires_debug(parser) - - subparser =3D parser.add_subparsers(help=3D_("commands")) - subparser.required =3D True - subparser.dest =3D "command" - gen_purge_args(subparser) - gen_prepare_args(subparser) - gen_run_args(subparser) - gen_list_args(subparser) - - args =3D parser.parse_args() - if args.debug: - args.func(args) - sys.exit(0) - else: - try: - args.func(args) - sys.exit(0) - except KeyboardInterrupt as e: - sys.exit(0) - except ValueError as e: - sys.stderr.write("%s: %s\n" % (sys.argv[0], e)) - sys.stderr.flush() - sys.exit(1) - except IOError as e: - sys.stderr.write("%s: %s\n" % (sys.argv[0], e.filename)) - sys.stderr.flush() - sys.exit(1) - except OSError as e: - sys.stderr.write("%s: %s\n" % (sys.argv[0], e)) - sys.stderr.flush() - sys.exit(1) - except Exception as e: - print (e) - sys.exit(1) diff --git a/libvirt-sandbox/image/sources/Makefile.am b/libvirt-sandbox/im= age/sources/Makefile.am deleted file mode 100644 index 817baa0..0000000 --- a/libvirt-sandbox/image/sources/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ - -pythonimagedir =3D $(pythondir)/libvirt_sandbox/image/sources -pythonimage_DATA =3D \ - __init__.py \ - base.py \ - docker.py \ - virtbuilder.py \ - $(NULL) - -EXTRA_DIST =3D $(pythonimage_DATA) diff --git a/libvirt-sandbox/image/sources/__init__.py b/libvirt-sandbox/im= age/sources/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/libvirt-sandbox/image/sources/base.py b/libvirt-sandbox/image/= sources/base.py deleted file mode 100644 index 0fc9243..0000000 --- a/libvirt-sandbox/image/sources/base.py +++ /dev/null @@ -1,160 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015 Universitat Polit=C3=A8cnica de Catalunya. -# Copyright (C) 2015 Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130= 1 USA -# -# Author: Eren Yagdiran - -from abc import ABCMeta, abstractmethod -import subprocess - -class Source(): - '''The Source class defines the base interface for - all image provider source implementations. An image - provide source is able to download templates from - a repository, convert them to a host specific image - format and report commands used to invoke them.''' - - __metaclass__ =3D ABCMeta - def __init__(self): - pass - - @abstractmethod - def list_templates(self, templatedir): - """ - :param templatedir: local directory path in which to store the tem= plate - - Get a list of all templates that are locally cached - - :returns: a list of libvirt_sandbox.template.Template objects - """ - pass - - @abstractmethod - def has_template(self, template, templatedir): - """ - :param template: libvirt_sandbox.template.Template object - :param templatedir: local directory path in which to store the tem= plate - - Check if a template has already been created. - """ - pass - - @abstractmethod - def create_template(self, template, templatedir, - connect=3DNone): - """ - :param template: libvirt_sandbox.template.Template object - :param templatedir: local directory path in which to store the tem= plate - :param connect: libvirt connection URI - - 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 - - @abstractmethod - def delete_template(self, template, templatedir): - """ - :param template: libvirt_sandbox.template.Template object - :param templatedir: local directory path from which to delete temp= late - - Delete all local files associated with the template - """ - pass - - @abstractmethod - def get_command(self, template, templatedir, userargs): - """ - :param template: libvirt_sandbox.template.Template object - :param templatedir: local directory path in which templates are st= ored - :param userargs: user specified arguments to run - - Get the command line to invoke in the container. If userargs - is specified, then this should override the default args in - the image""" - pass - - @abstractmethod - def get_disk(self, template, templatedir, imagedir, sandboxname): - """ - :param template: libvirt_sandbox.template.Template object - :param templatedir: local directory path in which to find template - :param imagedir: local directory in which to storage disk image - - Creates an instance private disk image, backed by the content - of a template. - """ - pass - - @abstractmethod - def get_env(self, template, templatedir): - """ - :param template: libvirt_sandbox.template.Template object - :param templatedir: local directory path in which to find template - - Get the dict of environment variables to set - """ - pass - - def post_run(self, template, templatedir, imagename): - """ - :param template: libvirt_sandbox.template.Template object - :param templatedir: local directory path in which to find template - :param imagename: name of the image that just stopped running - - Hook called after the image has been stopped. By default is doesn't - do anything, subclasses can override this to do some additional - cleanup. - """ - pass - - - # Utility functions to share between the sources. - - def format_disk(self,disk,format,connect): - cmd =3D ['virt-sandbox'] - if connect is not None: - cmd.append("-c") - cmd.append(connect) - cmd.append("-p") - params =3D ['--disk=3Dfile:disk_image=3D%s,format=3D%s' %(disk,for= mat), - '/sbin/mkfs.ext3', - '/dev/disk/by-tag/disk_image'] - cmd =3D cmd + params - subprocess.check_call(cmd) - - def extract_tarball(self, diskfile, format, tarfile, connect): - cmd =3D ['virt-sandbox'] - if connect is not None: - cmd.append("-c") - cmd.append(connect) - cmd.append("-p") - compression =3D "" - if tarfile.endswith(".gz"): - compression =3D "z" - params =3D ['-m', - 'host-image:/mnt=3D%s,format=3D%s' % (diskfile, format), - '--', - '/bin/tar', - 'xf%s' % compression, - '%s' % tarfile, - '-C', - '/mnt'] - cmd =3D cmd + params - subprocess.check_call(cmd) diff --git a/libvirt-sandbox/image/sources/docker.py b/libvirt-sandbox/imag= e/sources/docker.py deleted file mode 100755 index eaf41fc..0000000 --- a/libvirt-sandbox/image/sources/docker.py +++ /dev/null @@ -1,690 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015 Universitat Polit=C3=A8cnica de Catalunya. -# Copyright (C) 2015 Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130= 1 USA -# -# Author: Eren Yagdiran -# - -import sys -import json -import traceback -import os -import subprocess -import shutil -import urllib.error -import urllib.parse -import urllib.request -import hashlib -from abc import ABCMeta, abstractmethod -import copy -from libvirt_sandbox.image.template import Template - -from . import base - -class DockerConfParser(): - - def __init__(self,jsonfile): - with open(jsonfile) as json_file: - self.json_data =3D json.load(json_file) - def getCommand(self): - return self.json_data['config']['Cmd'] - def getEntrypoint(self): - return self.json_data['config']['Entrypoint'] - def getEnvs(self): - lst =3D self.json_data['config']['Env'] - if lst is not None and isinstance(lst,list): - return lst - else: - return [] - -class DockerImage(): - - def __init__(self, repo, name, tag=3DNone): - - self.repo =3D repo - self.name =3D name - self.tag =3D tag - - if self.tag is None: - self.tag =3D "latest" - - if self.repo is None: - self.repo =3D "library" - - def __repr__(self): - return "%s/%s,tag=3D%s" % (self.repo, self.name, self.tag) - - @classmethod - def from_template(cls, template): - bits =3D template.path[1:].split("/") - if len(bits) =3D=3D 1: - return cls(repo=3DNone, - name=3Dbits[0], - tag=3Dtemplate.params.get("tag")) - elif len(bits) =3D=3D 2: - return cls(repo=3Dbits[0], - name=3Dbits[1], - tag=3Dtemplate.params.get("tag")) - else: - raise Exception("Expected image name, or repo & image name for= path, not '%s'", - template.path) - - -class DockerAuth(): - - __metaclass__ =3D ABCMeta - def __init__(self): - pass - - @abstractmethod - def prepare_req(self, req): - pass - - @abstractmethod - def process_res(self, res): - pass - - @abstractmethod - def process_err(self, err): - return False - - -class DockerAuthNop(DockerAuth): - - def prepare_req(self, req): - pass - - def process_res(self, res): - pass - - def process_err(self, err): - return False - - -class DockerAuthBasic(DockerAuth): - - def __init__(self, username, password): - self.username =3D username - self.password =3D password - self.token =3D None - - def prepare_req(self, req): - if self.username is not None: - auth =3D base64.encodestring( - '%s:%s' % (self.username, self.password)).replace('\n', '') - - req.add_header("Authorization", "Basic %s" % auth) - - req.add_header("X-Docker-Token", "true") - - def process_res(self, res): - self.token =3D res.info().get('X-Docker-Token') - - def process_err(self, err): - return False - - -class DockerAuthToken(DockerAuth): - - def __init__(self, token): - self.token =3D token - - def prepare_req(self, req): - req.add_header("Authorization", "Token %s" % self.token) - - def process_res(self, res): - pass - - def process_err(self, err): - return False - - -class DockerAuthBearer(DockerAuth): - - def __init__(self): - self.token =3D None - - def prepare_req(self, req): - if self.token is not None: - req.add_header("Authorization", "Bearer %s" % self.token) - - def process_res(self, res): - pass - - def process_err(self, err): - method =3D err.headers.get("WWW-Authenticate", None) - if method is None: - return False - - if not method.startswith("Bearer "): - return False - - challenge =3D method[7:] - - bits =3D challenge.split(",") - attrs =3D {} - for bit in bits: - subbit =3D bit.split("=3D") - attrs[subbit[0]] =3D subbit[1][1:-1] - - url =3D attrs["realm"] - del attrs["realm"] - if "error" in attrs: - del attrs["error"] - - params =3D "&".join([ - "%s=3D%s" % (attr, attrs[attr]) - for attr in attrs.keys() - ]) - if params !=3D "": - url =3D url + "?" + params - - req =3D urllib.request.Request(url=3Durl) - req.add_header("Accept", "application/json") - - res =3D urllib.request.urlopen(req) - data =3D json.loads(res.read()) - self.token =3D data["token"] - return True - - -class DockerRegistry(): - - def __init__(self, uri_base): - - self.uri_base =3D list(urllib.parse.urlparse(uri_base)) - self.auth_handler =3D DockerAuthNop() - - def set_auth_handler(self, auth_handler): - self.auth_handler =3D auth_handler - - def supports_v2(self): - try: - (data, res) =3D self.get_json("/v2/") - ver =3D res.info().get("Docker-Distribution-Api-Version") - except urllib.error.HTTPError as e: - ver =3D e.headers.get("Docker-Distribution-Api-Version", None) - - if ver is None: - return False - return ver.startswith("registry/2") - - def set_server(self, server): - self.uri_base[1] =3D server - - @classmethod - def from_template(cls, template): - protocol =3D template.protocol - hostname =3D template.hostname - port =3D template.port - - if protocol is None: - protocol =3D "https" - if hostname is None: - hostname =3D "index.docker.io" - - if port is None: - server =3D hostname - else: - server =3D "%s:%s" % (hostname, port) - - url =3D urllib.parse.urlunparse((protocol, server, "", None, None,= None)) - - return cls(url) - - def get_url(self, path, headers=3DNone): - url_bits =3D copy.copy(self.uri_base) - url_bits[2] =3D path - url =3D urllib.parse.urlunparse(url_bits) - debug("Fetching %s..." % url) - - req =3D urllib.request.Request(url=3Durl) - - if headers is not None: - for h in headers.keys(): - req.add_header(h, headers[h]) - - self.auth_handler.prepare_req(req) - - try: - res =3D urllib.request.urlopen(req) - self.auth_handler.process_res(res) - return res - except urllib.error.HTTPError as e: - if e.code =3D=3D 401: - retry =3D self.auth_handler.process_err(e) - if retry: - debug("Re-Fetching %s..." % url) - self.auth_handler.prepare_req(req) - res =3D urllib.request.urlopen(req) - self.auth_handler.process_res(res) - return res - else: - debug("Not re-fetching") - raise - else: - raise - - def save_data(self, path, dest, checksum=3DNone): - try: - res =3D self.get_url(path) - - datalen =3D res.info().get("Content-Length") - if datalen is not None: - datalen =3D int(datalen) - - csum =3D None - if checksum is not None: - csum =3D hashlib.sha256() - - pattern =3D [".", "o", "O", "o"] - patternIndex =3D 0 - donelen =3D 0 - - with open(dest, "wb") as f: - while 1: - buf =3D res.read(1024*64) - if not buf: - break - if csum is not None: - csum.update(buf) - f.write(buf) - - if datalen is not None: - donelen =3D donelen + len(buf) - debug("\x1b[s%s (%5d Kb of %5d Kb)\x1b8" % ( - pattern[patternIndex], (donelen/1024), (datale= n/1024) - )) - patternIndex =3D (patternIndex + 1) % 4 - - debug("\x1b[K") - if csum is not None: - csumstr =3D "sha256:" + csum.hexdigest() - if csumstr !=3D checksum: - debug("FAIL checksum '%s' does not match '%s'" % (csum= str, checksum)) - os.remove(dest) - raise IOError("Checksum '%s' for data does not match '= %s'" % (csumstr, checksum)) - debug("OK\n") - return res - except Exception as e: - debug("FAIL %s\n" % str(e)) - raise - - def get_json(self, path): - try: - headers =3D {} - headers["Accept"] =3D "application/json" - res =3D self.get_url(path, headers) - data =3D json.loads(res.read()) - debug("OK\n") - return (data, res) - except Exception as e: - debug("FAIL %s\n" % str(e)) - raise - - -class DockerSource(base.Source): - - def _check_cert_validate(self): - major =3D sys.version_info.major - SSL_WARNING =3D "SSL certificates couldn't be validated by default= . You need to have 2.7.9/3.4.3 or higher" - SSL_WARNING +=3D"\nSee https://bugs.python.org/issue22417\n" - py2_7_9_hexversion =3D 34015728 - py3_4_3_hexversion =3D 50594800 - if (major =3D=3D 2 and sys.hexversion < py2_7_9_hexversion) or (m= ajor =3D=3D 3 and sys.hexversion < py3_4_3_hexversion): - sys.stderr.write(SSL_WARNING) - - def _was_downloaded(self, image, templatedir): - try: - self._get_image_list(image, templatedir) - return True - except Exception: - return False - - def list_templates(self, templatedir): - indexes =3D [] - try: - imagedirs =3D os.listdir(templatedir) - except OSError: - return [] - - for imagetagid in imagedirs: - indexfile =3D templatedir + "/" + imagetagid + "/index.json" - if os.path.exists(indexfile): - with open(indexfile,"r") as f: - index =3D json.load(f) - indexes.append(index) - - return [ - Template(source=3D"docker", - protocol=3DNone, - hostname=3DNone, - port=3DNone, - username=3DNone, - password=3DNone, - path=3D"/%s/%s" % (index.get("repo", "library"), inde= x["name"]), - params=3D{ - "tag": index.get("tag", "latest"), - }) for index in indexes] - - def has_template(self, template, templatedir): - try: - image =3D DockerImage.from_template(template) - configfile, diskfile =3D self._get_template_data(image, templa= tedir) - return os.path.exists(diskfile) - except Exception: - return False - - def download_template(self, image, template, templatedir): - try: - createdFiles =3D [] - createdDirs =3D [] - - self._download_template_impl(image, template, templatedir, cre= atedFiles, createdDirs) - except Exception as e: - for f in createdFiles: - try: - os.remove(f) - except: - pass - for d in createdDirs: - try: - shutil.rmtree(d) - except: - pass - raise - - def _download_template_impl(self, image, template, templatedir, create= dFiles, createdDirs): - self._check_cert_validate() - - registry =3D DockerRegistry.from_template(template) - registry.set_auth_handler(DockerAuthBearer()) - if registry.supports_v2(): - self._download_template_impl_v2(registry, image, template, tem= platedir, createdFiles, createdDirs) - else: - self._download_template_impl_v1(registry, image, template, tem= platedir, createdFiles, createdDirs) - - def _download_template_impl_v1(self, registry, image, template, templa= tedir, createdFiles, createdDirs): - basicauth =3D DockerAuthBasic(template.username, template.password) - registry.set_auth_handler(basicauth) - try: - (data, res) =3D registry.get_json("/v1/repositories/%s/%s/imag= es" % ( - image.repo, image.name, - )) - except urllib.error.HTTPError as e: - raise ValueError(["Image '%s' does not exist" % template]) - - registryendpoint =3D res.info().get('X-Docker-Endpoints') - - if basicauth.token is not None: - registry.set_auth_handler(DockerAuthToken(basicauth.token)) - else: - registry.set_auth_handler(DockerAuthNop()) - - (data, res) =3D registry.get_json("/v1/repositories/%s/%s/tags" %( - image.repo, image.name - )) - - if image.tag not in data: - raise ValueError(["Tag '%s' does not exist for image '%s'" % - (image.tag, template)]) - imagetagid =3D data[image.tag] - - (data, res) =3D registry.get_json("/v1/images/" + imagetagid + "/a= ncestry") - - if data[0] !=3D imagetagid: - raise ValueError(["Expected first layer id '%s' to match image= id '%s'", - data[0], imagetagid]) - - for layerid in data: - layerdir =3D templatedir + "/" + layerid - if not os.path.exists(layerdir): - os.makedirs(layerdir) - createdDirs.append(layerdir) - - jsonfile =3D layerdir + "/template.json" - datafile =3D layerdir + "/template.tar.gz" - - if not os.path.exists(jsonfile) or not os.path.exists(datafile= ): - res =3D registry.save_data("/v1/images/" + layerid + "/jso= n", - jsonfile) - createdFiles.append(jsonfile) - - registry.save_data("/v1/images/" + layerid + "/layer", - datafile) - createdFiles.append(datafile) - - index =3D { - "repo": image.repo, - "name": image.name, - "tag": image.tag, - } - - indexfile =3D templatedir + "/" + imagetagid + "/index.json" - with open(indexfile, "w") as f: - f.write(json.dumps(index)) - - - def _download_template_impl_v2(self, registry, image, template, templa= tedir, createdFiles, createdDirs): - (manifest, res) =3D registry.get_json( "/v2/%s/%s/manifests/%s" % ( - image.repo, image.name, image.tag)) - - layerChecksums =3D [ - layer["blobSum"] for layer in manifest["fsLayers"] - ] - layers =3D [ - json.loads(entry["v1Compatibility"]) for entry in manifest["hi= story"] - ] - - for i in range(len(layerChecksums)): - layerChecksum =3D layerChecksums[i] - config =3D layers[i] - - layerdir =3D templatedir + "/" + config["id"] - if not os.path.exists(layerdir): - os.makedirs(layerdir) - createdDirs.append(layerdir) - - jsonfile =3D layerdir + "/template.json" - datafile =3D layerdir + "/template.tar.gz" - - with open(jsonfile, "w") as fh: - fh.write(json.dumps(config)) - - registry.save_data("/v2/%s/%s/blobs/%s" % ( - image.repo, image.name, layerChecksum), - datafile, checksum=3DlayerChecksum) - - - index =3D { - "repo": image.repo, - "name": image.name, - "tag": image.tag, - } - - indexfile =3D templatedir + "/" + layers[0]["id"] + "/index.json" - with open(indexfile, "w") as f: - f.write(json.dumps(index)) - - - def create_template(self, template, templatedir, connect=3DNone): - image =3D DockerImage.from_template(template) - - if not self._was_downloaded(image, templatedir): - self.download_template(image, template, templatedir) - - imagelist =3D self._get_image_list(image, templatedir) - imagelist.reverse() - - parentImage =3D None - for imagetagid in imagelist: - templateImage =3D templatedir + "/" + imagetagid + "/template.= qcow2" - cmd =3D ["qemu-img","create","-f","qcow2"] - if parentImage is not None: - cmd.append("-o") - cmd.append("backing_fmt=3Dqcow2,backing_file=3D%s" % paren= tImage) - cmd.append(templateImage) - if parentImage is None: - cmd.append("10G") - subprocess.check_call(cmd) - - if parentImage is None: - self.format_disk(templateImage, "qcow2", connect) - - path =3D templatedir + "/" + imagetagid + "/template." - self.extract_tarball(path + "qcow2", - "qcow2", - path + "tar.gz", - connect) - parentImage =3D templateImage - - def _get_image_list(self, image, templatedir): - imageparent =3D {} - imagenames =3D {} - imagedirs =3D [] - try: - imagedirs =3D os.listdir(templatedir) - except OSError: - pass - for imagetagid in imagedirs: - indexfile =3D templatedir + "/" + imagetagid + "/index.json" - if os.path.exists(indexfile): - with open(indexfile,"r") as f: - index =3D json.load(f) - thisimage =3D DockerImage(index.get("repo"), - index["name"], - index.get("tag")) - imagenames[str(thisimage)] =3D imagetagid - jsonfile =3D templatedir + "/" + imagetagid + "/template.json" - if os.path.exists(jsonfile): - with open(jsonfile,"r") as f: - data =3D json.load(f) - parent =3D data.get("parent",None) - if parent: - imageparent[imagetagid] =3D parent - if str(image) not in imagenames: - raise ValueError(["Image %s does not exist locally" % image]) - imagetagid =3D imagenames[str(image)] - imagelist =3D [] - while imagetagid !=3D None: - imagelist.append(imagetagid) - parent =3D imageparent.get(imagetagid,None) - imagetagid =3D parent - return imagelist - - def delete_template(self, template, templatedir): - image =3D DockerImage.from_template(template) - - imageusage =3D {} - imageparent =3D {} - imagenames =3D {} - imagedirs =3D [] - try: - imagedirs =3D os.listdir(templatedir) - except OSError: - pass - for imagetagid in imagedirs: - indexfile =3D templatedir + "/" + imagetagid + "/index.json" - if os.path.exists(indexfile): - with open(indexfile,"r") as f: - index =3D json.load(f) - thisimage =3D DockerImage(index.get("repo"), - index["name"], - index.get("tag")) - imagenames[str(thisimage)] =3D imagetagid - jsonfile =3D templatedir + "/" + imagetagid + "/template.json" - if os.path.exists(jsonfile): - with open(jsonfile,"r") as f: - data =3D json.load(f) - - parent =3D data.get("parent",None) - if parent: - if parent not in imageusage: - imageusage[parent] =3D [] - imageusage[parent].append(imagetagid) - imageparent[imagetagid] =3D parent - - - if str(image) not in imagenames: - raise ValueError(["Image %s does not exist locally" % image]) - imagetagid =3D imagenames[str(image)] - while imagetagid !=3D None: - debug("Remove %s\n" % imagetagid) - parent =3D imageparent.get(imagetagid,None) - - indexfile =3D templatedir + "/" + imagetagid + "/index.json" - if os.path.exists(indexfile): - os.remove(indexfile) - jsonfile =3D templatedir + "/" + imagetagid + "/template.json" - if os.path.exists(jsonfile): - os.remove(jsonfile) - datafile =3D templatedir + "/" + imagetagid + "/template.tar.g= z" - if os.path.exists(datafile): - os.remove(datafile) - imagedir =3D templatedir + "/" + imagetagid - shutil.rmtree(imagedir) - - if parent: - if len(imageusage[parent]) !=3D 1: - debug("Parent %s is shared\n" % parent) - parent =3D None - imagetagid =3D parent - - def _get_template_data(self, image, templatedir): - imageList =3D self._get_image_list(image, templatedir) - toplayer =3D imageList[0] - diskfile =3D templatedir + "/" + toplayer + "/template.qcow2" - configfile =3D templatedir + "/" + toplayer + "/template.json" - return configfile, diskfile - - def get_disk(self, template, templatedir, imagedir, sandboxname): - image =3D DockerImage.from_template(template) - configfile, diskfile =3D self._get_template_data(image, templatedi= r) - tempfile =3D imagedir + "/" + sandboxname.split('/')[-1] + ".qcow2" - if not os.path.exists(imagedir): - os.makedirs(imagedir) - cmd =3D ["qemu-img","create","-q","-f","qcow2"] - cmd.append("-o") - cmd.append("backing_fmt=3Dqcow2,backing_file=3D%s" % diskfile) - cmd.append(tempfile) - subprocess.check_call(cmd) - return tempfile - - def get_command(self, template, templatedir, userargs): - image =3D DockerImage.from_template(template) - configfile, diskfile =3D self._get_template_data(image, templatedi= r) - configParser =3D DockerConfParser(configfile) - cmd =3D configParser.getCommand() - entrypoint =3D configParser.getEntrypoint() - if entrypoint is None: - entrypoint =3D [] - if cmd is None: - cmd =3D [] - if userargs is not None and len(userargs) > 0: - return entrypoint + userargs - else: - return entrypoint + cmd - - def get_env(self, template, templatedir): - image =3D DockerImage.from_template(template) - configfile, diskfile =3D self._get_template_data(image, templatedi= r) - configParser =3D DockerConfParser(configfile) - return configParser.getEnvs() - -def debug(msg): - sys.stderr.write(msg) diff --git a/libvirt-sandbox/image/sources/virtbuilder.py b/libvirt-sandbox= /image/sources/virtbuilder.py deleted file mode 100755 index 1b32083..0000000 --- a/libvirt-sandbox/image/sources/virtbuilder.py +++ /dev/null @@ -1,109 +0,0 @@ -# -# Copyright (C) 2015 SUSE LLC -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130= 1 USA -# -# Author: Cedric Bosdonnat -# - -import os -import os.path -import subprocess - -from . import base -from libvirt_sandbox.image.template import Template - - -class VirtBuilderSource(base.Source): - - def _get_template_name(self, template): - # We shouldn't have '/' in the names, but let's make sure - # nobody can try to alter the folders structure later. - return template.path[1:].replace('/', '_') - - def has_template(self, template, templatedir): - imagepath =3D "%s/%s.qcow2" % (templatedir, template.path) - return os.path.exists(imagepath) - - def create_template(self, template, templatedir, connect=3DNone): - if not os.path.exists(templatedir): - os.makedirs(templatedir) - - # Get the image using virt-builder - templatename =3D self._get_template_name(template) - imagepath_original =3D "%s/%s-original.qcow2" % (templatedir, temp= latename) - imagepath =3D "%s/%s.qcow2" % (templatedir, templatename) - cmd =3D ["virt-builder", templatename, "--no-network", - "-o", imagepath_original, "--format", "qcow2"] - subprocess.check_call(cmd) - - try: - # We need to convert this image into a single partition one. - tarfile =3D "%s/%s.tar" % (templatedir, templatename) - cmd =3D ["virt-tar-out", "-a", imagepath_original, "/", tarfil= e] - subprocess.check_call(cmd) - - cmd =3D ["qemu-img", "create", "-q", "-f", "qcow2", imagepath,= "10G"] - subprocess.check_call(cmd) - - self.format_disk(imagepath, "qcow2", connect) - self.extract_tarball(imagepath, "qcow2", tarfile, connect) - - finally: - os.unlink(imagepath_original) - os.unlink(tarfile) - - def list_templates(self, templatedir): - files =3D [] - try: - imagefiles =3D os.listdir(templatedir) - except OSError: - return [] - - for filename in imagefiles: - if not filename.endswith(".qcow2"): - continue - files.append(filename[0:-6]) - - return [ - Template(source=3D"virt-builder", - protocol=3DNone, - hostname=3DNone, - port=3DNone, - username=3DNone, - password=3DNone, - path=3D"/%s" % filename, - params=3D{}) for filename in files] - - def delete_template(self, template, templatedir): - os.unlink("%s/%s.qcow2" % (templatedir, self._get_template_name(te= mplate))) - - def get_command(self, template, templatedir, userargs): - return userargs - - def get_disk(self,template, templatedir, imagedir, sandboxname): - diskfile =3D "%s/%s.qcow2" % (templatedir, self._get_template_name= (template)) - tempfile =3D imagedir + "/" + sandboxname + ".qcow2" - if not os.path.exists(imagedir): - os.makedirs(imagedir) - cmd =3D ["qemu-img", "create", "-q", - "-f", "qcow2", - "-o", "backing_fmt=3Dqcow2,backing_file=3D%s" % diskfile, - tempfile] - subprocess.check_call(cmd) - return tempfile - - def get_env(self,template, templatedir): - return [] diff --git a/libvirt-sandbox/image/template.py b/libvirt-sandbox/image/temp= late.py deleted file mode 100644 index ab2ea29..0000000 --- a/libvirt-sandbox/image/template.py +++ /dev/null @@ -1,133 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Authors: Daniel P. Berrange -# -# Copyright (C) 2015 Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -import urllib.parse -import importlib -import re - -class Template(object): - - def __init__(self, - source, protocol, - hostname, port, - username, password, - path, params): - """ - :param source: template source name - :param protocol: network transport protocol or None - :param hostname: registry hostname or None - :param port: registry port or None - :param username: username or None - :param password: password or None - :param path: template path identifier - :param params: template parameters - - docker:///ubuntu - - docker+https://index.docker.io/ubuntu?tag=3Dlatest - - virt-builder:///fedora-20 - """ - - self.source =3D source - self.protocol =3D protocol - self.hostname =3D hostname - self.port =3D port - self.username =3D username - self.password =3D password - self.path =3D path - self.params =3D params - if self.params is None: - self.params =3D {} - - @classmethod - def _get_source_impl(klass, source): - try: - p =3D re.compile("\W") - sourcemod =3D "".join(p.split(source)) - sourcename =3D "".join([i.capitalize() for i in p.split(source= )]) - - mod =3D importlib.import_module( - "libvirt_sandbox.image.sources." + sourcemod) - classname =3D sourcename + "Source" - classimpl =3D getattr(mod, classname) - return classimpl() - except Exception as e: - print (e) - raise Exception("Invalid source: '%s'" % source) - - def get_source_impl(self): - if self.source =3D=3D "": - raise Exception("Missing scheme in image URI") - - return self._get_source_impl(self.source) - - def __repr__(self): - if self.protocol is not None: - scheme =3D self.source + "+" + self.protocol - else: - scheme =3D self.source - if self.hostname: - if self.port: - netloc =3D "%s:%d" % (self.hostname, self.port) - else: - netloc =3D self.hostname - - if self.username: - if self.password: - auth =3D self.username + ":" + self.password - else: - auth =3D self.username - netloc =3D auth + "@" + netloc - else: - netloc =3D None - - query =3D "&".join([key + "=3D" + self.params[key] for key in self= .params.keys()]) - ret =3D urllib.parse.urlunparse((scheme, netloc, self.path, None, = query, None)) - return ret - - @classmethod - def from_uri(klass, uri): - o =3D urllib.parse.urlparse(uri) - - idx =3D o.scheme.find("+") - if idx =3D=3D -1: - source =3D o.scheme - protocol =3D None - else: - source =3D o.scheme[0:idx] - protocol =3D o.scheme[idx + 1:] - - query =3D {} - if o.query is not None and o.query !=3D "": - for param in o.query.split("&"): - (key, val) =3D param.split("=3D") - query[key] =3D val - return klass(source, protocol, - o.hostname, o.port, - o.username, o.password, - o.path, query) - - @classmethod - def get_all(klass, source, templatedir): - impl =3D klass._get_source_impl(source) - - return impl.list_templates(templatedir) diff --git a/m4/virt-win32.m4 b/m4/virt-win32.m4 index d088ce8..8b908e7 100644 --- a/m4/virt-win32.m4 +++ b/m4/virt-win32.m4 @@ -4,15 +4,11 @@ AC_DEFUN([LIBVIRT_SANDBOX_WIN32],[ dnl for now since I'm not supporting mingw at present. - RWMJ CYGWIN_EXTRA_LDFLAGS=3D CYGWIN_EXTRA_LIBADD=3D - CYGWIN_EXTRA_PYTHON_LIBADD=3D MINGW_EXTRA_LDFLAGS=3D case "$host" in *-*-cygwin*) CYGWIN_EXTRA_LDFLAGS=3D"-no-undefined" CYGWIN_EXTRA_LIBADD=3D"${INTLLIBS}" - if test "x$PYTHON_VERSION" !=3D "x"; then - CYGWIN_EXTRA_PYTHON_LIBADD=3D"-L/usr/lib/python${PYTHON_VERSION}= /config -lpython${PYTHON_VERSION}" - fi ;; *-*-mingw*) MINGW_EXTRA_LDFLAGS=3D"-no-undefined" @@ -20,6 +16,5 @@ AC_DEFUN([LIBVIRT_SANDBOX_WIN32],[ esac AC_SUBST([CYGWIN_EXTRA_LDFLAGS]) AC_SUBST([CYGWIN_EXTRA_LIBADD]) - AC_SUBST([CYGWIN_EXTRA_PYTHON_LIBADD]) AC_SUBST([MINGW_EXTRA_LDFLAGS]) ]) --=20 2.14.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list