def check(self, task): node = task.get_obj('Node') conn = node.libvirt_conn() for vm in node.vm_set.filter(state__in=['running', 'starting']): try: libvirt_vm = conn.lookupByName(vm.libvirt_name) except Exception as e: vm.set_state('stopped') vm.save() log(msg='Failed to find VM %s at node %s' % (vm.id, vm.node.address), exception=e, tags=('agent', 'node', 'error'), context=task.logger_ctx) if libvirt_vm.state() == libvirt.VIR_DOMAIN_RUNNING: vm.set_state('running') vm.save() else: vm.set_state('stopped') vm.save() conn.close() node.state = 'ok' node.save()
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()
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()
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)
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()
def start(self): super(Hook, self).finish() network = self.task.get_obj('Subnet') try: dnsmasq_procs = [int(x) for x in subprocess.check_output(['pgrep', 'dnsmasq']).splitlines()] ns_procs = [int(x) for x in subprocess.check_output(['sudo', 'ip', 'netns', 'pids', network.netns_name]).splitlines()] for pid in ns_procs: if pid in dnsmasq_procs: try: #os.kill(pid, 15) subprocess.call(['sudo', 'ip', 'netns', 'exec', network.netns_name, 'kill', '-15', str(pid)]) except: pass except Exception, e: log(msg="Failed to kill DHCP process: " + str(e), tags=('agent', 'dhcp', 'network'))
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()
def get_user_data(request, auth_hash, auth_seed, vm_ip): log(msg='Serving cloudinit for %s' % vm_ip, tags=('coretalk', 'debug')) try: lease = resolve_ip(auth_hash, auth_seed, vm_ip) except: return HttpResponse('none') vm = lease.vm if vm == None: return HttpResponse('none') try: user_data_id = vm.get_prop('coretalk_user_data') except: return HttpResponse('none') try: user_data = UserData.objects.get(id=user_data_id) return HttpResponse(user_data.data) except: return HttpResponse('none')
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()