示例#1
0
def Ubuntu(host, force=False):
    unix.isvalid(host)

    root = host.__dict__.get('root', None)

    instances = unix.instances(host)
    if len(instances) >= 1:
        host = Linux(getattr(unix, instances[0]).clone(host))
    if root:
        host = Chroot(host, root)
    host = Debian(host)

    if host.distrib[0] != 'Ubuntu' and not force:
        raise LinuxError('invalid distrib')

    class UbuntuHost(host.__class__):
        def __init__(self):
            #            kwargs = {'root': root} if root else {}
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)

        @property
        def services(self):
            version = float(self.distrib[1])
            if version <= 9.04:
                service_handler = Initd
            elif 9.10 <= version <= 14.10:
                service_handler = Upstart
            elif version >= 15.04:
                servivce_handler = Systemd
            return service_handler(weakref.ref(self)())

    return UbuntuHost()
示例#2
0
def Arch(host, force=False):
    unix.isvalid(host)

    root = host.__dict__.get('root', None)

    instances = unix.instances(host)
    if len(instances) >= 1:
        host = Linux(getattr(unix, instances[0]).clone(host))
    if root:
        host = Chroot(host, root)

    if host.distrib[0] != 'Arch' and not force:
        raise LinuxError('invalid distrib')

    class ArchHost(host.__class__):
        def __init__(self):
            kwargs = {'root': root} if root else {}
            host.__class__.__init__(self, **kwargs)
            self.__dict__.update(host.__dict__)

        @property
        def hostname(self):
            with self.open(_HOSTNAMEFILE) as fhandler:
                return fhandler.read().decode().strip()

        @hostname.setter
        def hostname(self, value):
            with self.open(_HOSTNAMEFILE, 'w') as fhandler:
                fhandler.write(value)

        @property
        def services(self):
            return Systemd(weakref.ref(self)())

    return ArchHost()
示例#3
0
def Ubuntu(host, force=False):
    unix.isvalid(host)

    root = host.__dict__.get('root', None)

    instances = unix.instances(host)
    if len(instances) >= 1:
        host = Linux(getattr(unix, instances[0]).clone(host))
    if root:
        host = Chroot(host, root)
    host = Debian(host)

    if host.distrib[0] != 'Ubuntu' and not force:
        raise LinuxError('invalid distrib')

    class UbuntuHost(host.__class__):
        def __init__(self):
#            kwargs = {'root': root} if root else {}
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)

        @property
        def services(self):
            version = float(self.distrib[1])
            if version <= 9.04:
                service_handler = Initd
            elif 9.10 <= version <= 14.10:
                service_handler = Upstart
            elif version >= 15.04:
                servivce_handler = Systemd
            return service_handler(weakref.ref(self)())

    return UbuntuHost()
示例#4
0
def Debian(host, force=False):
    unix.isvalid(host)

    root = host.__dict__.get('root', None)

    instances = unix.instances(host)
    if len(instances) >= 1:
        host = Linux(getattr(unix, instances[0]).clone(host))
    if root:
        host = Chroot(host, root)

    if host.distrib[0] not in DISTRIBS and not force:
        raise LinuxError('invalid distrib')

    class DebianHost(host.__class__):
        def __init__(self):
            kwargs = {'root': root} if root else {}
            host.__class__.__init__(self, **kwargs)
            self.__dict__.update(host.__dict__)

        def list_packages(self):
            return self.execute('dpkg -l')

        @property
        def hostname(self):
            with self.open(_HOSTNAMEFILE) as fhandler:
                return fhandler.read().decode().strip()

        @hostname.setter
        def hostname(self, value):
            with self.open(_HOSTNAMEFILE, 'w') as fhandler:
                fhandler.write(value)

        @property
        def network(self):
            return _Network(weakref.ref(self)())

        @property
        def apt(self):
            return _APT(weakref.ref(self)())

        @property
        def services(self):
            major_version = int(self.distrib[1][0])
            if major_version <= 5:
                service_handler = Initd
            elif 6 <= major_version <= 7:
                service_handler = Upstart
            elif major_version >= 8:
                service_handler = Systemd
            return service_handler(weakref.ref(self)())

    return DebianHost()
示例#5
0
def Debian(host, force=False):
    unix.isvalid(host)

    root = host.__dict__.get('root', None)

    instances = unix.instances(host)
    if len(instances) >= 1:
        host = Linux(getattr(unix, instances[0]).clone(host))
    if root:
        host = Chroot(host, root)

    if host.distrib[0] not in DISTRIBS and not force:
        raise LinuxError('invalid distrib')

    class DebianHost(host.__class__):
        def __init__(self):
            kwargs = {'root': root} if root else {}
            host.__class__.__init__(self, **kwargs)
            self.__dict__.update(host.__dict__)

        def list_packages(self):
            return self.execute('dpkg -l')

        @property
        def hostname(self):
            with self.open(_HOSTNAMEFILE) as fhandler:
                return fhandler.read().decode().strip()

        @hostname.setter
        def hostname(self, value):
            with self.open(_HOSTNAMEFILE, 'w') as fhandler:
                fhandler.write(value)

        @property
        def network(self):
            return _Network(weakref.ref(self)())

        @property
        def apt(self):
            return _APT(weakref.ref(self)())

        @property
        def services(self):
            major_version = int(self.distrib[1][0])
            if major_version <= 5:
                service_handler = Initd
            elif 6 <= major_version <= 7:
                service_handler = Upstart
            elif major_version >= 8:
                service_handler = Systemd
            return service_handler(weakref.ref(self)())

    return DebianHost()
示例#6
0
def RedHat(host, force=False):
    unix.isvalid(host)

    root = host.__dict__.get('root', None)

    instances = unix.instances(host)
    if len(instances) >= 1:
        host = Linux(getattr(unix, instances[0]).clone(host))
    if root:
        host = Chroot(host, root)

    if host.distrib[0] not in DISTRIBS and not force:
        raise LinuxError('invalid distrib')

    class RedHatHost(host.__class__):
        def __init__(self):
            kwargs = {'root': root} if root else {}
            host.__class__.__init__(self, **kwargs)
            self.__dict__.update(host.__dict__)

        def list_packages(self):
            return self.execute('dpkg -l')

        @property
        def hostname(self):
            with self.open(_NETFILE) as fhandler:
                for line in fhandler.read().splitlines():
                    attr, value = line.split('=')
                    if attr == 'HOSTNAME':
                        return value

        @hostname.setter
        def hostname(self, value):
            contnet = ''
            with self.open(_NETFILE) as fhandler:
                content = re.sub('HOSTNAME=[^\n]*',
                                 'HOSTNAME=%s\n' % value,
                                 fhandler.read())
            with self.open(_NETFILE, 'w') as fhandler:
                fhandler.write(content)

        @property
        def services(self):
            major_version = int(self.distrib[1][0])
            if major_version <= 5:
                service_handler = Initd
            elif major_version == 6:
                service_handler = Upstart
            elif major_version >= 7:
                service_handler = Systemd
            return service_handler(weakref.ref(self)())

    return RedHatHost()
示例#7
0
def RedHat(host, force=False):
    unix.isvalid(host)

    root = host.__dict__.get('root', None)

    instances = unix.instances(host)
    if len(instances) >= 1:
        host = Linux(getattr(unix, instances[0]).clone(host))
    if root:
        host = Chroot(host, root)

    if host.distrib[0] not in DISTRIBS and not force:
        raise LinuxError('invalid distrib')

    class RedHatHost(host.__class__):
        def __init__(self):
            kwargs = {'root': root} if root else {}
            host.__class__.__init__(self, **kwargs)
            self.__dict__.update(host.__dict__)

        def list_packages(self):
            return self.execute('dpkg -l')

        @property
        def hostname(self):
            with self.open(_NETFILE) as fhandler:
                for line in fhandler.read().splitlines():
                    attr, value = line.split('=')
                    if attr == 'HOSTNAME':
                        return value

        @hostname.setter
        def hostname(self, value):
            contnet = ''
            with self.open(_NETFILE) as fhandler:
                content = re.sub('HOSTNAME=[^\n]*', 'HOSTNAME=%s\n' % value,
                                 fhandler.read())
            with self.open(_NETFILE, 'w') as fhandler:
                fhandler.write(content)

        @property
        def services(self):
            major_version = int(self.distrib[1][0])
            if major_version <= 5:
                service_handler = Initd
            elif major_version == 6:
                service_handler = Upstart
            elif major_version >= 7:
                service_handler = Systemd
            return service_handler(weakref.ref(self)())

    return RedHatHost()
示例#8
0
def Linux(host):
    unix.isvalid(host)
    host.is_connected()

    instances = unix.instances(host)
    if len(instances) > 1:
        host = getattr(unix, instances[0]).clone(host)

    host_type = host.type
    if host_type != 'linux':
        raise LinuxError('this is not a Linux host (%s)' % host_type)

    class LinuxHost(host.__class__):
        def __init__(self):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)

        @property
        def distrib(self):
            return distribution(self)

        @property
        def chrooted(self):
            return False

        @property
        def conf(self):
            return _Conf(weakref.ref(self)())

        @property
        def memory(self):
            return _Memory(weakref.ref(self)())

        def stat(self, filepath):
            return _Stat(weakref.ref(self)(), filepath)

        @property
        def modules(self):
            return _Modules(weakref.ref(self)())

        @property
        def sysctl(self):
            return _Sysctl(weakref.ref(self)())

        @property
        def fstab(self):
            return _Fstab(weakref.ref(self)())

    return LinuxHost()
示例#9
0
def Linux(host):
    unix.isvalid(host)
    host.is_connected()

    instances = unix.instances(host)
    if len(instances) > 1:
        host = getattr(unix, instances[0]).clone(host)

    host_type = host.type
    if host_type != 'linux':
        raise LinuxError('this is not a Linux host (%s)' % host_type)

    class LinuxHost(host.__class__):
        def __init__(self):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)

        @property
        def distrib(self):
            return distribution(self)

        @property
        def chrooted(self):
            return False

        @property
        def conf(self):
            return _Conf(weakref.ref(self)())

        @property
        def memory(self):
            return _Memory(weakref.ref(self)())

        def stat(self, filepath):
            return _Stat(weakref.ref(self)(), filepath)

        @property
        def modules(self):
            return _Modules(weakref.ref(self)())

        @property
        def sysctl(self):
            return _Sysctl(weakref.ref(self)())

        @property
        def fstab(self):
            return _Fstab(weakref.ref(self)())

    return LinuxHost()
示例#10
0
def CentOS(host, root='', force=False):
    unix.isvalid(host)

    root = host.__dict__.get('root', None)

    instances = unix.instances(host)
    if len(instances) >= 1:
        host = Linux(getattr(unix, instances[0]).clone(host))
    if root:
        host = Chroot(host, root)
    host = RedHat(host)

    if host.distrib[0] != 'CentOS' and not force:
        raise LinuxError('invalid distrib')

    class CentOSHost(host.__class__):
        def __init__(self):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)

    return CentOSHost()
示例#11
0
def Hypervisor(host):
    unix.isvalid(host)

    try:
        host.which('virsh')
    except unix.UnixError:
        raise KvmError("unable to find 'virsh' command, is this a KVM host?")

    class Hypervisor(host.__class__):
        """This object represent an Hypervisor. **host** must be an object of
        type ``unix.Local`` or ``unix.Remote`` (or an object inheriting from
        them).
        """
        def __init__(self):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)
            for control, value in _CONTROLS.items():
                setattr(self, '_%s' % control, value)


        def virsh(self, command, *args, **kwargs):
            """Wrap the execution of the virsh command. It set a control for
            putting options after the virsh **command**. If **parse** control
            is activated, the value of ``stdout`` is returned or **KvmError**
            exception is raised.
            """
            if self._ignore_opts:
                for opt in self._ignore_opts:
                    kwargs.update({opt: False})
            with self.set_controls(options_place='after', decode='utf-8'):
                status, stdout, stderr = self.execute('virsh',
                                                      command,
                                                      *args,
                                                      **kwargs)
                # Clean stdout and stderr.
                if stdout:
                    stdout = stdout.rstrip('\n')
                if stderr:
                    stderr = stderr.rstrip('\n')

                if not self._parse:
                    return status, stdout, stderr
                elif not status:
                    raise KvmError(stderr)
                else:
                    stdout = stdout.splitlines()
                    return stdout[:-1] if not stdout[-1] else stdout


        def list_domains(self, **kwargs):
            """List domains. **kwargs** can contains any option supported by the
            virsh command. It can also contains a **state** argument which is a
            list of states for filtering (*all* option is automatically set).
            For compatibility the options ``--table``, ``--name`` and ``--uuid``
            have been disabled.

            Virsh options are (some option may not work according your version):
                * *all*: list all domains
                * *inactive*: list only inactive domains
                * *persistent*: include persistent domains
                * *transient*: include transient domains
                * *autostart*: list autostarting domains
                * *no_autostart*: list not autostarting domains
                * *with_snapshot*: list domains having snapshots
                * *without_snapshort*: list domains not having snapshots
                * *managed_save*:  domains that have managed save state (only
                                   possible if they are in the shut off state,
                                   so you need to specify *inactive* or *all*
                                   to actually list them) will instead show as
                                   saved
                * *with_managed_save*: list domains having a managed save image
                * *without_managed_save*: list domains not having a managed
                                          save image
            """
            # Remove incompatible options between virsh versions.
            kwargs.pop('name', None)
            kwargs.pop('uuid', None)

            # Get states argument (which is not an option of the virsh command).
            states = kwargs.pop('states', [])
            if states:
                kwargs['all'] = True

            # Add virsh options for kwargs.
            virsh_opts = {arg: value for arg, value in kwargs.items() if value}

            # Get domains (filtered on state).
            domains = {}
            with self.set_controls(parse=True):
                stdout = self.virsh('list', **virsh_opts)

                for line in stdout[2:]:
                    line = line.split()
                    (domid, name, state), params = line[:3], line[3:]
                    # Manage state in two words.
                    if state == 'shut':
                        state += ' %s' % params.pop(0)
                    domain = {'id': int(domid) if domid != '-' else -1,
                              'state': state}
                    if 'title' in kwargs:
                        domain['title'] = ' '.join(params) if params else ''
                    domains[name] = domain

            return domains


        def list_networks(self, **kwargs):
            with self.set_controls(parse=True):
                stdout = self.virsh('net-list', **kwargs)
                networks = {}
                for line in stdout[2:]:
                    line = line.split()
                    name, state, autostart = line[:3]
                    net = dict(state=state, autostart=_convert(autostart))
                    if len(line) == 4:
                        net.update(persistent=_convert(line[3]))
                    networks.setdefault(name, net)
            return networks


        def list_interfaces(self, **kwargs):
            with self.set_controls(parse=True):
                stdout = self.virsh('iface-list', **kwargs)
                return {name: {'state': state, 'mac': mac}
                        for line in self.virsh('iface-list', **kwargs)[2:]
                        for name, state, mac in [line.split()]}


        @property
        def image(self):
            return _Image(weakref.ref(self)())



    for property_name, property_methods in _MAPPING.items():
        property_obj = type('_%s' % property_name.capitalize(),
                            (object,),
                            dict(__init__=__init))

        for method_name, method_conf in property_methods.items():
            __add_method(property_obj, method_name, method_conf)
        #    getattr(Hypervisor, method['name']).__doc__ = '\n'.join(method['doc'])

        for method_name in dir(_SELF):
            if method_name.startswith('__%s' % property_name):
                method = method_name.replace('__%s_' % property_name, '')
                setattr(property_obj, method, getattr(_SELF, method_name))
        setattr(Hypervisor, property_name, property(property_obj))


    return Hypervisor()
示例#12
0
文件: deb.py 项目: Jack47/python-unix
def Deb(host, root=''):
    unix.isvalid(host)

    if unix.ishost(host, 'DebHost'):
        if unix.ishost(host, 'Local'):
            new_host = unix.Local()
        else:
            new_host = unix.Remote()
        new_host.__dict__.update(host.__dict__)
        return Deb(new_host, root)

    host = unix.linux.Linux(host, root)

    class DebHost(host.__class__):
        def __init__(self, root=''):
            host.__class__.__init__(self, root)
            self.__dict__.update(host.__dict__)
            # Check this is a Debian-like system.


        @property
        def distribution(self):
            return self.execute('lsb_release -i')[1].split(':')[1].strip()


        @property
        def release(self):
            return self.execute('lsb_release -r')[1].split(':')[1].strip()


        @property
        def codename(self):
            return self.execute('lsb_release -c')[1].split(':')[1].strip()


        def set_hostname(self, hostname):
            try:
                self.write('/etc/hostname', hostname)
                return [True, '', '']
            except IOError as ioerr:
                return [False, '', ioerr]


        def set_network(self, interfaces):
            main_conf = ['auto lo', 'iface lo inet loopback']

            # For each interface, creating a configuration file
            interfaces_conf = []
            for index, interface in enumerate(interfaces):
                interface_name = 'eth%s' % index

                interface_conf = [
                    'auto %s' % interface_name,
                    'iface %s inet static' % interface_name,
                    '    address %s' % interface['address'],
                    '    netmask %s' % interface['netmask'],
                ]
                if 'gateway' in interface:
                    interface_conf.insert(
                        -2,
                        '    gateway %s' % interface['gateway']
                    )

                interfaces_conf.append(interface_conf)

            if self.distribution == 'Ubuntu' and float(self.release) < 11.04:
                for interface_conf in interfaces_conf:
                    main_conf.append('')
                    main_conf.extend(interface_conf)
            else:
                # Add a line
                main_conf.extend(['', 'source %s*' % NETCONF_DIR])

                # Creating the directory where configuration files of each
                # interfaces are stored.
                output = self.mkdir(NETCONF_DIR)
                if not output[0]:
                    return [False, '', output[2]]

                for index, interface_conf in enumerate(interfaces_conf):
                    try:
                        self.write(
                            path.join(NETCONF_DIR, 'eth%s' % index),
                            '\n'.join(interface_conf)
                        )
                    except IOError as ioerr:
                        return [False, '', ioerr]

            # Creating main configuration file.
            try:
                self.write(NETCONF_FILE, '\n'.join(main_conf))
            except IOError as ioerr:
                return [False, '', ioerr]

            return [True, '', '']


        def check_pkg(self, package):
            status, stdout = self.execute('dpkg -l')[:2]
            for line in stdout.split('\n'):
                if status and line.find(package) != -1 and line[0] != 'r':
                    return True
            return False


        def add_key(self, filepath):
            remote_filepath = path.join('/tmp', path.basename(filepath))
            self.get(filepath, remote_filepath)
            return self.execute('apt-key add %s' % remote_filepath)


        def add_repository(self, filepath):
            return self.get(filepath, path.join(
                '/etc/apt/sources.list.d',
                path.basename(filepath)
            ))


        def apt_update(self):
            return self.execute('aptitude update')


        def apt_install(self, packages, interactive=True):
            return self.execute(
                '%s aptitude install -y %s' % (NO_DEBCONF, ' '.join(packages)),
                interactive
            )


        def apt_search(self, package, interactive=True):
            status, stdout, stderr = self.execute(
                "aptitude search %s" % package, interactive
            )
            if status:
                for line in stdout.split("\n"):
                    if line.find(package) != -1:
                        return True

            return False


        def apt_remove(self, packages, purge=False):
            apt_command = 'purge -y' if purge else 'remove -y'
            return self.execute(
                '%s aptitude %s %s' % (NO_DEBCONF, apt_command, ' '.join(packages))
            )


        def deb_install(self, filepath, force=False):
            command = '-i --force-depends' if force else '-i'
            return self.execute('%s dpkg %s %s' % (NO_DEBCONF, command, filepath))

    return DebHost(root)
示例#13
0
def LXC(host):
    unix.isvalid(host)
    if not unix.ishost(host, 'Linux'):
        raise LXCError('this is not a Linux host')

    class Hypervisor(host.__class__):
        def __init__(self):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)

        def list_containers(self, **kwargs):
            def format_value(key, val):
                return (([v.strip()
                          for v in val.split(',')] if val != '-' else [])
                        if 'ipv' in key else ({
                            'YES': True,
                            'NO': False
                        }.get(val) if val in ['YES', 'NO'] else val))

            kwargs.update({
                'fancy': True,
                'fancy_format': ','.join(_FIELDS),
                '1': True
            })
            status, stdout, stderr = self.execute('lxc-ls', **kwargs)
            if not status:
                raise LXCError(stderr)
            return {
                values[0]: {
                    key: format_value(key, val)
                    for key, val in zip(_FIELDS[1:], values[1:])
                }
                for container in stdout.splitlines()[2:]
                for values in [re.split('\s{2,}', container)]
            }

        @property
        def container(self):
            return Container(weakref.ref(self)())

        @property
        def device(self):
            return Device(weakref.ref(self)())

    class Container(object):
        def __init__(self, host):
            self._host = host

        def exists(self, name):
            return True if name in self._host.list_containers() else False

        def info(self, name, **kwargs):
            kwargs.update(name=name)
            status, stdout, stderr = self._host.execute('lxc-info', **kwargs)
            if not status:
                raise LXCError(stderr)
            return {
                param.lower().strip().replace(' use', ''): value.strip()
                for line in stdout.splitlines()
                for param, value in [line.split(':')]
            }

        def state(self, name):
            return self.info(name, state=True)['state']

        def console(self, name, **kwargs):
            self._host.execute('lxc-console',
                               name=name,
                               TTY=True,
                               INTERACTIVE=True,
                               **kwargs)

        def create(self, name, tmpl_opts={}, **kwargs):
            def format_opt(opt, value):
                opt = '%s%s' % ('-' if len(opt) == 1 else '--', opt)
                return '%s %s' % (opt, value if isinstance(value, str) else '')

            tmpl_args = ' '.join(
                format_opt(opt, value) for opt, value in tmpl_opts.items())
            with self._host.set_controls(escape_args=False):
                return self._host.execute('lxc-create',
                                          '--',
                                          tmpl_args,
                                          name=name,
                                          **kwargs)

        def destroy(self, name, **kwargs):
            return self._host.execute('lxc-destroy', name=name, **kwargs)

        def start(self, name, **kwargs):
            return self._host.execute('lxc-start', name=name, **kwargs)

    class Device:
        def __init__(self, host):
            self._host = host

        def add(self, name, device):
            return self._host.execute('lxc-device', 'add', device, n=name)

    return Hypervisor()
示例#14
0
def Linux(host, root=''):
    # Check it a valid host (ie: *Local* or *Remote*)
    unix.isvalid(host)

    if unix.ishost(host, 'LinuxHost'):
        if unix.ishost(host, 'Local'):
            new_host = unix.Local()
        else:
            new_host = unix.Remote()
        new_host.__dict__.update(host.__dict__)
        return Linux(new_host, root)

    class LinuxHost(host.__class__):
        """Inherit class from *host* and deepcopy object."""
        def __init__(self, root=''):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)
            # If *root*, check that the directory contain
            # a valid Linux environment.
            self.root = root


        def __chroot(self):
            """Mount specials filesystems for having a  "valid" chrooted
            environment. This may be needed when install a package in a
            chrooted environment for example."""
            # Use parent (ie: Local or Remote) *execute* function.
            super(LinuxHost, self).execute(
                'mount -t proc proc %s/proc/' % self.root
            )
            super(LinuxHost, self).execute(
                'mount -t sysfs sys %s/sys/' % self.root
            )
            super(LinuxHost, self).execute(
                'mount -o bind /dev %s/dev/' % self.root
            )


        def __unchroot(self):
            """Umount specials filesystems on the chrooted environment."""
            # Use parent (ie: Local or Remote) *execute* function.
            super(LinuxHost, self).execute('umount %s/proc/' % self.root)
            super(LinuxHost, self).execute('umount %s/sys/' % self.root)
            super(LinuxHost, self).execute('umount %s/dev/' % self.root)


        def execute(self, command, interactive=False, chroot=False):
            """Refine the *execute* wrapper function, taking into account if
            it must be executed in a chrooted environment. if *chroot* is
            given, specials filesystems (*proc*, *sys* and *dev*) are mounted
            before execution of the command and unmounted after.
            """
            if chroot and self.root:
                self.__chroot()
            command = 'chroot %s %s' % (self.root, command) \
                if self.root \
                else command
            result = super(LinuxHost, self).execute(command, interactive)
            if chroot and self.root:
                self.__unchroot()
            return result


        def read(self, path, **kwargs):
            """Refine the *read* function, taking into account if it must be
            executed in a chroot environment."""
            if self.root:
                if not os.path.isabs(path):
                    raise IOError("'%s' is not an absolute path")
                path = os.path.join(self.root, path[1:])
            return super(LinuxHost, self).read(path, **kwargs)


        def write(self, path, content, **kwargs):
            """Refine the *write* function, taking into account if it must be
            executed in a chroot environment."""
            if self.root:
                if not os.path.isabs(path):
                    raise IOError("'%s' is not an absolute path")
                path = os.path.join(self.root, path[1:])
            super(LinuxHost, self).write(path, content, **kwargs)


        def isloaded(self, module):
            status, stdout, stderr = self.execute('lsmod')
            if not status:
                return False

            for line in stdout.split('\n')[1:-1]:
                if line.split()[0] == module:
                    return True
            return False


        def load(self, module, options=()):
            return self.execute('modprobe %s %s' % (module, ' '.join(options)))


        def unload(self, module):
            return self.execute('modprobe -r %s' % module)


        def service(self, name, action, type='upstart'):
            return self.execute(
                {
                    'upstart': lambda: "service %s %s" % (name, action),
                    'init': lambda: "/etc/init.d/%s %s" % (name, action)
                }.get(type)()
            )


        def set_password(self, username, password):
            shadow_file = '/etc/shadow'
            hashed_password = crypt.crypt(password, '$6$%s$' % ''.join(
                [random.choice(string.letters + string.digits) for i in xrange(0,8)]
            ))
            shadow_line = '%s:%s:%s:0:99999:7:::' % (
                username,
                hashed_password,
                (datetime.today() - datetime(1970, 1, 1)).days
            )

            new_content = []
            in_file = False
            for line in self.readlines(shadow_file):
                if line.find(username) != -1:
                    new_content.append(shadow_line)
                    in_file = True
                else:
                    new_content.append(line)
            if not in_file:
                new_content.append(shadow_line)
            try:
                self.write(shadow_file, '\n'.join(new_content))
                return [True, '', '']
            except IOError:
                return [False, '', ioerr]


        def set_hosts(self, ip, hostname, domain):
            try:
                self.write(
                    '/etc/hosts',
                    HOSTS_CONTENT \
                        .replace("$(IP)", ip) \
                        .replace("$(HOSTNAME)", hostname) \
                        .replace("$(DOMAIN)", domain)
                )
                return [True, '', '']
            except IOError as ioerr:
                return [False, '', ioerr]


        def set_sshkeys(self, algos=['rsa', 'dsa']):
            sshd_dir = '/etc/ssh'
            keys = [
                os.path.join(sshd_dir, filename) \
                for filename in self.listdir(sshd_dir) if 'ssh_host_' in filename
            ]
            for key in keys:
                output = self.execute("rm %s" % key)
                if not output[0]:
                    output[2] = "Unable to remove old keys: %s" % output[2]
                    return output

            for algo in algos:
                output = self.execute(
                    'ssh-keygen -N "" -t %s -f %s/ssh_host_%s_key' % (
                        algo, sshd_dir, algo
                    )
                )
                if not output[0]:
                    output[2] = "Unable to generate %s keys: %s" % (
                        algo.upper(), output[2]
                    )
                    return output
            return [True, '', '']

    return LinuxHost(root)
示例#15
0
def KVM(host):
    unix.isvalid(host)

    class KVM(host.__class__):
        def __init__(self):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)

        def virsh(self, command, args):
            virsh_cmd = ' '.join((
                'LANGUAGE=%s' % LANGUAGE,
                'virsh',
                command,
                args,
            ))
            status, stdout, stderr = self.execute(virsh_cmd)
            if not status \
            and (UNKNOWN_CMD_REGEXP.match(stderr) or BAD_OPTION_REGEXP.match(stderr)):
                raise KVMError('%s: %s' % (virsh_cmd, stderr))
            return (status, stdout, stderr)

        @property
        def vms(self):
            return [
                vm.split()[1] \
                for vm in self.virsh('list', '--all')[1].split('\n')[2:-1]
            ]

        def isdefined(self, vm):
            return True if vm in self.vms else False

        def state(self, vm):
            if not self.isdefined(vm):
                return (False, '', 'VM not exists')

            return self.virsh('domstate', vm)[1].split('\n')[0]

        def start(self, vm):
            return self.virsh('start', vm)

        def reboot(self, vm):
            return self.virsh('reboot', vm)

        def stop(self, vm, timeout=30, force=False):
            output = self.virsh('shutdown', vm)
            if not output[0]:
                return output

            def timeout_handler(signum, frame):
                raise TimeoutException()

            old_handler = signal.signal(signal.SIGALRM, timeout_handler)
            signal.alarm(timeout)

            try:
                while self.state(vm) != SHUTOFF:
                    time.sleep(1)
            except TimeoutException:
                if force:
                    status, stdout, stderr = self.destroy(vm)
                    if status:
                        stderr = 'VM has been destroy after %ss' % timeout
                    return (status, stdout, stderr)
                else:
                    return (False, '', 'VM not stopping after %ss' % timeout)
            finally:
                signal.signal(signal.SIGALRM, old_handler)
                signal.alarm(0)

            return output

        def destroy(self, vm):
            return self.virsh('destroy', vm)

        def restore(self, vm, src):
            return self.virsh('restore', src)

        def save(self, vm, dst):
            return self.virsh('save', ''.join("%s %s" % (vm, dst)))

        def define(self, conf_file):
            return self.virsh('define', conf_file)

        def undefine(self, vm, del_img=False):
            return self.virsh('undefine', vm)

        def migrate(self, vm, dst):
            return self.virsh(
                'migrate', ' '.join("--connect", "qemu:///system", "--live",
                                    "--persistent", "--copy-storage-all",
                                    "%s qemu+ssh://%s/system" % (vm, dst)))

        def img_size(self, img_path):
            if not self.exists(img_path):
                raise OSError("file '%s' not exists" % img_path)
            stdout = self.execute('qemu-img info %s' % img_path)[1]
            return int(SIZE_REGEXP.search(stdout).group(1)) / 1024

        def img_create(self, img_path, format, size):
            return self.execute('qemu-img create -f %s %s %sG' %
                                (format, img_path, size))

        def img_convert(self, format, src_path, dst_path, delete=False):
            output = self.execute("qemu-img convert -O %s %s %s" %
                                  (format, src_path, dst_path))
            if not delete or not output:
                return output

            return self.rm(src_path)

        def img_resize(self, path, new_size):
            return self.execute("qemu-img resize %s %sG" % (path, new_size))

        def img_load(self, path, nbd='/dev/nbd0'):
            if not self.isloaded('nbd'):
                output = self.load('nbd')
                if not output[0]:
                    return output

            if not self.exists(path):
                return [False, '', "'%' not exists" % path]

            output = self.execute("qemu-nbd -c %s %s" % (nbd, path))
            time.sleep(2)
            return output

        def img_unload(self, nbd='/dev/nbd0'):
            return self.execute("qemu-nbd -d %s" % nbd)

        def __xml_value(self, elt, tag):
            return elt.getElementsByTagName(tag)[0].childNodes[0].data

        def __xml_attr(self, elt, tag, attr):
            try:
                return elt.getElementsByTagName(tag)[0].getAttribute(attr)
            except IndexError:
                return ''

        def conf(self, vm):
            if not self.isdefined(vm):
                raise KVMError("VM '%s' is not defined" % vm)
            xml_conf = self.virsh('dumpxml', vm)[1]
            dom = parseString(xml_conf)

            disks = [
                {
                    'path': self.__xml_attr(disk_node, 'source', 'file'),
                    'format': self.__xml_attr(disk_node, 'driver', 'type'),
                    'driver': self.__xml_attr(disk_node, 'target', 'bus'),
                    'device': self.__xml_attr(disk_node, 'target', 'dev')
                }
                for disk_node in dom.getElementsByTagName('disk') \
                if disk_node.getAttribute('device') == 'disk'
            ]
            for index, disk in enumerate(disks):
                try:
                    disks[index]['size'] = self.img_size(disk['path'])
                except OSError:
                    disks[index]['size'] = 0

            interfaces = [{
                'mac':
                self.__xml_attr(int_node, 'mac', 'address'),
                'vlan':
                self.__xml_attr(int_node, 'source', 'bridge'),
                'interface':
                self.__xml_attr(int_node, 'target', 'dev'),
                'driver':
                self.__xml_attr(int_node, 'model', 'type')
            } for int_node in dom.getElementsByTagName('interface')]

            return {
                'pc':
                self.__xml_attr(
                    dom.getElementsByTagName('os')[0], 'type', 'machine'),
                'name':
                self.__xml_value(dom, 'name'),
                'uuid':
                self.__xml_value(dom, 'uuid'),
                'memory':
                int(self.__xml_value(dom, 'currentMemory')),
                'memory_max':
                int(self.__xml_value(dom, 'memory')),
                'cores':
                int(self.__xml_value(dom, 'vcpu')),
                'disks':
                disks,
                'interfaces':
                interfaces
            }

        def __node(self, name, attrs={}, text='', childs=[]):
            node = self.xml.createElement(name)
            for attr_name, attr_value in attrs.iteritems():
                node.setAttribute(attr_name, attr_value)
            if text:
                node.appendChild(self.xml.createTextNode(str(text)))
            if childs:
                for child_node in childs:
                    node.appendChild(child_node)
            return node

        def _gen_devices_config(self, disks, interfaces):
            devices_nodes = [self.__node('emulator', text='/usr/bin/kvm')]

            # Add disks.
            devices_nodes.extend(
                (self.__node('disk', {
                    'type': 'file',
                    'device': 'disk'
                },
                             childs=(
                                 self.__node('driver', {
                                     'name': 'qemu',
                                     'type': disk['format']
                                 }),
                                 self.__node('source', {'file': disk['path']}),
                                 self.__node('target', {
                                     'dev': disk['device'],
                                     'bus': disk['driver']
                                 })))) for disk in disks)

            # Add interfaces.
            devices_nodes.extend((self.__node(
                'interface', {'type': 'bridge'},
                childs=(
                    self.__node('mac', {'address': interface['mac']}),
                    self.__node('source',
                                {'bridge': 'br%s' % interface['vlan']}),
                    self.__node('model', {'type': interface['driver']}),
                )) for interface in interfaces))

            # Add other devices.
            devices_nodes.extend(
                (self.__node('serial', {'type': 'pty'},
                             childs=(self.__node('target', {'port': '0'}), )),
                 self.__node('console', {'type': 'pty'},
                             childs=(self.__node('target', {'port': '0'}), )),
                 self.__node('input', {
                     'type': 'mouse',
                     'bus': 'ps2'
                 }),
                 self.__node(
                     'graphics', {
                         'type': 'vnc',
                         'port': '-1',
                         'autoport': 'yes',
                         'keymap': 'fr'
                     }), self.__node('sound', {'model': 'es1370'}),
                 self.__node('video',
                             childs=(self.__node(
                                 'model', {
                                     'type': 'cirrus',
                                     'vram': '9216',
                                     'heads': '1'
                                 }), ))))
            return devices_nodes

        def gen_conf(self, conf_file, params):
            # Hack for not printing xml version
            Document.writexml = writexml_document

            # Hack for XML output: text node on one line
            Element.writexml = writexml_element

            self.xml = Document()
            #        memory = int(float(params['memory']) * 1024 * 1024)

            config = self.__node(
                'domain',
                {'type': 'kvm'},
                childs=(
                    self.__node('name', text=params['name']),
                    self.__node('uuid', text=params['uuid']),
                    self.__node('memory', text=params['memory']),
                    self.__node('currentMemory', text=params['memory']),
                    self.__node('vcpu', text=params['cores']),
                    self.__node(
                        'os',
                        childs=(
                            self.__node(
                                'type',
                                {
                                    'arch': 'x86_64',
                                    #                    'machine': 'pc-0.11'
                                },
                                'hvm'),
                            self.__node('boot', {'dev': 'hd'}))),
                    self.__node('features',
                                childs=(self.__node('acpi'),
                                        self.__node('apic'),
                                        self.__node('pae'))),
                    self.__node('clock', {'offset': 'utc'}),
                    self.__node('on_poweroff', text='destroy'),
                    self.__node('on_reboot', text='restart'),
                    self.__node('on_crash', text='restart'),
                    self.__node('devices',
                                childs=self._gen_devices_config(
                                    params['disks'], params['interfaces']))))

            try:
                self.write(
                    conf_file,
                    '\n'.join(config.toprettyxml(indent='  ').split('\n')[1:]))
                return [True, '', '']
            except IOError as ioerr:
                return [False, '', ioerr]

        def vms_conf(self):
            vms_conf = {}
            for vm in self.vms:
                vms_conf.setdefault(vm, self.conf(vm))
            return vms_conf

        def mount(self, vgroot, lvroot, path):
            # Load root Volume Group.
            output = self.execute("vgchange -ay %s" % vgroot)
            if not output[0]:
                output[2] = "Unable to load root Volume Group: %s" % output[2]
                return output

            # Create mount point.
            if not self.exists(path):
                output = self.mkdir(path, True)
                if not output[0]:
                    output[2] = "Unable to create mount point: %s" % output[2]
                    return output

            # Mount root partition
            output = self.execute("mount /dev/%s/%s %s" %
                                  (vgroot, lvroot, path))
            if not output[0]:
                output[2] = "Unable to mount root partition: %s" % output[2]
                return output
            self.mounted = [path]

            # Read fstab
            try:
                lines = self.readlines(os.path.join(path, 'etc', 'fstab'))
            except OSError, os_err:
                return (False, "", "Unable to read fstab: %s" % output[2])

            for line in lines:
                if \
                line.find('/dev/mapper') == -1 or \
                line.find('/dev/mapper/%s-%s' % (vgroot, lvroot)) != -1 or \
                line.find('swap') != -1:
                    continue
                dev, partition = line.split()[:2]
                mount_point = os.path.join(path, partition[1:])
                output = self.execute("mount %s %s" % (dev, mount_point))
                if not output[0]:
                    output[2] = "Unable to mount '%s' partition: %s" % (
                        partition, output[2])
                    return output
                self.mounted.append(mount_point)
            return (True, "", "")

        def umount(self, vgroot):
            if not self.mounted:
                return (True, "", "Nothing was mounted")

            mounted = list(self.mounted)
            for mount in reversed(mounted):
                output = self.execute("umount %s" % mount)
                if not output[0]:
                    output[2] = "Unable to umount '%s': %s" % (mount,
                                                               output[2])
                    return output
                self.mounted.remove(mount)

            output = self.execute("vgchange -an %s" % vgroot)
            if not output[0]:
                output[
                    2] = "Unable to unload root Volume Group: %s" % output[2]
            return output
示例#16
0
文件: rpm.py 项目: Jack47/python-unix
def Rpm(host, root=''):
    unix.isvalid(host)

    if unix.ishost(host, 'RpmHost'):
        if unix.ishost(host, 'Local'):
            new_host = unix.Local()
        else:
            new_host = unix.Remote()
        new_host.__dict__.update(host.__dict__)
        return Rpm(new_host, root)

    host = unix.linux.Linux(host, root)


    class RpmHost(host.__class__):
        def __init__(self, root=''):
            host.__class__.__init__(self, root)
            self.__dict__.update(host.__dict__)


        def set_hostname(self, hostname):
            try:
                self.write(
                    '/etc/sysconfig/network',
                    '\n'.join((
                        'NETWORKING=yes',
                        'NETWORKING_IPV6=no',
                        'HOSTNAME=%s' % hostname
                    ))
                )
                return [True, '', '']
            except IOError as ioerr:
                return [False, '', ioerr]


        def set_network(self, interfaces):
            network_root = '/etc/sysconfig/network-scripts'
            self.rm(path.join(network_root, 'ifcfg-ext'))
            for index, interface in enumerate(interfaces):
                interface_conf = [
                    'DEVICE=eth%s' % index,
                    'BOOTPROTO=none',
                    'ONBOOT=yes',
                    'NETMASK=%s' % interface['netmask'],
                    'IPADDR=%s' % interface['address'],
                    'TYPE=Ethernet',
                    'USERCTL=no',
                    'IPV6INIT=no',
                    'PEERDNS=yes'
                ]

                if 'gateway' in interface:
                    interface_conf.insert(5, 'GATEWAY=%s' % interface['gateway'])

                try:
                    self.write(
                        path.join(network_root, 'ifcfg-eth%s' % index),
                        '\n'.join(interface_conf)
                    )
                except IOError as ioerr:
                    return [False, '', ioerr]

            return [True, '', '']


        def check_pkg(self, package):
            status, stdout = self.execute('rpm -qa')[:2]
            if status and stdout.find(package) != -1:
                return True
            return False


        def add_repository(self, filepath):
            return self.get(filepath, os.path.join(
                '/etc/yum.repos.d',
                os.path.basename(filepath))
            )


        def yum_install(self, packages, interative=True,repository=''):
            yum_cmd = '-y' if not repository else '-y --enablerepo=%s' % repository
            return self.execute(
                'yum install %s %s' % (yum_cmd, ' '.join(packages)),
                interactive
            )


        def yum_remove(self, packages):
            return self.execute('yum erase -y %s' % ' '.join(packages))


        def rpm_install(self, filepath):
            return self.execute('rpm -U %s' % filepath)

    return RpmHost(root)
示例#17
0
文件: lxc.py 项目: fmenabe/python-lxc
def LXC(host):
    unix.isvalid(host)
    if not unix.ishost(host, 'Linux'):
        raise LXCError('this is not a Linux host')


    class Hypervisor(host.__class__):
        def __init__(self):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)


        def list_containers(self, **kwargs):
            def format_value(key, val):
                return (([v.strip() for v in val.split(',')] if val != '-' else [])
                        if 'ipv' in key
                        else ({'YES': True, 'NO': False}.get(val)
                              if val in ['YES', 'NO']
                              else val))

            kwargs.update({'fancy': True,
                           'fancy_format': ','.join(_FIELDS),
                           '1': True})
            status, stdout, stderr = self.execute('lxc-ls', **kwargs)
            if not status:
                raise LXCError(stderr)
            return {values[0]: {key: format_value(key, val)
                                for key, val in zip(_FIELDS[1:], values[1:])}
                    for container in stdout.splitlines()[2:]
                    for values in [re.split('\s{2,}', container)]}


        @property
        def container(self):
            return Container(weakref.ref(self)())


        @property
        def device(self):
            return Device(weakref.ref(self)())


    class Container(object):
        def __init__(self, host):
            self._host = host


        def exists(self, name):
            return True if name in self._host.list_containers() else False


        def info(self, name, **kwargs):
            kwargs.update(name=name)
            status, stdout, stderr = self._host.execute('lxc-info', **kwargs)
            if not status:
                raise LXCError(stderr)
            return {param.lower().strip().replace(' use', ''): value.strip()
                    for line in stdout.splitlines()
                    for param, value in [line.split(':')]}


        def state(self, name):
            return self.info(name, state=True)['state']


        def console(self, name, **kwargs):
            self._host.execute('lxc-console', name=name,
                                TTY=True, INTERACTIVE=True, **kwargs)


        def create(self, name, tmpl_opts={}, **kwargs):
            def format_opt(opt, value):
                opt = '%s%s' % ('-' if len(opt) == 1 else '--', opt)
                return '%s %s' % (opt, value if isinstance(value, str) else '')

            tmpl_args = ' '.join(format_opt(opt, value) for opt, value in tmpl_opts.items())
            with self._host.set_controls(escape_args=False):
                return self._host.execute('lxc-create', '--', tmpl_args, name=name, **kwargs)


        def destroy(self, name, **kwargs):
            return self._host.execute('lxc-destroy', name=name, **kwargs)


        def start(self, name, **kwargs):
            return self._host.execute('lxc-start', name=name, **kwargs)


    class Device:
        def __init__(self, host):
            self._host = host


        def add(self, name, device):
            return self._host.execute('lxc-device', 'add', device, n=name)

    return Hypervisor()
示例#18
0
def Chroot(host, root):
    unix.isvalid(host)
    host.is_connected()

    if root and host.username != 'root':
        raise ChrootError('you need to be root for chroot')

    instances = unix.instances(host)
    if len(instances) > 1:
        host = getattr(unix, instances[0]).clone(host)
    host = Linux(host)

    class ChrootHost(host.__class__):
        def __init__(self, root):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)
            self.root = root

        @property
        def chrooted(self):
            return True

        def execute(self, cmd, *args, **kwargs):
            if self.root:
                cmd = 'chroot %s %s' % (self.root, cmd)
            result = host.execute(cmd, *args, **kwargs)
            # Set return code of the parent. If not set some functions (like
            # Path) does not work correctly on chrooted objects.
            self.return_code = host.return_code
            return result

        def open(self, filepath, mode='r'):
            if self.root:
                filepath = filepath[1:] if filepath.startswith('/') else filepath
                filepath = os.path.join(self.root, filepath)
            return host.open(filepath, mode)

        @contextmanager
        def set_controls(self, **controls):
            cur_controls = dict(host.controls)

            try:
                for control, value in controls.items():
                    host.set_control(control, value)
                yield None
            finally:
                for control, value in cur_controls.items():
                    host.set_control(control, value)

        def chroot(self):
            for (fs, opts) in _FILESYSTEMS:
                mount_point = os.path.join(root, fs[1:] if fs.startswith('/') else fs)
                status, _, stderr = host.mount(fs, mount_point, **opts)
                if not status:
                    raise ChrootError("unable to mount '%s': %s" % (fs, stderr))

        def unchroot(self):
            for (fs, _) in _FILESYSTEMS:
                mount_point = os.path.join(root, fs[1:] if fs.startswith('/') else fs)
                status, _, stderr = host.umount(mount_point)
                if not status:
                    raise ChrootError("unable to umount '%s': %s" % (fs, stderr))


    return ChrootHost(root)
示例#19
0
def Chroot(host, root):
    unix.isvalid(host)
    host.is_connected()

    if root and host.username != 'root':
        raise ChrootError('you need to be root for chroot')

    instances = unix.instances(host)
    if len(instances) > 1:
        host = getattr(unix, instances[0]).clone(host)
    host = Linux(host)

    class ChrootHost(host.__class__):
        def __init__(self, root):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)
            self.root = root

        @property
        def chrooted(self):
            return True

        def execute(self, cmd, *args, **kwargs):
            if self.root:
                cmd = 'chroot %s %s' % (self.root, cmd)
            result = host.execute(cmd, *args, **kwargs)
            # Set return code of the parent. If not set some functions (like
            # Path) does not work correctly on chrooted objects.
            self.return_code = host.return_code
            return result

        def open(self, filepath, mode='r'):
            if self.root:
                filepath = filepath[1:] if filepath.startswith('/') else filepath
                filepath = os.path.join(self.root, filepath)
            return host.open(filepath, mode)

        @contextmanager
        def set_controls(self, **controls):
            cur_controls = dict(host.controls)

            try:
                for control, value in controls.items():
                    host.set_control(control, value)
                yield None
            finally:
                for control, value in cur_controls.items():
                    host.set_control(control, value)

        def chroot(self):
            for (fs, opts) in _FILESYSTEMS:
                mount_point = os.path.join(root, fs[1:] if fs.startswith('/') else fs)
                status, _, stderr = host.mount(fs, mount_point, **opts)
                if not status:
                    raise ChrootError("unable to mount '%s': %s" % (fs, stderr))

        def unchroot(self):
            for (fs, _) in _FILESYSTEMS:
                mount_point = os.path.join(root, fs[1:] if fs.startswith('/') else fs)
                status, _, stderr = host.umount(mount_point)
                if not status:
                    raise ChrootError("unable to umount '%s': %s" % (fs, stderr))


    return ChrootHost(root)
示例#20
0
def KVM(host):
    unix.isvalid(host)

    class KVM(host.__class__):
        def __init__(self):
            host.__class__.__init__(self)
            self.__dict__.update(host.__dict__)


        def virsh(self, command, args):
            virsh_cmd = ' '.join((
                'LANGUAGE=%s' % LANGUAGE,
                'virsh',
                command,
                args,
            ))
            status, stdout, stderr = self.execute(virsh_cmd)
            if not status \
            and (UNKNOWN_CMD_REGEXP.match(stderr) or BAD_OPTION_REGEXP.match(stderr)):
                raise KVMError('%s: %s' % (virsh_cmd, stderr))
            return (status, stdout, stderr)


        @property
        def vms(self):
            return [
                vm.split()[1] \
                for vm in self.virsh('list', '--all')[1].split('\n')[2:-1]
            ]


        def isdefined(self, vm):
            return True if vm in self.vms else False


        def state(self, vm):
            if not self.isdefined(vm):
                return (False, '', 'VM not exists')

            return self.virsh('domstate', vm)[1].split('\n')[0]


        def start(self, vm):
            return self.virsh('start', vm)


        def reboot(self, vm):
            return self.virsh('reboot', vm)


        def stop(self, vm, timeout=30, force=False):
            output = self.virsh('shutdown', vm)
            if not output[0]:
                return output

            def timeout_handler(signum, frame):
                raise TimeoutException()
            old_handler = signal.signal(signal.SIGALRM, timeout_handler)
            signal.alarm(timeout)

            try:
                while self.state(vm) != SHUTOFF:
                    time.sleep(1)
            except TimeoutException:
                if force:
                    status, stdout,stderr = self.destroy(vm)
                    if status:
                        stderr = 'VM has been destroy after %ss' % timeout
                    return (status, stdout, stderr)
                else:
                    return (False, '', 'VM not stopping after %ss' % timeout)
            finally:
                signal.signal(signal.SIGALRM, old_handler)
                signal.alarm(0)

            return output


        def destroy(self, vm):
            return self.virsh('destroy', vm)


        def restore(self, vm, src):
            return self.virsh('restore', src)


        def save(self, vm, dst):
            return self.virsh('save', ''.join("%s %s" %(vm, dst)))


        def define(self, conf_file):
            return self.virsh('define', conf_file)


        def undefine(self, vm, del_img=False):
            return self.virsh('undefine', vm)


        def migrate(self, vm, dst):
            return self.virsh('migrate', ' '.join(
                "--connect",
                "qemu:///system",
                "--live",
                "--persistent",
                "--copy-storage-all",
                "%s qemu+ssh://%s/system" % (vm, dst)
            ))


        def img_size(self, img_path):
            if not self.exists(img_path):
                raise OSError("file '%s' not exists" % img_path)
            stdout = self.execute('qemu-img info %s' % img_path)[1]
            return int(SIZE_REGEXP.search(stdout).group(1)) / 1024


        def img_create(self, img_path, format, size):
            return self.execute('qemu-img create -f %s %s %sG' % (
                format, img_path, size
            ))


        def img_convert(self, format, src_path, dst_path, delete=False):
            output = self.execute("qemu-img convert -O %s %s %s" % (
                format,
                src_path,
                dst_path
            ))
            if not delete or not output:
                return output

            return self.rm(src_path)


        def img_resize(self, path, new_size):
            return self.execute(
                "qemu-img resize %s %sG" % (path, new_size)
            )


        def img_load(self, path, nbd='/dev/nbd0'):
            if not self.isloaded('nbd'):
                output = self.load('nbd')
                if not output[0]:
                    return output

            if not self.exists(path):
                return [False, '', "'%' not exists" % path]

            output = self.execute("qemu-nbd -c %s %s" % (nbd, path))
            time.sleep(2)
            return output


        def img_unload(self, nbd='/dev/nbd0'):
            return self.execute("qemu-nbd -d %s" % nbd)


        def __xml_value(self, elt, tag):
            return elt.getElementsByTagName(tag)[0].childNodes[0].data


        def __xml_attr(self, elt, tag, attr):
            try:
                return elt.getElementsByTagName(tag)[0].getAttribute(attr)
            except IndexError:
                return ''


        def conf(self, vm):
            if not self.isdefined(vm):
                raise KVMError("VM '%s' is not defined" % vm)
            xml_conf = self.virsh('dumpxml', vm)[1]
            dom = parseString(xml_conf)

            disks = [
                {
                    'path': self.__xml_attr(disk_node, 'source', 'file'),
                    'format': self.__xml_attr(disk_node, 'driver', 'type'),
                    'driver': self.__xml_attr(disk_node, 'target', 'bus'),
                    'device': self.__xml_attr(disk_node, 'target', 'dev')
                }
                for disk_node in dom.getElementsByTagName('disk') \
                if disk_node.getAttribute('device') == 'disk'
            ]
            for index, disk in enumerate(disks):
                try:
                    disks[index]['size'] = self.img_size(disk['path'])
                except OSError:
                    disks[index]['size'] = 0

            interfaces = [
                {
                    'mac': self.__xml_attr(int_node, 'mac', 'address'),
                    'vlan': self.__xml_attr(int_node, 'source', 'bridge'),
                    'interface': self.__xml_attr(int_node, 'target', 'dev'),
                    'driver': self.__xml_attr(int_node, 'model', 'type')
                }
                for int_node in dom.getElementsByTagName('interface')
            ]

            return {
                'pc': self.__xml_attr(dom.getElementsByTagName('os')[0], 'type', 'machine'),
                'name': self.__xml_value(dom, 'name'),
                'uuid': self.__xml_value(dom, 'uuid'),
                'memory': int(self.__xml_value(dom, 'currentMemory')),
                'memory_max': int(self.__xml_value(dom, 'memory')),
                'cores': int(self.__xml_value(dom, 'vcpu')),
                'disks': disks,
                'interfaces': interfaces
            }


        def __node(self, name, attrs={}, text='', childs=[]):
            node = self.xml.createElement(name)
            for attr_name, attr_value in attrs.iteritems():
                node.setAttribute(attr_name, attr_value)
            if text:
                node.appendChild(self.xml.createTextNode(str(text)))
            if childs:
                for child_node in childs:
                    node.appendChild(child_node)
            return node


        def _gen_devices_config(self, disks, interfaces):
            devices_nodes = [self.__node('emulator', text='/usr/bin/kvm')]

            # Add disks.
            devices_nodes.extend(
                (
                    self.__node('disk', {'type': 'file', 'device': 'disk'}, childs=(
                        self.__node('driver', {'name': 'qemu', 'type': disk['format']}),
                        self.__node('source', {'file': disk['path']}),
                        self.__node('target', {'dev': disk['device'], 'bus': disk['driver']})
                    ))
                ) for disk in disks
            )

            # Add interfaces.
            devices_nodes.extend(
                (
                    self.__node('interface', {'type': 'bridge'}, childs=(
                        self.__node('mac', {'address': interface['mac']}),
                        self.__node('source', {'bridge': 'br%s' % interface['vlan']}),
                        self.__node('model', {'type': interface['driver']}),
                    ))
                    for interface in interfaces
                )
            )

            # Add other devices.
            devices_nodes.extend((
                self.__node('serial', {'type': 'pty'}, childs=(
                    self.__node('target', {'port': '0'}),
                )),
                self.__node('console', {'type': 'pty'}, childs=(
                    self.__node('target', {'port': '0'}),
                )),
                self.__node('input', {'type': 'mouse', 'bus': 'ps2'}),
                self.__node('graphics', {
                    'type': 'vnc',
                    'port': '-1',
                    'autoport': 'yes',
                    'keymap': 'fr'}
                ),
                self.__node('sound', {'model': 'es1370'}),
                self.__node('video', childs=(
                    self.__node('model', {'type': 'cirrus', 'vram': '9216', 'heads': '1'}),
                )
            )))
            return devices_nodes


        def gen_conf(self, conf_file, params):
            # Hack for not printing xml version
            Document.writexml = writexml_document

            # Hack for XML output: text node on one line
            Element.writexml = writexml_element

            self.xml = Document()
    #        memory = int(float(params['memory']) * 1024 * 1024)

            config = self.__node('domain', {'type': 'kvm'}, childs=(
                self.__node('name', text=params['name']),
                self.__node('uuid', text=params['uuid']),
                self.__node('memory', text=params['memory']),
                self.__node('currentMemory', text=params['memory']),
                self.__node('vcpu', text=params['cores']),
                self.__node('os', childs=(
                    self.__node('type', {
                        'arch': 'x86_64',
    #                    'machine': 'pc-0.11'
                    }, 'hvm'),
                    self.__node('boot', {'dev': 'hd'})
                )),
                self.__node('features', childs=(
                    self.__node('acpi'),
                    self.__node('apic'),
                    self.__node('pae')
                )),
                self.__node('clock', {'offset': 'utc'}),
                self.__node('on_poweroff', text='destroy'),
                self.__node('on_reboot', text='restart'),
                self.__node('on_crash', text='restart'),
                self.__node('devices', childs=self._gen_devices_config(
                    params['disks'],
                    params['interfaces']
                ))
            ))

            try:
                self.write(
                    conf_file,
                    '\n'.join(config.toprettyxml(indent='  ').split('\n')[1:])
                )
                return [True, '', '']
            except IOError as ioerr:
                return[False, '', ioerr]


        def vms_conf(self):
            vms_conf = {}
            for vm in self.vms:
                vms_conf.setdefault(vm, self.conf(vm))
            return vms_conf


        def mount(self, vgroot, lvroot, path):
            # Load root Volume Group.
            output = self.execute("vgchange -ay %s" % vgroot)
            if not output[0]:
                output[2] = "Unable to load root Volume Group: %s" % output[2]
                return output

            # Create mount point.
            if not self.exists(path):
                output = self.mkdir(path, True)
                if not output[0]:
                    output[2] = "Unable to create mount point: %s" % output[2]
                    return output

            # Mount root partition
            output = self.execute(
                "mount /dev/%s/%s %s" % (vgroot, lvroot, path)
            )
            if not output[0]:
                output[2] = "Unable to mount root partition: %s" % output[2]
                return output
            self.mounted = [path]

            # Read fstab
            try:
                lines = self.readlines(os.path.join(path, 'etc', 'fstab'))
            except OSError, os_err:
                return (False, "", "Unable to read fstab: %s" % output[2])

            for line in lines:
                if \
                line.find('/dev/mapper') == -1 or \
                line.find('/dev/mapper/%s-%s' % (vgroot, lvroot)) != -1 or \
                line.find('swap') != -1:
                    continue
                dev, partition = line.split()[:2]
                mount_point = os.path.join(path, partition[1:])
                output = self.execute("mount %s %s" % (dev, mount_point))
                if not output[0]:
                    output[2] = "Unable to mount '%s' partition: %s" % (
                        partition, output[2]
                    )
                    return output
                self.mounted.append(mount_point)
            return (True, "", "")


        def umount(self, vgroot):
            if not self.mounted:
                return (True, "", "Nothing was mounted")

            mounted = list(self.mounted)
            for mount in reversed(mounted):
                output = self.execute("umount %s" % mount)
                if not output[0]:
                    output[2] = "Unable to umount '%s': %s" % (mount, output[2])
                    return output
                self.mounted.remove(mount)

            output = self.execute("vgchange -an %s" % vgroot)
            if not output[0]:
                output[2] = "Unable to unload root Volume Group: %s" % output[2]
            return output