Exemple #1
0
    def _read_local_rpm(self, path):
        # Read the rpm header from the local file
        hdr = None
        try:
            with open(path, 'rb') as rpm_fd:
                ts = rpm.TransactionSet()
                # Don't check package signatures before installation, which will
                # fail unless we have the signing key for the target OS
                # installed locally. We implicitly trust these packages.
                ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
                hdr = ts.hdrFromFdno(rpm_fd)

                return Package(hdr[u'NAME'], hdr[u'EPOCH'], hdr[u'VERSION'],
                               hdr[u'RELEASE'], hdr[u'ARCH'])
        except IOError as e:
            # Display an additional warning to the user for any error other
            # than file missing
            if e.errno != errno.ENOENT:
                self._logger.warn(_(u'Unable to open local file '
                                    u'{path}: {error}').
                                    format(path=path, error=e.message))
        except rpm.error as e:
            self._logger.warn(_(u'Unable to read rpm package header from '
                                u'{path}').format(path=path))

        return None
Exemple #2
0
        def _get_default():
            '''Return the grub path of the default kernel, or None if there is
            no valid default kernel'''

            try:
                default_str = h.aug_get(u'/files{}/default'.format(grub_conf))
            except GuestFSException:
                return None # We don't care if there is no default

            try:
                default_int = int(default_str)
            except ValueError:
                self._logger.info(_(u'{path} contains invalid default: '
                                    u'{default').
                                    format(path=grub_conf, default=default_str))
                return None

            # Grub indices are zero-based, augeas is 1-based
            default_aug = (u'/files{}/title[{}]/kernel'.
                            format(grub_conf, default_int + 1))

            try:
                return h.aug_get(default_aug)
            except GuestFSException:
                self._logger.info(_(u'grub refers to default kernel {index}, '
                                    u'which doesn\'t exist').
                                  format(index=default_int))
                return None
Exemple #3
0
    def _remove_libs(self):
        h = self._h

        replaced = []

        with Network(h):
            for lib in self._vmw_libs:
                nevra = str(Package.from_guestfs_app(lib))
                name = lib[u'app2_name']

                # Get the list of provides for the library package.
                try:
                    provides = set([i.strip() for i in
                                    h.command_lines([u'rpm', u'-q',
                                                     u'--provides', nevra])

                                    # The packages explicitly provide
                                    # themselves.  Filter this out
                                    if name not in i])
                except GuestfsException as ex:
                    self._logger.warn(_(u'Error getting rpm provides for '
                                        u'{package}: {error}').
                                      format(package = nevra,
                                             error = ex.message))
                    continue

                # Install the dependencies with yum. We use yum explicitly
                # here, as up2date wouldn't work anyway and local install is
                # impractical due to the large number of required
                # dependencies out of our control.
                try:
                    alts = set([i.strip() for i in
                                h.command_lines(list(chain([u'yum', u'-q',
                                                            u'resolvedep'],
                                                           provides)))])
                except GuestfsException as ex:
                    self._logger.warn(
                        _(u'Error resolving depencies for '
                          u'{packages}: {error}').
                        format(packages = u', '.join(list(provides)),
                               error = ex.message))
                    continue

                if len(alts) > 0:
                    try:
                        h.command(u'yum', u'install', u'-y', list(alts))
                    except GuestfsException as ex:
                        self._logger.warn(
                            _(u'Error installing replacement packages for '
                              u'{package} ({replacements}): {error}').
                            format(package = nevra,
                                   replacements = u', '.join(list(alts)),
                                   error = ex.message))
                        continue

                replaced.append(nevra)

        return replaced
Exemple #4
0
    def _get_installed(self, name, arch=None):
        if arch is None:
            search = name
        else:
            search = u'{}.{}'.format(name, arch)

        rpmcmd = [u'rpm', u'-q', u'--qf',
                  ur'%{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n', search]

        try:
            output = self._h.command_lines(rpmcmd)
        except GuestFSException:
            # RPM command returned non-zero. This might be because there was
            # actually an error, or might just be because the package isn't
            # installed.
            # Unfortunately, rpm sent its error to stdout instead of stderr,
            # and command_lines only gives us stderr in $@. To get round this
            # we execute the command again, sending all output to stdout and
            # ignoring failure. If the output contains 'not installed', we'll
            # assume it's not a real error.

            cmd = (u'LANG=C ' +
                   u' '.join([u"'"+i+u"'" for i in rpmcmd]) + u' 2>&1 ||:')
            error = self._h.sh(cmd)

            if re.search(ur'not installed', error):
                return

            raise ConversionError(
                _(u'Error running {command} in guest: {msg}').
                format(command=cmd, msg=error))
Exemple #5
0
    def _cap_missing_deps(self, name):
        h = self._h
        root = self._root
        db = self._db

        arch = h.inspect_get_arch(root)
        missing = []
        cap = db.match_capability(name, arch, h, root)
        if cap is None:
            self._logger.debug(u'No {} capability found for this root'.
                               format(name))
            return []

        for (pkg, params) in cap.iteritems():
            try:
                target = Package(pkg, evr=params[u'minversion'])
            except Package.InvalidEVR:
                self._logger.info(_(u'Ignoring invalid minversion for package '
                                    u'{name} in virtio capability: {version}').
                                  format(name=pkg,
                                         version=params[u'minversion']))
                target = Package(pkg)

            need = not params[u'ifinstalled']
            for installed in self._get_installed(pkg):
                if installed < target:
                    need = True
                if installed >= target:
                    need = False
                    continue
            if need:
                missing.append(target)

        return missing
Exemple #6
0
    def inspect(self):
        info = {}
        options = []

        h = self._h
        root = self._root

        info[u'hostname'] = h.inspect_get_hostname(root)
        info[u'os'] = h.inspect_get_type(root)
        info[u'distribution'] = h.inspect_get_distro(root)
        info[u'arch'] = h.inspect_get_arch(root)
        info[u'version'] = {
            u'major': h.inspect_get_major_version(root),
            u'minor': h.inspect_get_minor_version(root)
        }

        try:
            self._bootloader = guestconv.converters.grub.detect(
                h, root, self, self._logger)
        except BootLoaderNotFound:
            raise ConversionError(_(u"Didn't detect a bootloader for root "
                                    u'{root}').format(root=self._root))

        bl_disk, bl_props = self._bootloader.inspect()

        return {bl_disk: bl_props}, info, options
Exemple #7
0
    def _is_installed(self, apps):
        h = self._h

        probe = re.compile(ur'virtualbox-guest-additions(?:-.*)$')
        self._vbox_apps = [str(Package.from_guestfs_app(i)) for i in apps
                           if probe.match(i[u'app2_name'])]

        self._vbox_uninstall = None
        config = u'/var/lib/VBoxGuestAdditions/config'
        if h.is_file(config):
            prefix = u'INSTALL_DIR'
            for line in h.read_lines(config):
                if line.startswith(prefix):
                    install_dir = line[len(prefix)::]
                    uninstall = install_dir + u'/uninstall.sh'
                    if h.is_file(uninstall):
                        self._vbox_uninstall = uninstall
                    else:
                        self._logger.warn(_(u'VirtualBox config at {path} says '
                                            u'INSTALL_DIR={installdir}, but '
                                            u"{uninstall} doesn't exist").
                                          format(path=config,
                                                 installdir=install_dir,
                                                 uninstall=uninstall))
                    break

        return len(self._vbox_apps) > 0 or self._vbox_uninstall is not None
Exemple #8
0
 def __init__(self, db_paths):
     self._trees = []
     for path in db_paths:
         try:
             self._trees.append(ET.parse(path))
         except ET.ParseError as e:
             raise DBParseError(_(u'Parse error in %(path)s: %(error)s') % \
                                {u'path': path, u'error': e.message})
Exemple #9
0
    def _inspect_bootloader(self):
        for bl in [GrubLegacy, Grub2EFI, Grub2BIOS]:
            try:
                return bl(self._h, self._root, self._logger)
            except BootLoaderNotFound:
                pass  # Try the next one

        raise ConversionError(_(u"Didn't detect a bootloader for root %(root)s") % {u"root": self._root})
Exemple #10
0
    def get_initrd(self, path):
        for line in h.command_lines([u'grubby', u'--info', path]):
            m = re.match(u'^initrd=(\S+)', line)
            if m is not None:
                return m.group(1)

        raise ConversionError(
            _(u"grubby didn't return an initrd for kernel %(kernel)s") %
            {u'kernel': path})
Exemple #11
0
        def _check_and_uniq(path):
          if path in seen:
              return False

          seen.add(path)

          if not self._h.is_file_opts(path, followsymlinks=True):
              self._logger.warn(_(u"grub refers to {kernel}, which doesn't "
                                  "exist").format(kernel=path))
              return False

          return True
Exemple #12
0
    def check_available(self, pkgs):
        missing = []
        required = []
        self._resolve_required_deps(map(lambda pkg: pkg.name, pkgs), required, missing)

        if len(missing) > 0:
            self._logger.warn(
                _(u'The following files referenced in the configuration are '
                  u'required, but missing: {list}').
                format(list=u' '.join(missing)))
            return False

        return True
Exemple #13
0
    def check_available(self, pkgs):
        for i in pkgs:
            if self._old_packages:
                self._logger.info(_(u'Checking package {pkg} is available via '
                                    u'YUM').format(pkg=str(i)))
                try:
                    self._yum_cmd(i, YumInstaller.LIST)
                    return True
                except YumInstaller.NoPackage:
                    return False
            else:
                # We just want to lookup name.arch
                name_arch = Package(i.name, arch=i.arch)
                self._logger.info(_(u'Checking for latest version of {pkg} '
                                    u'available via YUM').
                                  format(pkg=str(name_arch)))
                output = self._yum_cmd(name_arch, YumInstaller.LIST)

                for line in output:
                    # Look for output lines starting with package name
                    # containing version and source repo
                    m = re.match(ur'{}\s+(\S+)\s+\S+\s*$'.
                                 format(re.escape(str(name_arch))), line)
                    if m is None:
                        continue

                    try:
                        found = Package(i.name, evr=m.group(1))
                    except Package.InvalidEVR:
                        self._logger.debug(u"{}: doesn't look like evr".
                                           format(m.group(1)))
                        continue

                    # Check if this package is new enough
                    self._logger.debug(u'Package {pkg} is available'.
                                       format(pkg=str(found)))
                    if found >= i:
                        return True
                return False
Exemple #14
0
    def inspect(self):
        h = self._h
        root = self._root

        info = {
            u'hostname': h.inspect_get_hostname(root),
            u'os': h.inspect_get_type(root),
            u'distribution': h.inspect_get_distro(root),
            u'arch': h.inspect_get_arch(root),
            u'version': {
                u'major': h.inspect_get_major_version(root),
                u'minor': h.inspect_get_minor_version(root)
            }
        }

        installer = Installer(h, root, self._db, self._logger)

        # Drivers which are always available
        graphics = []
        network = [
            (u'e1000', u'Intel E1000'),
            (u'rtl8139', u'Realtek 8139')
        ]
        block = [
            (u'ide-hd', u'IDE'),
            (u'scsi-hd', u'SCSI')
        ]
        console = [
            (u'vc', _(u'Kernel virtual console')),
            (u'serial', _(u'Serial console'))
        ]

        options = [
            (u'graphics', _(u'Graphics driver'), graphics),
            (u'network', _(u'Network driver'), network),
            (u'block', _(u'Block device driver'), block),
            (u'console', _(u'System Console'), console)
        ]

        if self._check_capability(u'virtio', installer):
            network.append((u'virtio-net', u'VirtIO'))
            block.append((u'virtio-blk', u'VirtIO'))
            console.append((u'virtio-serial', _(u'VirtIO Serial')))

        if self._check_capability(u'cirrus', installer):
            graphics.append((u'cirrus-vga', u'Cirrus'))

        if self._check_capability(u'qxl', installer):
            graphics.append((u'qxl-vga', u'Spice'))

        self._bootloader = self._inspect_bootloader()
        bl_disk, bl_props = self._bootloader.inspect()

        return {bl_disk: bl_props}, info, options
Exemple #15
0
    def convert(self, target):
        if target != 'grub2-bios':
            raise ConversionError(_(u'Cannot convert grub2-efi bootloader to '
                                    u'{target}').format(target=target))

        # For grub2, we:
        #   Turn the EFI partition into a BIOS Boot Partition
        #   Remove the former EFI partition from fstab
        #   Install the non-EFI version of grub
        #   Install grub2 in the BIOS Boot Partition
        #   Regenerate grub.cfg
        h = self._h

        if not self._converter._install_capability('grub2-bios'):
            raise ConversionError(_(u'Failed to install bios version of grub2'))

        # Relabel the EFI boot partition as a BIOS boot partition
        h.part_set_gpt_type(self.device, 1,
                            u'21686148-6449-6E6F-744E-656564454649')

        # Delete the fstab entry for the EFI boot partition
        for node in h.aug_match(u"/files/etc/fstab/*[file = '/boot/efi']"):
            h.aug_rm(node)

        try:
            h.aug_save()
        except GuestfsException as ex:
            augeas_error(h, ex)

        GRUB2_BIOS_CFG = u'/boot/grub2/grub.cfg'

        h.command([u'grub2-install', self.device])
        h.command([u'grub2-mkconfig', u'-o', GRUB2_BIOS_CFG])

        return Grub2BIOS(h, self._root, self._converter, self._logger,
                         GRUB2_BIOS_CFG)
Exemple #16
0
            def _resolve_default(default):
                # Is default an index or a menuentry title?
                try:
                    default_int = int(default)

                    # Get the kernel from the default'th menuentry
                    i = 0
                    for title, kernel in _list_menuentries():
                        if i == default_int:
                            return kernel
                        i += 1

                    self._logger.warn(_(u'Default kernel with index {index} '
                                        u'not found').format(index=default_int))
                except ValueError:
                    # Not an integer: find the menuentry with title == default
                    for title, kernel in _list_menuentries():
                        if title == default:
                            return kernel

                    self._logger.warn(_(u'Default kernel \'{title}\' not '
                                        u'found').format(title=default))

                return None
Exemple #17
0
    def _remove(self):
        h = self._h

        if len(self._vbox_apps) > 0:
            _remove_applications(h, self._vbox_apps)

        if self._vbox_uninstall is not None:
            try:
                h.command([self._vbox_uninstall])
                h.aug_load()
            except GuestFSException as ex:
                self._logger.warn(_(u'VirtualBox Guest Additions '
                                    u'were detected, but '
                                    u'uninstallation failed. The '
                                    u'error message was: {error}').
                                  format(error=ex.message))
Exemple #18
0
    def _report_missing_app(self, name, arch, missing):
        h = self._h
        root = self._root

        os = h.inspect_get_type(root)
        distro = h.inspect_get_distro(root)
        version = u'{}.{}'.format(h.inspect_get_major_version(root),
                                  h.inspect_get_minor_version(root))

        self._logger.warn(_(u"Didn't find {name} app for os={os} "
                            u'distro={distro} version={version} '
                            u'arch={arch}').
                            format(name=name, os=os, distro=distro,
                                   version=version, arch=arch))

        missing.append(u'app:'+name)
Exemple #19
0
    def list_kernels(self):
        h = self._h
        grub_conf = self._grub_conf
        grub_fs = self._grub_fs

        # List all kernels from grub.conf in the order that grub would try them

        paths = []
        # Try to add the default kernel to the front of the list. This will
        # fail if there is no default, or if the default specifies a
        # non-existent kernel.
        try:
            default = h.aug_get(u'/files%s/default' % grub_conf)
            paths.extend(
                h.aug_match(u'/files%s/title[%s]/kernel' % (grub_conf, default))
            )
        except GuestFSException:
            pass # We don't care

        # Add kernel paths from grub.conf in the order they are listed. This
        # will add the default kernel twice, but it doesn't matter.
        try:
            paths.extend(h.aug_match(u'/files%s/title/kernel' % grub_conf))
        except GuestFSException as ex:
            augeas_error(h, ex)

        # Fetch the value of all detected kernels, and sanity check them
        kernels = []
        checked = {}
        for path in paths:
            if path in checked:
                continue
            checked[path] = True

            try:
                kernel = grub_fs + h.aug_get(path)
            except GuestFSException as ex:
                augeas_error(h, ex)

            if h.exists(kernel):
                kernels.append(kernel)
            else:
                self._logger.warn(_(u"grub refers to %(kernel)s, which doesn't exist") %
                                  {u'kernel': kernel})

        return kernels
Exemple #20
0
    def convert(self, target):
        if target != 'grub-bios':
            raise ConversionError(_(u'Cannot convert grub-efi bootloader to '
                                    u'{target}').format(target=target))

        grub_conf = u'/boot/grub/grub.conf'

        h = self._h
        h.cp(self._cfg, grub_conf)
        h.ln_sf(grub_conf, u'/etc/grub.conf')

        # Reload to push up grub.conf in its new location
        h.aug_load()

        h.command([u'grub-install', self.device])

        return GrubBIOS(self._h, self._root, self._converter, self._logger,
                        grub_conf)
Exemple #21
0
    def match_app(self, name, arch, h, root):
        """Match the app with name and arch for the given root."""
        app, path_root = self._match_element(u'app', name, arch, h, root)
        if app is None:
            return (None, None)

        paths = app.xpath(u'path[1]')
        if len(paths) == 0:
            raise DBParseError(_(u'app {name} for root {root} is missing '
                                 u'a path element').
                               format(name=name, root=root))
        if path_root:
            path = os.path.join(path_root, paths[0].text.strip())
        else:
            path = paths[0].text.strip()

        deps = []
        for dep in app.xpath(u'dep'):
            deps.append(dep.text.strip())

        return (path, deps)
Exemple #22
0
        def _list_menuentries():
            '''Return title and kernel for each menuentry in grub config, in
            order'''

            lines = iter(h.read_lines(self._cfg))
            for line in lines:
                # Is this a menu entry
                m = re.match(u"\s*menuentry\s+(?:'([^']*)')?", line)
                if m is None:
                    continue

                # Try to find a title
                title = m.group(1) # May be None

                # Try to find an open curly
                while re.search(u'{\s*$', line) is None:
                    try:
                        line = lines.next()
                    except StopIteration:
                        self._logger.warn(_(u'Unexpected EOF in {path}: '
                                            u'menuentry with no \'{\''))
                        return

                # line is now the line containing the close curly.
                # This for loop will continue to iterate starting at the line
                # following the close curly
                kernel = None
                for line in lines:
                    m = re.match(u'\s*linux(?:efi)?\s+(\S+)\s', line)
                    if m is None:
                        if re.search(u'}\s*$', line):
                            break    
                        else:
                            continue

                    kernel = m.group(1)

                # We're now at either a close curly or EOF
                # title and kernel could both be None
                yield (title, kernel)
Exemple #23
0
    def _remove(self):
        h = self._h

        for repo in self._vmw_repos:
            h.aug_set(repo + u'/enabled', 0)
            try:
                h.aug_save()
            except GuestFSException as ex:
                augeas_error(h, ex)

        remove = False

        if len(self._vmw_libs) > 0:
            # It's important that we did aug_save() above, or resolvedep might
            # return the same vmware packages we're trying to get rid of
            libs = self._remove_libs()
        else:
            libs = []

        if len(self._vmw_remove) > 0 or len(libs) > 0:
            _remove_applications(h, chain(self._vmw_remove, libs))

        # VMwareTools may have been installed from tarball, in which case the
        # above won't detect it. Look for the uninstall tool, and run it if
        # it's present.
        #
        # Note that it's important we do this early in the conversion process,
        # as this uninstallation script naively overwrites configuration files
        # with versions it cached prior to installation.
        vmwaretools = u'/usr/bin/vmware-uninstall-tools.pl'
        if h.is_file(vmwaretools):
            try:
                h.command([vmwaretools])
            except GuestfsException as ex:
                self._logger.warn(_(u'VMware Tools was detected, but '
                                    u'uninstallation failed: {error}').
                                  format(error = ex.message))
            h.aug_load()
Exemple #24
0
    def _check_capability(self, name, installer):
        h = self._h
        root = self._root
        db = self._db

        arch = h.inspect_get_arch(root)
        check = []
        cap = db.match_capability(name, arch, h, root)
        if cap is None:
            self._logger.debug(u'No {} capability found for this root'.
                               format(name))
            return False

        for (pkg, params) in cap.iteritems():
            try:
                target = Package(pkg, evr=params[u'minversion'])
            except Package.InvalidEVR:
                self._logger.info(_(u'Ignoring invalid minversion for package '
                                    u'{name} in virtio capability: {version}').
                                  format(name=pkg,
                                         version=params[u'minversion']))
                target = Package(pkg)

            need = not params[u'ifinstalled']
            for installed in installer.get_installed(pkg):
                if installed < target:
                    need = True
                if installed >= target:
                    need = False
                    continue
            if need:
                check.append(target)

        # Success if we've got nothing to check
        if len(check) == 0:
            return True

        return installer.check_available(check)
Exemple #25
0
 def __init__(self, h, root, logger, apps):
     super(HVCitrixFV, self).__init__(u'citrixfv',
                                      _(u'Citrix Fully Virtualised'),
                                      h, root, logger, apps)
Exemple #26
0
 def convert(self, bootloaders, options):
     self._logger.info(_(u'Converting root %(name)s') %
                       {u'name': self._root})
Exemple #27
0
 def _missing_deps(name, missing):
     '''Utility function for reporting missing dependencies'''
     l = u', '.join([str(i) for i in missing])
     self._logger.info(_(u'Missing dependencies for {name}: {missing}')
                       .format(name=name, missing=l))
Exemple #28
0
    def inspect(self):
        h = self._h
        root = self._root

        # Initialise supported drivers
        options = [
            (u'hypervisor', _(u'Hypervisor support'), []),
            (u'graphics', _(u'Graphics driver'), []),
            (u'network', _(u'Network driver'), [
                (u'e1000', u'Intel E1000'),
                (u'rtl8139', u'Realtek 8139')
            ]),
            (u'block', _(u'Block device driver'), [
                (u'ide-hd', u'IDE'),
                (u'scsi-hd', u'SCSI')
            ]),
            (u'console', _(u'System Console'), [
                (u'vc', _(u'Kernel virtual console')),
                (u'serial', _(u'Serial console'))
            ])
        ]

        drivers = {}
        for name, desc, values in options:
            drivers[name] = values

        def _missing_deps(name, missing):
            '''Utility function for reporting missing dependencies'''
            l = u', '.join([str(i) for i in missing])
            self._logger.info(_(u'Missing dependencies for {name}: {missing}')
                              .format(name=name, missing=l))

        # Detect supported hypervisors
        self._hypervisors = {}
        apps = h.inspect_list_applications2(root)
        for klass in [HVKVM,
                      HVXenPV, HVXenFV,
                      HVVBox,
                      HVVMware,
                      HVCitrixFV, HVCitrixPV]:
            hv = klass(h, root, self._logger, apps)
            if hv.is_available():
                self._hypervisors[hv.key] = klass
                drivers[u'hypervisor'].append((hv.key, hv.description))

        # Detect supported graphics hardware
        for driver, desc in [(u'qxl-vga', u'Spice'),
                             (u'cirrus-vga', u'Cirrus')]:
            deps = self._cap_missing_deps(driver)
            if len(deps) == 0:
                drivers[u'graphics'].append((driver, desc))
            else:
                _missing_deps(driver, deps)

        # Detect VirtIO
        virtio_deps = self._cap_missing_deps(u'virtio')
        if len(virtio_deps) == 0:
            drivers[u'network'].append((u'virtio-net', u'VirtIO'))
            drivers[u'block'].append((u'virtio-blk', u'VirtIO'))
            drivers[u'console'].append((u'virtio-serial', _(u'VirtIO Serial')))
        else:
            _missing_deps(u'virtio', virtio_deps)

        # Info section of inspection
        info = {
            u'hostname': h.inspect_get_hostname(root),
            u'os': h.inspect_get_type(root),
            u'distribution': h.inspect_get_distro(root),
            u'arch': h.inspect_get_arch(root),
            u'version': {
                u'major': h.inspect_get_major_version(root),
                u'minor': h.inspect_get_minor_version(root)
            }
        }

        try:
            self._bootloader = guestconv.converters.grub.detect(
                h, root, self, self._logger)
        except BootLoaderNotFound:
            raise ConversionError(_(u"Didn't detect a bootloader for root "
                                    u'{root}').format(root=self._root))

        # Persist detected driver support for later sanity checking
        self._drivers = {}
        for driver in drivers:
            self._drivers[driver] = set([i[0] for i in drivers[driver]])

        return ({self._bootloader.device: self._bootloader.inspect()},
                info, options)


        raise ConversionError(_(u"Didn't detect a bootloader for root %(root)s") %
                              {u'root': self._root})
Exemple #29
0
 def convert(self, bootloaders, options):
     self._logger.info(_(u"Converting root %(name)s") % {u"name": self._root})
Exemple #30
0
 def __init__(self, h, root, logger, apps):
     super(HVCitrixPV, self).__init__(u'citrixpv',
                                      _(u'Citrix Paravirtualised'),
                                      h, root, logger, apps)