コード例 #1
0
    def detach(self, task):
        vm = task.get_obj('VM')

        vm.node.check_online(task.ignore_errors)

        image = task.get_obj('Image')

        conn = vm.node.libvirt_conn()
        if not vm.in_states(['stopped', 'closed']) and not task.ignore_errors:
            raise TaskError('vm_not_stopped')

        system.call([
            'scp',
            '%s@%s:/images/permanent-%s' %
            (vm.node.username, vm.node.address, vm.id),
            image.storage.path + '/' + image.libvirt_name + '-tmp'
        ])

        system.call([
            'mv', image.storage.path + '/' + image.libvirt_name + '-tmp',
            image.storage.path + '/' + image.libvirt_name
        ])

        image.attached_to = None
        image.save()

        for device in Device.objects.filter(object_id=image.id).all():
            device.delete()

        try:
            vm.libvirt_redefine()
        except:
            pass

        conn.close()
コード例 #2
0
    def suspend(self, task):
        """
        Suspend node to RAM for defined in config seconds. After this time + NODE_WAKEUP_TIME
        node is suspended again, unles it's state is not wake up. Available only
        in admin site or through plugins.
        """
        node = task.get_obj('Node')

        if VM.objects.filter(node=node).exclude(state='closed').count() > 0:
            task.comment = "Node is in use. Aborting suspend"
            task.save()
            return

        node.set_state('suspend')
        node.save()

        log(msg="suspending node %s" % node.address,
            tags=('agent', 'node', 'info'),
            context=task.logger_ctx)
        system.call(['ping', '-c', '1', node.address])

        arp = open('/proc/net/arp', 'r').readlines()
        for line in arp:
            fields = line.split()
            if fields[0] == node.address:
                node.set_prop('mac', fields[3])

        node.save()

        conn = node.libvirt_conn()
        conn.suspendForDuration(libvirt.VIR_NODE_SUSPEND_TARGET_MEM,
                                config.get('core', 'NODE_SUSPEND_DURATION'))
        conn.close()
コード例 #3
0
    def create(self, task):
        image = task.get_obj('Image')
        system.call('dog vdi create %s %d' % (image.libvirt_name, image.size),
                    shell=True)

        image.set_state('ok')
        image.save()
コード例 #4
0
ファイル: vpn.py プロジェクト: cloudOver/corevpn
    def mk_ca(self, vpn):
        if not os.path.exists('/var/lib/cloudOver/coreVpn/certs/%s' % vpn.id):
            os.mkdir('/var/lib/cloudOver/coreVpn/certs/%s' % vpn.id)

        if os.path.exists(vpn.ca_key_file):
            raise Exception('vpn_exists')

        if vpn.ca_crt != '' and vpn.ca_crt != None:
            raise Exception('vpn_ca_exists')

        system.call(['openssl',
                     'genrsa',
                     '-out', vpn.ca_key_file,
                     str(config.get('vpn', 'CA_KEY_SIZE'))])

        system.call(['openssl',
                     'req',
                     '-x509',
                     '-new',
                     '-nodes',
                     '-key', vpn.ca_key_file,
                     '-days', str(config.get('vpn', 'CERTIFICATE_LIFETIME')),
                     '-out', vpn.ca_crt_file,
                     '-subj', '/CN=CoreVpn-%s/O=CloudOver/OU=CoreVpn' % vpn.id])

        vpn.ca_crt = open(vpn.ca_crt_file, 'rb').read(1024*1024)
        vpn.save()
コード例 #5
0
    def save_image(self, task):
        node = task.get_obj('Node')
        node.check_online(task.ignore_errors)

        vm = task.get_obj('VM')
        image = task.get_obj('Image')
        if not vm.in_state('stopped'):
            raise TaskNotReady('vm_not_stopped')

        vm.set_state('saving')
        vm.save()

        system.call([
            'scp',
            '%s@%s:/images/%s' % (node.username, node.address, vm.id),
            image.storage.path + '/' + image.libvirt_name
        ])

        vm.set_state('stopped')
        vm.save()

        image.state = long(
            subprocess.check_output("qemu-img info " + image.storage.path +
                                    '/' + image.libvirt_name +
                                    " | grep 'virtual size'",
                                    shell=True).split()[3][1:])
        image.set_state('ok')
        image.save()
コード例 #6
0
 def wake_up(self, task):
     node = task.get_obj('Node')
     if node.has_prop('mac'):
         system.call(['wakeonlan', node.get_prop('mac')])
         if node.in_state('suspend'):
             time.sleep(config.get('core', 'NODE_WAKEUP_TIME'))
             node.start()
     else:
         raise TaskError('Cannot find node\'s MAC')
コード例 #7
0
 def _sheepdog_startup(self):
     for i in range(30):
         r = system.call('dog node list', shell=True)
         if r == 0:
             break
         else:
             log(msg="sheepdog_startup: Restarting shepdog service", tags=('system', 'info'))
             system.call('service sheepdog restart', shell=True)
             time.sleep(i)
コード例 #8
0
ファイル: userdata.py プロジェクト: cloudOver/coretalk
def attach_configdrive(context, userdata_id, vm_id):
    userdata = UserData.get(context.user_id, userdata_id)
    vm = VM.get(context.user_id, vm_id)

    system.call(['mkdir', '-p', '/tmp/configdrive_' + userdata.id + '/openstack/latest/'])
    ud = open('/tmp/configdrive_' + userdata.id + '/openstack/latest/user_data', 'w')
    ud.write(userdata.data)
    ud.close()

    # Detailed instruction: https://coreos.com/os/docs/latest/config-drive.html
    #TODO: Convert to: http://serverfault.com/questions/43634/how-to-mount-external-vfat-drive-as-user
    system.call(['genisoimage', '-R', '-V', 'config-2', '-o', '/tmp/configdrive_' + userdata.id + '.img', '/tmp/configdrive_' + userdata.id])
    system.call(['rm', '-rf', '/tmp/configdrive_' + userdata.id])
    system.call(['qemu-img', 'convert', '-f', 'raw', '-O', 'qcow2', '/tmp/configdrive_' + userdata.id + '.img', '/tmp/configdrive_' + userdata.id + '.qcow2'])
    system.call(['rm', '-rf', '/tmp/configdrive_' + userdata.id + '.img'])

    image = Image.create(name='CoreTalk ConfigDrive',
                         description='UserData: %s, VM: %s' % (userdata.id, vm.id),
                         access='private',
                         format='qcow2',
                         size=os.stat('/tmp/configdrive_' + userdata.id + '.qcow2').st_size,
                         type='permanent',
                         disk_controller='virtio',
                         user=vm.user)
    image.save()

    create_img = Task()
    create_img.user_id = context.user_id
    create_img.type = 'image'
    create_img.action = 'create'
    create_img.append_to([vm, image, image.storage])

    chunk = DataChunk()
    contents = open('/tmp/configdrive_' + userdata.id + '.qcow2').read(image.size)
    chunk.data = base64.b64encode(contents)
    chunk.offset = 0
    chunk.image_id = image.id
    chunk.type = 'upload'
    chunk.save()

    upload_data = Task()
    upload_data.user_id = context.user_id
    upload_data.type = 'image'
    upload_data.action = 'upload_data'
    upload_data.set_all_props({'offset': 0,
                               'size': image.size,
                               'chunk_id': chunk.cache_key()})
    upload_data.append_to([image, vm])

    attach_img = Task()
    attach_img.user_id = context.user_id
    attach_img.type = 'image'
    attach_img.action = 'attach'
    attach_img.append_to([vm, image])
コード例 #9
0
 def create(self, task):
     image = task.get_obj('Image')
     system.call([
         'qemu-img', 'create', '-f', image.format,
         image.storage.path + '/' + image.libvirt_name,
         str(image.size)
     ])
     image.size = os.stat(image.storage.path + '/' +
                          image.libvirt_name).st_size
     image.set_state('ok')
     image.save()
コード例 #10
0
    def delete(self, task):
        '''
        Delete base image from node
        '''
        vm = task.get_obj('VM')

        vm.node.check_online(task.ignore_errors)

        if vm.state not in ['stopped', 'closed', 'closing'] and not task.ignore_errors:
            raise TaskNotReady('vm_not_stopped')

        system.call('dog vdi delete %s' % (vm.id), shell=True)
コード例 #11
0
    def delete(self, task):
        image = task.get_obj('Image')
        if image.attached_to != None and not image.attached_to.in_state(
                'closed') and not task.ignore_errors:
            raise TaskError('image_attached')

        for vm in image.vm_set.all():
            if not vm.in_state('closed') and not task.ignore_errors:
                raise TaskError('image_attached')

        system.call(['rm', image.storage.path + '/' + image.libvirt_name])
        image.set_state('deleted')
        image.save()
コード例 #12
0
    def delete(self, task):
        image = task.get_obj('Image')
        if image.attached_to is not None and not task.ignore_errors:
            raise TaskError('image_attached')

        for vm in image.vm_set.all():
            if not vm.in_state('closed') and not task.ignore_errors:
                raise TaskError('image_attached')

        system.call('dog vdi delete %s' % image.libvirt_name, shell=True)
        system.call('dog vdi delete %s_tmp' % image.libvirt_name, shell=True)

        image.set_state('deleted')
        image.save()
コード例 #13
0
    def resize_image(self, task):
        vm = task.get_obj('VM')

        vm.node.check_online(task.ignore_errors)

        if not vm.in_state('stopped'):
            raise TaskNotReady('vm_not_stopped')

        system.call([
            'ssh', '-l', vm.node.username, vm.node.address, 'qemu-img',
            'resize'
            '/images/%s' % vm.id,
            str(task.get_prop('size'))
        ])
コード例 #14
0
    def delete(self, task):
        '''
        Delete volume
        '''
        node = task.get_obj('Node')
        node.check_online(task.ignore_errors)
        vm = task.get_obj('VM')
        if vm.state not in ['stopped', 'closed', 'closing'
                            ] and not task.ignore_errors:
            raise TaskNotReady('vm_not_stopped')

        system.call([
            'ssh', '-l', node.username, node.address, 'rm',
            '/images/' + str(vm.id)
        ])
コード例 #15
0
    def upload_url(self, task):
        '''
        Download datq from url and put its contents into given image. Operation.data
        should contains:
        - action
        - url
        - size
        '''
        image = task.get_obj('Image')
        if image.attached_to != None:
            raise TaskError('image_attached')

        image.set_state('downloading')
        image.save()

        try:
            volume = open(image.storage.path + '/' + image.libvirt_name, 'r+')
        except Exception as e:
            raise TaskFatalError('libvirt_image_not_found', exception=e)

        try:
            remote = urllib2.urlopen(task.get_prop('url'))
        except Exception as e:
            raise TaskError('url_not_found', exception=e)

        bytes = 0
        while bytes < int(task.get_prop('size')):
            data = remote.read(1024 * 250)
            if len(data) == 0:
                break
            volume.write(data)
            bytes += len(data)
            image = task.get_obj('Image')
            image.set_prop('progress',
                           float(bytes) / float(task.get_prop('size')))
            image.save()

        remote.close()
        volume.close()

        log(msg="Rebasing image to no backend",
            tags=('agent', 'image', 'info'),
            context=task.logger_ctx)
        if image.format in ['qcow2', 'qed']:
            r = system.call([
                'sudo', 'qemu-img', 'rebase', '-u', '-f', image.format, '-u',
                '-b', '', image.storage.path + '/' + image.libvirt_name
            ],
                            stderr=None,
                            stdout=None)
            if r != 0:
                image.set_state('failed')
                image.save()
                return

        image = task.get_obj('Image')
        image.size = os.stat(image.storage.path + '/' +
                             image.libvirt_name).st_size
        image.set_state('ok')
        image.save()
コード例 #16
0
    def load_image(self, task):
        node = task.get_obj('Node')
        node.check_online(task.ignore_errors)

        vm = task.get_obj('VM')
        image = task.get_obj('Image')

        if image.state != 'ok':
            raise TaskNotReady('image_wrong_state')

        system.call([
            'scp', image.storage.path + '/' + image.libvirt_name,
            '%s@%s:/images/%s' % (node.username, node.address, vm.id)
        ])

        vm.set_state('stopped')
        vm.save()
コード例 #17
0
    def attach(self, task):
        vm = task.get_obj('VM')

        vm.node.check_online(task.ignore_errors)

        image = task.get_obj('Image')
        conn = vm.node.libvirt_conn()

        if image.attached_to != None and not image.attached_to.in_state(
                'closed'):
            raise TaskError('image_attached')

        if not vm.in_state('stopped'):
            raise TaskError('vm_not_stopped')

        if not image.in_state('ok'):
            raise TaskError('image_state')

        devices = [i.disk_dev for i in vm.image_set.all()]
        if 'device' in task.get_all_props().keys() and not int(
                task.get_prop('device')) in devices:
            disk_dev = int(task.get_prop('device'))
        else:
            disk_dev = 1
            while disk_dev in devices:
                disk_dev = disk_dev + 1

        image.disk_dev = disk_dev
        image.attached_to = vm
        image.save()

        system.call([
            'scp', image.storage.path + '/' + image.libvirt_name,
            '%s@%s:/images/permanent-%s' %
            (vm.node.username, vm.node.address, vm.id)
        ])

        Device.create(image.id, vm, 'devices/image.xml', {
            'img': image,
            'disk_dev': 'sd' + chr(ord('a') + disk_dev),
            'vm': vm
        })

        vm.libvirt_redefine()

        conn.close()
コード例 #18
0
ファイル: vpn.py プロジェクト: cloudOver/corevpn
    def delete(self, task):
        vpn = task.get_obj('VPN')

        vpn.set_state('removing')
        vpn.save()
        try:
            pid = int(open('/var/lib/cloudOver/coreVpn/%s.pid' % vpn.id, 'rb').read(1024))
            system.call(['sudo', 'kill', '-15', str(pid)])
        except Exception as e:
            log(msg='Failed to kill openvpn process', exception=e, tags=('corevpn', 'error'))

        system.call('rm -rf /var/lib/cloudOver/coreVpn/certs/%s' % vpn.id, shell=True)

        try:
            os.remove('/var/lib/cloudOver/coreVpn/%s.pid' % vpn.id)
        except:
            log(msg='Failed to remove pid file', tags=('error'))

        vpn.set_state('removed')
        vpn.save()
コード例 #19
0
    def save_image(self, task):
        vm = task.get_obj('VM')

        vm.node.check_online(task.ignore_errors)

        image = task.get_obj('Image')

        if not vm.in_state('stopped'):
            raise TaskNotReady('vm_not_stopped')

        vm.set_state('saving')
        vm.save()

        # Save snapshot from VM (based on vm.base_image) to clone of image (operation.image)
        rc = None
        if not task.ignore_errors:
            rc = 0
        system.call('dog vdi snapshot -s snap_%s %s' % (vm.id, vm.id), shell=True, retcode=rc)
        system.call('dog vdi clone -s snap_%s %s %s' % (vm.id, vm.id, image.libvirt_name), shell=True, retcode=rc)
        system.call('dog vdi delete -s snap_%s %s' % (vm.id, vm.id), shell=True, retcode=rc)

        vm.set_state('stopped')
        vm.save()

        image.set_state('ok')
        image.save()
コード例 #20
0
ファイル: dhcp.py プロジェクト: cloudOver/coredhcp
    def start_dhcp(self, task):
        network = task.get_obj('Subnet')

        self.stop_dhcp(task)

        gateway = network.get_prop('gateway', None)
        if gateway is None:
            #TODO: Exception?
            return

        system.call(['ip', 'link', 'set', network.isolated_bridge_name, 'up'], netns=network.netns_name)
        system.call(['ip', 'addr', 'add', 'dev', network.isolated_bridge_name, '%s/%d' % (gateway, network.mask)], netns=network.netns_name)

        dnsmasq = ['dnsmasq',
                   '-O', '3',
                   '-O', '6',
                   '-i', network.isolated_bridge_name,
                   '-F', '%s,%s' % (str(network.to_ipnetwork().ip+1), str(network.to_ipnetwork().broadcast-1))]

        for lease in network.lease_set.all():
            dnsmasq.append('-G')
            dnsmasq.append('%s,%s' % (str(lease.mac), str(lease.address)))

        system.call(dnsmasq, netns=network.netns_name, background=True)

        network.set_prop('dhcp_running', True)
        network.save()
コード例 #21
0
    def start_dhcp(self, task):
        network = task.get_obj('Subnet')

        self.stop_dhcp(task)

        gateway = network.get_prop('gateway', None)
        if gateway is None:
            #TODO: Exception?
            return

        system.call(['ip', 'link', 'set', network.isolated_bridge_name, 'up'],
                    netns=network.netns_name)
        system.call([
            'ip', 'addr', 'add', 'dev', network.isolated_bridge_name,
            '%s/%d' % (gateway, network.mask)
        ],
                    netns=network.netns_name)

        dnsmasq = [
            'dnsmasq', '-O', '3', '-O', '6', '-i',
            network.isolated_bridge_name, '-F',
            '%s,%s' % (str(network.to_ipnetwork().ip + 1),
                       str(network.to_ipnetwork().broadcast - 1))
        ]

        for lease in network.lease_set.all():
            dnsmasq.append('-G')
            dnsmasq.append('%s,%s' % (str(lease.mac), str(lease.address)))

        system.call(dnsmasq, netns=network.netns_name, background=True)

        network.set_prop('dhcp_running', True)
        network.save()
コード例 #22
0
ファイル: vpn.py プロジェクト: cloudOver/corevpn
    def mk_cert(self, vpn, name):
        if not os.path.exists(vpn.ca_key_file):
            raise Exception('vpn_root_ca_not_found')

        # Create key
        system.call(['openssl',
                     'genrsa',
                     '-out', vpn.client_key_file(name),
                     str(config.get('vpn', 'CLIENT_KEY_SIZE'))])

        # Create certificate sign request
        system.call(['openssl',
                     'req',
                     '-new',
                     '-key', vpn.client_key_file(name),
                     '-out', vpn.client_key_file(name) + '.csr',
                     '-subj', '/CN=server/O=CloudOver/OU=CoreVpn/'])

        system.call(['openssl',
                     'x509',
                     '-req',
                     '-in', vpn.client_key_file(name) + '.csr',
                     '-CA', vpn.ca_crt_file,
                     '-CAkey', vpn.ca_key_file,
                     '-CAcreateserial',
                     '-out', vpn.client_crt_file(name),
                     '-days', str(config.get('vpn', 'CERTIFICATE_LIFETIME'))])
コード例 #23
0
    def upload_data(self, task):
        '''
        Put file given in operation.data['filename'] into given image (operation.image)
        at offset. The file can extend existing image. Operation.data should contain:
        - action
        - offset
        - filename
        '''
        image = task.get_obj('Image')
        if image.attached_to != None:
            raise TaskError('image_attached')

        image.set_state('downloading')
        image.save()

        try:
            volume = open(image.storage.path + '/' + image.libvirt_name, 'r+')
        except Exception as e:
            raise TaskFatalError('image_not_found', exception=e)

        data_chunk = DataChunk(cache_key=task.get_prop('chunk_id'))
        data = base64.b64decode(data_chunk.data)

        volume.seek(data_chunk.offset)
        volume.write(data)
        volume.close()

        data_chunk.delete()

        log(msg="Rebasing image to no backend",
            tags=('agent', 'image', 'info'),
            context=task.logger_ctx)
        if image.format in ['qcow2', 'qed']:
            r = system.call([
                'sudo', 'qemu-img', 'rebase', '-u', '-f', image.format, '-u',
                '-b', '', image.storage.path + '/' + image.libvirt_name
            ],
                            stderr=None,
                            stdout=None)
            if r != 0:
                image = task.get_obj('Image')
                image.set_state('failed')
                image.save()
                return

        image = task.get_obj('Image')
        image.size = os.stat(image.storage.path + '/' +
                             image.libvirt_name).st_size
        image.set_state('ok')
        image.save()
コード例 #24
0
    def load_image(self, task):
        image = task.get_obj('Image')
        vm = task.get_obj('VM')

        vm.node.check_online(task.ignore_errors)

        if image.state != 'ok':
            raise TaskNotReady('image_wrong_state')

        rc = None
        if not task.ignore_errors:
            rc = 0

        system.call('dog vdi snapshot -s snap_%s %s' % (vm.id, image.libvirt_name), shell=True, retcode=rc)
        system.call('dog vdi clone -s snap_%s %s %s' % (vm.id, image.libvirt_name, vm.id), shell=True, retcode=rc)
        system.call('dog vdi delete -s snap_%s %s' % (vm.id, image.libvirt_name), shell=True, retcode=rc)
コード例 #25
0
ファイル: vpn.py プロジェクト: cloudOver/corevpn
    def mk_openvpn(self, vpn, network):
        p = system.call(['sudo', 'openvpn',
                         '--config', vpn.config_file,
                         '--writepid', '/var/lib/cloudOver/coreVpn/%s.pid' % vpn.id], background=True)
        vpn.openvpn_pid = p
        vpn.save()

        for i in range(60):
            r = system.call(['ip', 'link', 'show', vpn.interface_name])
            if r > 0:
                time.sleep(1)
                continue
            else:
                break

        system.call(['sudo', 'brctl', 'addif', network.isolated_bridge_name, vpn.interface_name])
        system.call(['sudo', 'ip', 'link', 'set', vpn.interface_name, 'up'])
コード例 #26
0
    def umount(self, task):
        system.call('service sheepdog stop', shell=True)

        storage = task.get_obj('Storage')
        storage.state = 'locked'
        storage.save()
コード例 #27
0
 def create_images_pool(self, task):
     node = task.get_obj('Node')
     system.call(
         ['ssh', '-l', node.username, node.address, 'mkdir', '/images'])
コード例 #28
0
ファイル: vpn.py プロジェクト: cloudOver/corevpn
 def mk_dh(self, vpn):
     system.call(['openssl',
                  'dhparam',
                  '-out', vpn.dh_file,
                  '1024'])
コード例 #29
0
    def upload_url(self, task):
        '''
        Download datq from url and put its contents into given image. Operation.data
        should contains:
        - action
        - url
        - size
        '''
        image = task.get_obj('Image')
        if image.attached_to is not None:
            raise TaskError('image_attached')

        image.set_state('downloading')
        image.save()

        try:
            remote = urllib2.urlopen(task.get_prop('url'))
        except Exception as e:
            raise TaskError('url_not_found', exception=e)

        # Create temporary object
        system.call('dog vdi create %s_tmp %s' %
                    (image.libvirt_name, task.get_prop('size')),
                    shell=True)
        bytes = 0

        while bytes < int(task.get_prop('size')):
            data = remote.read(1024 * 1024)
            if len(data) == 0:
                log(msg='End of data',
                    context=task.logger_ctx,
                    tags=('agent', 'image', 'info'))
                break
            try:
                p = subprocess.Popen([
                    'dog', 'vdi', 'write', image.libvirt_name + '_tmp',
                    str(bytes)
                ],
                                     stdin=subprocess.PIPE)
                p.stdin.write(data)
                p.stdin.close()
                p.wait()
            except Exception as e:
                log(msg='Failed to finish download at %d bytes' % bytes,
                    exception=e,
                    context=task.logger_ctx,
                    tags=('agent', 'image', 'error'))
                break

            bytes += len(data)
            image.set_prop('progress',
                           float(bytes) / float(task.get_prop('size')))
            image.save()

        log(msg='Converting image %s to no-backend' % (image.libvirt_name),
            context=task.logger_ctx,
            tags=('agent', 'network', 'debug'))
        system.call('dog vdi delete %s' % image.libvirt_name, shell=True)
        r = system.call([
            'qemu-img', 'convert', '-f', image.format,
            'sheepdog:%s_tmp' % image.libvirt_name, '-O', 'raw',
            'sheepdog:%s' % image.libvirt_name
        ])

        if r != 0:
            image.set_state('failed')
            image.save()
            return

        system.call('dog vdi delete %s_tmp' % image.libvirt_name, shell=True)

        image.size = int(task.get_prop('size'))
        image.set_state('ok')
        image.save()

        remote.close()