Exemple #1
0
    def get(self, rmthost, rmtpath, localpath, **kwargs):
        if unix.ishost(self._host, 'Remote') and rmthost == 'localhost':
            return unix.Local().remote.put(rmtpath,
                                           self._host.ip,
                                           localpath,
                                           rmtuser=kwargs.pop('rmtuser',
                                                              self._host.username),
                                           **kwargs)

        method = kwargs.pop('method', 'scp')
        rmtuser = kwargs.pop('rmtuser', 'root')

        try:
            args = (rmtpath, localpath)
            kwargs.update(src_host=rmthost, src_user=rmtuser)
            return getattr(self, method)(*args, **kwargs)
        except AttributeError:
            return [False, [], ["unknown copy method '%s'" % method]]
Exemple #2
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()
Exemple #3
0
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)
Exemple #4
0
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)
Exemple #5
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)
Exemple #6
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()