Пример #1
0
    def __init__(self, config):
        import libvirt
        import os
        from lab.server import Server

        super(ProviderLibvirt, self).__init__(config=config)
        self.lab_id = config['lab_id']
        self.username = config['username']
        self.password = config['password']
        self.network_id = config['networks']
        self.network_names = {
            x: '{0}-{1}'.format(self.lab_id, x)
            for x in self.network_id
        }
        self.instances = config['instances']

        self.dir_for_backing_disks = os.path.abspath(
            os.path.join('/tmp', 'libvirt', 'backing_images'))
        self.dir_for_main_disks = os.path.abspath(
            os.path.join('/tmp', 'libvirt', 'main_disks'))
        self.dir_for_saved_xml = os.path.abspath(
            os.path.join('/tmp', 'libvirt', 'saved_xml'))
        self.domain_tmpl = self.read_config_from_file(
            config_path='domain_template.txt',
            directory='libvirt',
            is_as_string=True)
        self.connection = libvirt.open()
        self.servers = []
        self.local = Server(ip='localhost',
                            username='******',
                            password=Server.USE_SSH_KEY)
Пример #2
0
    def check_mgm_node(ip):
        import StringIO
        import paramiko
        from lab.server import Server

        pkey = paramiko.RSAKey.from_private_key(
            StringIO.StringIO(WithConfig.PRIVATE_KEY))
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        try:
            client.connect(hostname=ip,
                           username=WithConfig.SQE_USERNAME,
                           pkey=pkey,
                           timeout=2)
        except paramiko.AuthenticationException:  # user SQE yet, create it
            for password in WithMercury.POSSIBLE_PASSWORDS:
                try:
                    client.connect(hostname=ip,
                                   username='******',
                                   password=password,
                                   timeout=2)
                    Server(ip=ip, username='******',
                           password=password).create_user(
                               username=WithConfig.SQE_USERNAME,
                               public_key=WithConfig.PUBLIC_KEY,
                               private_key=WithConfig.PRIVATE_KEY)
                    break
                except paramiko.AuthenticationException:
                    continue
            else:
                raise RuntimeError('failed to connect to {} with {}'.format(
                    ip, WithMercury.POSSIBLE_PASSWORDS))
        return Server(ip=ip, username=WithConfig.SQE_USERNAME, password=None)
Пример #3
0
def kill_index(index):
    """fab elk.kill_index:index_name \t\t Kill given index in ES.
        :param index: name of index to delete
    """
    from lab.server import Server

    Server.run_local('curl -s -XDELETE 172.29.173.236:9999/{index}'.format(index=index))
Пример #4
0
def json_to_es():
    """fab elk.json_to_es \t\t\t\t Push json.log to our ES and index it."""
    from lab.server import Server

    with open('json.log') as l:
        with open('elk', 'w') as e:
            for line in l:
                e.write('{ "index" : { "_index" : "sqe", "_type" : "type1"} }\n')
                e.write(line)
    Server.run_local('curl -s -XPOST 172.29.173.236:9999/_bulk --data-binary @elk')
Пример #5
0
    def create_from_actual(ip, password):
        from lab.with_config import WithConfig
        from lab.server import Server
        import yaml

        separator = 'separator'
        cmds = [
            'sudo ciscovim install-status', 'cat setup_data.yaml',
            'grep -E "image_tag|RELEASE_TAG" defaults.yaml'
        ]
        cmd = ' ; echo {} ; '.format(separator).join(cmds)

        mgm = Server(ip=ip, username=WithConfig.SQE_USERNAME, password=None)

        while True:
            try:
                a = mgm.exe(cmd)
                status, setup_data_body, grep = a.split('separator')
                setup_data_dic = yaml.load(setup_data_body)
                release_tag = grep.split('\n')[1].split(':')[-1].strip()
                gerrit_tag = grep.split('\n')[2].split(':')[-1].strip()
                mgm.username = '******'
                mgm.password = password
                return mgm, status, setup_data_dic, release_tag, gerrit_tag
            except ValueError:  # means username/password combination wrong
                mgm.username = '******'
                mgm.password = password
                mgm.create_user(username=WithConfig.SQE_USERNAME,
                                public_key=WithConfig.PUBLIC_KEY,
                                private_key=WithConfig.PRIVATE_KEY)
                continue
Пример #6
0
    def create_from_actual(ip, password):
        from lab.with_config import WithConfig
        from lab.server import Server
        import yaml

        separator = 'separator'
        cmds = ['sudo ciscovim install-status', 'cat setup_data.yaml', 'grep -E "image_tag|RELEASE_TAG" defaults.yaml']
        cmd = ' ; echo {} ; '.format(separator).join(cmds)

        mgm = Server(ip=ip, username=WithConfig.SQE_USERNAME, password=None)

        while True:
            try:
                a = mgm.exe(cmd)
                status, setup_data_body, grep = a.split('separator')
                setup_data_dic = yaml.load(setup_data_body)
                release_tag = grep.split('\n')[1].split(':')[-1].strip()
                gerrit_tag = grep.split('\n')[2].split(':')[-1].strip()
                mgm.username = '******'
                mgm.password = password
                return mgm, status, setup_data_dic, release_tag, gerrit_tag
            except ValueError:  # means username/password combination wrong
                mgm.username = '******'
                mgm.password = password
                mgm.create_user(username=WithConfig.SQE_USERNAME, public_key=WithConfig.PUBLIC_KEY, private_key=WithConfig.PRIVATE_KEY)
                continue
Пример #7
0
    def create_server(self, dev_num, hostname, on_nets, image_url,
                      image_checksum):
        from lab.server import Server

        net_tmpl = '''
<interface type='network'>
    <source network='{{net_name}}'/>
    <mac address='{{mac}}'/>
    <target dev='v{{net_name}}-{hostname}'/>
</interface>

'''.format(lab_id=self.lab_id, dev_num=dev_num, hostname=hostname)

        macs = [
            'ee:{lab_id:02}:00:{net_id:02}:00:{dev_num:02}'.format(
                lab_id=self.lab_id, net_id=net_id, dev_num=dev_num)
            for net_id in on_nets
        ]
        net_names = [self.network_names[net_id] for net_id in on_nets]

        net_part = '\n\n'.join([
            net_tmpl.format(net_name=net_names[i], mac=macs[i])
            for i in range(len(on_nets))
        ])

        disk_part = '''
<disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='{main_disk}'/>
    <target dev='vda' bus='virtio'/>
</disk>

<disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='{cloud_init_disk}'/>
    <target dev='hdb' bus='ide'/>
</disk>
'''.format(main_disk=self.create_main_disk(hostname=hostname,
                                           image_url=image_url,
                                           image_checksum=image_checksum),
           cloud_init_disk=self.create_cloud_init_disk(hostname=hostname))

        xml = self.domain_tmpl.format(hostname='{0}-{1}'.format(
            self.lab_id, hostname),
                                      net_part=net_part,
                                      disk_part=disk_part)
        self.save_xml(name=hostname, xml=xml)
        domain = self.connection.defineXML(xml)
        domain.create()

        ip = self.ip_for_mac_by_looking_at_libvirt_leases(net=net_names[0],
                                                          mac=macs[0])

        lab_logger.info(msg='Domain {0} created'.format(hostname))
        return Server(ip=ip,
                      username=self.username,
                      password=Server.USE_SSH_KEY)
Пример #8
0
    def exe(self,
            cmd,
            in_dir='.',
            is_warn_only=False,
            is_as_sqe=False,
            n_attempts=100,
            estimated_time=None):
        import time
        from lab.server import Server

        ip, username, password = (self.proxy.ssh_ip, self.proxy.ssh_username,
                                  self.proxy.ssh_password) if self.proxy else (
                                      self.ssh_ip, self.ssh_username,
                                      self.ssh_password)
        if is_as_sqe:
            username, password = self.pod.SQE_USERNAME, None
        srv = Server(ip=ip, username=username, password=password)

        comment = ' # sshpass -p ' + password if password else ' # '
        comment += ' ssh ' + username + '@' + ip

        if 'sudo' in cmd and 'sudo -p "" -S ' not in cmd:
            cmd = cmd.replace(
                'sudo ', 'echo {} | sudo -p "" -S '.format(self.ssh_password))
        if self.proxy:
            cmd = 'ssh -o StrictHostKeyChecking=no ' + self.ssh_username + '@' + (
                self.ssh_ip or self.id) + " '" + cmd + "'"
            comment += ' ssh ' + self.id
        comment += ' # ' + self.id + '@' + self.pod.name

        if estimated_time:
            self.log('Running {}... (usually it takes {} secs)'.format(
                cmd, estimated_time))
        started_at = time.time()
        ans = srv.exe(cmd=cmd + comment,
                      in_dir=in_dir,
                      is_warn_only=is_warn_only,
                      n_attempts=n_attempts)
        if estimated_time:
            self.log('{} finished and actually took {} secs'.format(
                cmd,
                time.time() - started_at))
        return ans
Пример #9
0
    def store_on_our_server():
        """Store $REPO/*.log and $REPO/artifacts/* on file storage server"""
        from lab import logger
        from lab.server import Server

        destination_dir = '{0}-{1}'.format(logger.JENKINS_TAG, logger.REPO_TAG)
        server = Server(ip='172.29.173.233', username='******', password='******', lab=None, name='FileStorage')
        server.run(command='mkdir -p /var/www/logs/{0}'.format(destination_dir))
        server.put(local_path='*.log', remote_path='/var/www/logs/' + destination_dir, is_sudo=False)
        server.put(local_path='artifacts/*', remote_path='/var/www/logs/' + destination_dir, is_sudo=False)
Пример #10
0
    def exe(self, cmd, in_dir='.', is_warn_only=False, is_as_sqe=False, n_attempts=100, estimated_time=None):
        import time
        from lab.server import Server

        ip, username, password = (self.proxy.ip, self.proxy.username, self.proxy.password) if self.proxy else (self.ip, self.username, self.password)
        if is_as_sqe:
            username, password = self.pod.SQE_USERNAME, None
        srv = Server(ip=ip, username=username, password=password)

        if 'sudo' in cmd and 'sudo -p "" -S ' not in cmd:
            cmd = cmd.replace('sudo ', 'echo {} | sudo -p "" -S '.format(self.password))
        if self.proxy:
            cmd = 'ssh ' + self.username + '@' + (self.ip or self.id) + " '" + cmd + "'"
        comment = ' # ' + self.id + ' ' + self.pod.name

        if estimated_time:
            self.log('Running {}... (usually it takes {} secs)'.format(cmd, estimated_time))
        started_at = time.time()
        ans = srv.exe(cmd=cmd + comment, in_dir=in_dir, is_warn_only=is_warn_only, n_attempts=n_attempts)
        if estimated_time:
            self.log('{} finished and actually took {} secs'.format(cmd, time.time() - started_at))
        return ans
Пример #11
0
    def __init__(self, config):
        import libvirt
        import os
        from lab.server import Server

        super(ProviderLibvirt, self).__init__(config=config)
        self.lab_id = config['lab_id']
        self.username = config['username']
        self.password = config['password']
        self.network_id = config['networks']
        self.network_names = {x: '{0}-{1}'.format(self.lab_id, x) for x in self.network_id}
        self.instances = config['instances']

        self.dir_for_backing_disks = os.path.abspath(os.path.join('/tmp', 'libvirt', 'backing_images'))
        self.dir_for_main_disks = os.path.abspath(os.path.join('/tmp', 'libvirt', 'main_disks'))
        self.dir_for_saved_xml = os.path.abspath(os.path.join('/tmp', 'libvirt', 'saved_xml'))
        self.domain_tmpl = self.read_config_from_file(config_path='domain_template.txt', directory='libvirt', is_as_string=True)
        self.connection = libvirt.open()
        self.servers = []
        self.local = Server(ip='localhost', username='******', password=Server.USE_SSH_KEY)
Пример #12
0
    def file_append(self,
                    file_path,
                    data,
                    in_directory='.',
                    is_warn_only=False,
                    n_attempts=100):
        from lab.server import Server

        if self.proxy:
            raise NotImplemented()
        else:
            ans = Server(ip=self.ip,
                         username=self.username,
                         password=self.password).file_append(
                             file_path=file_path,
                             data=data,
                             in_directory=in_directory,
                             is_warn_only=is_warn_only,
                             n_attempts=n_attempts)
        return ans
Пример #13
0
    def __init__(self, config):
        from lab.server import Server

        super(ProviderExisting, self).__init__(config=config)
        self._servers = [Server(ip=server['host'], username=server['username'], password=server['password']) for server in config]
Пример #14
0
class ProviderLibvirt(Provider):
    """Creates servers in libvirt of localhost
    """
    def sample_config(self):
        return {
            'lab_id':
            'int in range 1-99',
            'username':
            '******',
            'password':
            '******',
            'networks': [41, 61, 42, 43, 62],
            'instances': [{
                'hostname': 'some name',
                'image_url': 'http://path.to.image.file',
                'image_checksum': 'checksum',
                'on_nets': [41, 62]
            }]
        }

    def __init__(self, config):
        import libvirt
        import os
        from lab.server import Server

        super(ProviderLibvirt, self).__init__(config=config)
        self.lab_id = config['lab_id']
        self.username = config['username']
        self.password = config['password']
        self.network_id = config['networks']
        self.network_names = {
            x: '{0}-{1}'.format(self.lab_id, x)
            for x in self.network_id
        }
        self.instances = config['instances']

        self.dir_for_backing_disks = os.path.abspath(
            os.path.join('/tmp', 'libvirt', 'backing_images'))
        self.dir_for_main_disks = os.path.abspath(
            os.path.join('/tmp', 'libvirt', 'main_disks'))
        self.dir_for_saved_xml = os.path.abspath(
            os.path.join('/tmp', 'libvirt', 'saved_xml'))
        self.domain_tmpl = self.read_config_from_file(
            config_path='domain_template.txt',
            directory='libvirt',
            is_as_string=True)
        self.connection = libvirt.open()
        self.servers = []
        self.local = Server(ip='localhost',
                            username='******',
                            password=Server.USE_SSH_KEY)

    def delete_lab(self):
        import libvirt

        servers_and_networks = self.connection.listAllDomains()
        servers_and_networks.extend(self.connection.listAllNetworks())
        for obj in servers_and_networks:
            if obj.name().find(str(self.lab_id)) != -1:
                try:
                    obj.destroy()
                except libvirt.libvirtError:
                    pass
                obj.undefine()
        for bridge in self.local.exe(
                command='brctl show | grep 8000 | grep {0} | cut -f1'.format(
                    self.lab_id)).split('\n'):
            if bridge:
                self.local.exe(
                    'sudo ip l s {0} down && sudo brctl delbr {0}'.format(
                        bridge))
        self.local.exe('rm -f {0}/*{1}*'.format(self.dir_for_main_disks,
                                                self.lab_id))

    def create_networks(self):
        tmpl = '''
<network>
    <name>{name}</name>
    <bridge name='br{name}' />
    <forward mode="nat"/>
    {ip_part}
</network>
'''
        ip_part4 = '<ip address="10.{lab_id}.0.1" netmask="255.255.255.0"><dhcp><range start="10.{lab_id}.0.2" end="10.{lab_id}.0.254" /></dhcp></ip>'.format(
            lab_id=self.lab_id)
        ip_part6 = '<ip family="ipv6" address="20{lab_id:02}::1" prefix="64"></ip>'.format(
            lab_id=self.lab_id)

        for net_id in self.network_id:
            name = self.network_names[net_id]
            xml = tmpl.format(name=name,
                              ip_part=ip_part6 if net_id / 60 else ip_part4)
            self.save_xml(name='net-' + name, xml=xml)
            net = self.connection.networkDefineXML(xml)
            net.create()
            net.setAutostart(True)
            lab_logger.info('Network {0} created'.format(name))

    def save_xml(self, name, xml):
        self.local.r_put_string_as_file_in_dir(
            string_to_put=xml,
            file_name=name,
            in_directory=self.dir_for_saved_xml)

    @decorators.repeat_until_not_false(n_repetitions=50,
                                       time_between_repetitions=5)
    def ip_for_mac_by_looking_at_libvirt_leases(self, net, mac):
        ans = self.local.exe(
            command='sudo grep "{mac}" /var/lib/libvirt/dnsmasq/{net}.leases'.
            format(mac=mac, net=net),
            warn_only=True)
        if ans:
            return ans.split(' ')[2]
        else:
            return ans

    def make_local_file_name(self, where, name, extension):
        import os

        return os.path.abspath(
            os.path.join(where,
                         str(self.lab_id) + name + '.' + extension))

    def create_cloud_init_disk(self, hostname):
        import uuid

        public_key = self.read_config_from_file(config_path='public',
                                                directory='keys',
                                                is_as_string=True)

        user_data = self.read_config_from_file(
            config_path='cloud_init_user_data.txt',
            directory='libvirt',
            is_as_string=True)

        user_data = user_data.replace('{username}', self.username)
        user_data = user_data.replace('{password}', self.password)
        user_data = user_data.replace('{public_key}', public_key)

        user_data_path = self.make_local_file_name(
            where=self.dir_for_main_disks,
            name=hostname,
            extension='user_data')
        with open(user_data_path, 'w') as f:
            f.write(user_data)

        meta_data_path = self.make_local_file_name(
            where=self.dir_for_main_disks,
            name=hostname,
            extension='meta_data')
        with open(meta_data_path, 'w') as f:
            meta_data = 'instance_id: {uuid}\nlocal-hostname: {hostname}\n'.format(
                uuid=uuid.uuid4(), hostname=hostname)
            f.write(meta_data)

        cloud_init_disk_path = self.make_local_file_name(
            where=self.dir_for_main_disks,
            name=hostname,
            extension='cloud_init.qcow2')
        self.local.exe('cloud-localds -d qcow2 {ci_d} {u_d} {m_d}'.format(
            ci_d=cloud_init_disk_path, u_d=user_data_path, m_d=meta_data_path))
        return cloud_init_disk_path

    def create_main_disk(self, hostname, image_url, image_checksum):
        back_disk = self.local.wget_file(
            url=image_url,
            checksum=image_checksum,
            to_directory=self.dir_for_backing_disks)
        main_disk = self.make_local_file_name(where=self.dir_for_main_disks,
                                              name=hostname,
                                              extension='qcow2')
        self.local.exe(
            command='qemu-img create -f qcow2 -b {0} {1} 15G'.format(
                back_disk, main_disk),
            in_directory=self.dir_for_main_disks)

        return main_disk

    def create_server(self, dev_num, hostname, on_nets, image_url,
                      image_checksum):
        from lab.server import Server

        net_tmpl = '''
<interface type='network'>
    <source network='{{net_name}}'/>
    <mac address='{{mac}}'/>
    <target dev='v{{net_name}}-{hostname}'/>
</interface>

'''.format(lab_id=self.lab_id, dev_num=dev_num, hostname=hostname)

        macs = [
            'ee:{lab_id:02}:00:{net_id:02}:00:{dev_num:02}'.format(
                lab_id=self.lab_id, net_id=net_id, dev_num=dev_num)
            for net_id in on_nets
        ]
        net_names = [self.network_names[net_id] for net_id in on_nets]

        net_part = '\n\n'.join([
            net_tmpl.format(net_name=net_names[i], mac=macs[i])
            for i in range(len(on_nets))
        ])

        disk_part = '''
<disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='{main_disk}'/>
    <target dev='vda' bus='virtio'/>
</disk>

<disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='{cloud_init_disk}'/>
    <target dev='hdb' bus='ide'/>
</disk>
'''.format(main_disk=self.create_main_disk(hostname=hostname,
                                           image_url=image_url,
                                           image_checksum=image_checksum),
           cloud_init_disk=self.create_cloud_init_disk(hostname=hostname))

        xml = self.domain_tmpl.format(hostname='{0}-{1}'.format(
            self.lab_id, hostname),
                                      net_part=net_part,
                                      disk_part=disk_part)
        self.save_xml(name=hostname, xml=xml)
        domain = self.connection.defineXML(xml)
        domain.create()

        ip = self.ip_for_mac_by_looking_at_libvirt_leases(net=net_names[0],
                                                          mac=macs[0])

        lab_logger.info(msg='Domain {0} created'.format(hostname))
        return Server(ip=ip,
                      username=self.username,
                      password=Server.USE_SSH_KEY)

    def create_servers(self):
        for server_num, server in enumerate(self.instances, start=1):
            self.servers.append(
                self.create_server(dev_num=server_num,
                                   hostname=server['hostname'],
                                   on_nets=server['on_nets'],
                                   image_url=server['image_url'],
                                   image_checksum=server['image_checksum']))
        return self.servers

    def wait_for_servers(self):
        self.delete_lab()
        self.create_networks()
        servers = self.create_servers()
        for server in servers:
            server.hostname = server.run('hostname')
            pwd = server.run('pwd')
            server.run('chmod 755 {0}'.format(pwd))
            if server.run('ip -o link | grep eth1', warn_only=True):
                server.run('sudo ip l s dev eth1 up')
        return servers
Пример #15
0
from lab.server import Server
from custom_lab import CustomServer


def test_server(server):
    server.set_up_ssh()
    system_info = server.get_system_info()
    print(system_info)
    disk_space = server.get_disk_space()
    print(disk_space)


if __name__ == '__main__':
    node = 'node_7'

    print('--- Regular server example ---')
    with Server('my_server', default_ssh_node=node) as my_server:
        test_server(my_server)

    print('--- Regular server example ---')
    with CustomServer('custom_server', default_ssh_node=node) as custom_server:
        test_server(custom_server)
Пример #16
0
    def analyse_instance_problems(self, instance):
        from lab.server import Server

        instance_details = self.cmd(self._show_server_cmd + instance['Name'])
        compute_node = Server(name='tmp_compute', role='compute', ip=instance_details['os-ext-srv-attr:host'], lab=None, username='******', password='******')
        logs = compute_node.run(command='grep {instance_id} | grep -i error'.format(instance_id=instance_details['id']))
Пример #17
0
    def get_as_sqe(self, rem_rel_path, in_dir, loc_abs_path):
        from lab.server import Server

        return Server(ip=self.ip, username='******',
                      password=None).get(rem_rel_path, in_dir, loc_abs_path)
Пример #18
0
class ProviderLibvirt(Provider):
    """Creates servers in libvirt of localhost
    """

    def sample_config(self):
        return {'lab_id': 'int in range 1-99',
                'username': '******',
                'password': '******',
                'networks': [41, 61, 42, 43, 62],
                'instances': [{'hostname': 'some name', 'image_url': 'http://path.to.image.file', 'image_checksum': 'checksum', 'on_nets': [41, 62]}]}

    def __init__(self, config):
        import libvirt
        import os
        from lab.server import Server

        super(ProviderLibvirt, self).__init__(config=config)
        self.lab_id = config['lab_id']
        self.username = config['username']
        self.password = config['password']
        self.network_id = config['networks']
        self.network_names = {x: '{0}-{1}'.format(self.lab_id, x) for x in self.network_id}
        self.instances = config['instances']

        self.dir_for_backing_disks = os.path.abspath(os.path.join('/tmp', 'libvirt', 'backing_images'))
        self.dir_for_main_disks = os.path.abspath(os.path.join('/tmp', 'libvirt', 'main_disks'))
        self.dir_for_saved_xml = os.path.abspath(os.path.join('/tmp', 'libvirt', 'saved_xml'))
        self.domain_tmpl = self.read_config_from_file(config_path='domain_template.txt', directory='libvirt', is_as_string=True)
        self.connection = libvirt.open()
        self.servers = []
        self.local = Server(ip='localhost', username='******', password=Server.USE_SSH_KEY)

    def delete_lab(self):
        import libvirt

        servers_and_networks = self.connection.listAllDomains()
        servers_and_networks.extend(self.connection.listAllNetworks())
        for obj in servers_and_networks:
            if obj.name().find(str(self.lab_id)) != -1:
                try:
                    obj.destroy()
                except libvirt.libvirtError:
                    pass
                obj.undefine()
        for bridge in self.local.exe(command='brctl show | grep 8000 | grep {0} | cut -f1'.format(self.lab_id)).split('\n'):
            if bridge:
                self.local.exe('sudo ip l s {0} down && sudo brctl delbr {0}'.format(bridge))
        self.local.exe('rm -f {0}/*{1}*'.format(self.dir_for_main_disks, self.lab_id))

    def create_networks(self):
        tmpl = '''
<network>
    <name>{name}</name>
    <bridge name='br{name}' />
    <forward mode="nat"/>
    {ip_part}
</network>
'''
        ip_part4 = '<ip address="10.{lab_id}.0.1" netmask="255.255.255.0"><dhcp><range start="10.{lab_id}.0.2" end="10.{lab_id}.0.254" /></dhcp></ip>'.format(lab_id=self.lab_id)
        ip_part6 = '<ip family="ipv6" address="20{lab_id:02}::1" prefix="64"></ip>'.format(lab_id=self.lab_id)

        for net_id in self.network_id:
            name = self.network_names[net_id]
            xml = tmpl.format(name=name, ip_part=ip_part6 if net_id / 60 else ip_part4)
            self.save_xml(name='net-' + name, xml=xml)
            net = self.connection.networkDefineXML(xml)
            net.create()
            net.setAutostart(True)
            lab_logger.info('Network {0} created'.format(name))

    def save_xml(self, name, xml):
        self.local.r_put_string_as_file_in_dir(string_to_put=xml, file_name=name, in_directory=self.dir_for_saved_xml)

    @decorators.repeat_until_not_false(n_repetitions=50, time_between_repetitions=5)
    def ip_for_mac_by_looking_at_libvirt_leases(self, net, mac):
        ans = self.local.exe(command='sudo grep "{mac}" /var/lib/libvirt/dnsmasq/{net}.leases'.format(mac=mac, net=net), warn_only=True)
        if ans:
            return ans.split(' ')[2]
        else:
            return ans

    def make_local_file_name(self, where, name, extension):
        import os

        return os.path.abspath(os.path.join(where, str(self.lab_id) + name + '.' + extension))

    def create_cloud_init_disk(self, hostname):
        import uuid

        public_key = self.read_config_from_file(config_path='public', directory='keys', is_as_string=True)

        user_data = self.read_config_from_file(config_path='cloud_init_user_data.txt', directory='libvirt', is_as_string=True)

        user_data = user_data.replace('{username}', self.username)
        user_data = user_data.replace('{password}', self.password)
        user_data = user_data.replace('{public_key}', public_key)

        user_data_path = self.make_local_file_name(where=self.dir_for_main_disks, name=hostname, extension='user_data')
        with open(user_data_path, 'w') as f:
            f.write(user_data)

        meta_data_path = self.make_local_file_name(where=self.dir_for_main_disks, name=hostname, extension='meta_data')
        with open(meta_data_path, 'w') as f:
            meta_data = 'instance_id: {uuid}\nlocal-hostname: {hostname}\n'.format(uuid=uuid.uuid4(), hostname=hostname)
            f.write(meta_data)

        cloud_init_disk_path = self.make_local_file_name(where=self.dir_for_main_disks, name=hostname, extension='cloud_init.qcow2')
        self.local.exe('cloud-localds -d qcow2 {ci_d} {u_d} {m_d}'.format(ci_d=cloud_init_disk_path, u_d=user_data_path, m_d=meta_data_path))
        return cloud_init_disk_path

    def create_main_disk(self, hostname, image_url, image_checksum):
        back_disk = self.local.wget_file(url=image_url, checksum=image_checksum, to_directory=self.dir_for_backing_disks)
        main_disk = self.make_local_file_name(where=self.dir_for_main_disks, name=hostname, extension='qcow2')
        self.local.exe(command='qemu-img create -f qcow2 -b {0} {1} 15G'.format(back_disk, main_disk), in_directory=self.dir_for_main_disks)

        return main_disk

    def create_server(self, dev_num, hostname, on_nets, image_url, image_checksum):
        from lab.server import Server

        net_tmpl = '''
<interface type='network'>
    <source network='{{net_name}}'/>
    <mac address='{{mac}}'/>
    <target dev='v{{net_name}}-{hostname}'/>
</interface>

'''.format(lab_id=self.lab_id, dev_num=dev_num, hostname=hostname)

        macs = ['ee:{lab_id:02}:00:{net_id:02}:00:{dev_num:02}'.format(lab_id=self.lab_id, net_id=net_id, dev_num=dev_num) for net_id in on_nets]
        net_names = [self.network_names[net_id] for net_id in on_nets]

        net_part = '\n\n'.join([net_tmpl.format(net_name=net_names[i], mac=macs[i]) for i in range(len(on_nets))])

        disk_part = '''
<disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='{main_disk}'/>
    <target dev='vda' bus='virtio'/>
</disk>

<disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='{cloud_init_disk}'/>
    <target dev='hdb' bus='ide'/>
</disk>
'''.format(main_disk=self.create_main_disk(hostname=hostname, image_url=image_url, image_checksum=image_checksum), cloud_init_disk=self.create_cloud_init_disk(hostname=hostname))

        xml = self.domain_tmpl.format(hostname='{0}-{1}'.format(self.lab_id, hostname), net_part=net_part, disk_part=disk_part)
        self.save_xml(name=hostname, xml=xml)
        domain = self.connection.defineXML(xml)
        domain.create()

        ip = self.ip_for_mac_by_looking_at_libvirt_leases(net=net_names[0], mac=macs[0])

        lab_logger.info(msg='Domain {0} created'.format(hostname))
        return Server(ip=ip, username=self.username, password=Server.USE_SSH_KEY)

    def create_servers(self):
        for server_num, server in enumerate(self.instances, start=1):
            self.servers.append(self.create_server(dev_num=server_num, hostname=server['hostname'], on_nets=server['on_nets'],
                                                   image_url=server['image_url'], image_checksum=server['image_checksum']))
        return self.servers

    def wait_for_servers(self):
        self.delete_lab()
        self.create_networks()
        servers = self.create_servers()
        for server in servers:
            server.hostname = server.run('hostname')
            pwd = server.run('pwd')
            server.run('chmod 755 {0}'.format(pwd))
            if server.run('ip -o link | grep eth1', warn_only=True):
                server.run('sudo ip l s dev eth1 up')
        return servers