def download(caller_id, description, name, path, disk_dev, disk_controller): """ Downloads specified StorateImage from remote path. @cmview_admin_cm @param_post{description,string} @param_post{name,string} how to name newly downloaded storage image @param_post{path,string} HTTP or FTP path to download StorageImage. @param_post{disk_dev} @param_post{disk_controller} """ # size value is taken try: connection = urllib.urlopen(path) size = int(connection.info()["Content-Length"]) except IOError: log.exception('Cannot find image') raise CMException('image_not_found') except KeyError: log.exception(caller_id, 'Cannot calculate size') raise CMException('image_calculate_size') user = User.get(caller_id) image = StorageImage.create(name=name, description=description, user=user, disk_dev=disk_dev, disk_controller=disk_controller) try: image.save() except Exception, e: log.error(caller_id, "Unable to save image to DB: %s" % str(e)) raise CMException('image_create')
def destroy(vms): """ @parameter{vms} @response result """ results = [] for vm in vms: vm = VM.objects.get(pk=vm.id) log.debug(vm.user.id, "Killing VM id: %s, state: %s" % (vm.id, vm.state)) # Check for VM state if vm.state in (vm_states['closing'], vm_states['saving']): results.append({'status': 'vm_already_closing', 'data': ''}) continue if vm.state in (vm_states['erased'], vm_states['closed']): results.append({'status': 'vm_wrong_state', 'data': ''}) continue vm.save_vm = 0 try: vm.save() transaction.commit() vm.lv_destroy() except Exception, e: log.exception(vm.user.id, 'error destroying VM: %s' % str(e)) results.append({'status': 'vm_destroy', 'data': ''}) message.error(vm.user_id, 'vm_destroy', { 'id': vm.id, 'name': vm.name }) continue results.append({'status': 'ok', 'data': ''})
def download(caller_id, description, name, path, disk_controller, network_device, platform, video_device): """ Downloads image depending on the \c data parameter. @cmview_admin_cm @parameter{description,string} @parameter{name,string} @parameter{path,string} HTTP or FTP path to image to download @parameter{type,image_types} type of image, automatically set, type is in the URL requested @response{None} """ # size value is taken try: connection = urllib.urlopen(path) size = int(connection.info()["Content-Length"]) except IOError: log.exception(caller_id, 'Cannot find image') raise CMException('image_not_found') except KeyError: log.exception(caller_id, 'Cannot calculate size') raise CMException('image_calculate_size') user = User.get(caller_id) image = SystemImage.create(name=name, description=description, user=user, platform=platform, disk_controller=disk_controller, network_device=network_device, video_device=video_device) try: image.save() except Exception, e: log.error(caller_id, "Unable to save image to DB: %s" % str(e)) raise CMException('image_create')
def detach(self, vm): """ Requests Libvirt to detach from given VM this StorageImage. @parameter{vm,VM} VM from which StorageImage should be detached. @raises{storage_image_detach,CMException} cannot detach StorageImage """ domain = vm.lv_domain() try: device_desc = """<disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='%(path)s'/> <target dev='%(dev)s' bus='%(bus)s'/> <alias name='%(bus)s-%(dev)s'/> </disk>""" % { 'path': self.path, 'dev': 'sd%s' % chr(self.disk_dev + 98), 'bus': self.disk_controller_name } domain.detachDevice(device_desc) except: log.exception(self.user.id, 'storage detach') raise CMException('storage_image_detach') self.vm = None
def wrapper(request, *args, **kwargs): data = request.GET.dict() data['remote_ip'] = request.META.get('REMOTE_ADDR') gen_exception = False log_enabled = kw.get('log', False) name = '%s.%s' % (fun.__module__.replace('cm.views.', ''), fun.__name__) if log_enabled: log.debug(0, '=' * 100) log.debug(0, 'Function: %s' % name) log.debug(0, 'Args:\n%s' % json.dumps(data, indent=4)) with transaction.commit_manually(): try: # Execute function resp = fun(**data) transaction.commit() except CMException, e: transaction.rollback() log.exception(0, 'CMException %s' % e) resp = e.response except Exception, e: transaction.rollback() gen_exception = True resp = response('cm_error', str(e))
def create(self): """ Starts VM's thread. -# Gets VM's record from database (basing on vm_id) (if exists). -# Copies image chosen for this VM. -# Connects to Libvirt and generate template for it. -# Creates Libvirt domain. -# Sets VM's state as *running* -# If VM is element of farm, it sets proper farm state. """ try: log.info( self.vm.user_id, "Copy image from %s to %s" % (self.vm.system_image.path, self.vm.path)) self.vm.system_image.copy_to_node(self.vm) except Exception, e: log.exception(self.vm.user_id, 'Libvirt error for %d: %s' % (self.vm.id, e)) self.vm.set_state('failed') message.error(self.vm.user_id, 'vm_create', { 'id': self.vm.id, 'name': self.vm.name }) self.vm.node.lock() self.vm.save(update_fields=['state']) return
def create(self): if not self.vm: raise Exception('No VM specified') rarg = [ "%s" % (self.filepath), "--step", "%d" % settings.PERIOD, "DS:cpu_count:GAUGE:%d:0:100000" % (settings.PERIOD * 2), "DS:cpu_time:COUNTER:%d:0:100000" % (settings.PERIOD * 2), "DS:rd_req:COUNTER:%d:0:100000000" % (settings.PERIOD * 2), "DS:rd_bytes:COUNTER:%d:0:100000000" % (settings.PERIOD * 2), "DS:wr_req:COUNTER:%d:0:100000000" % (settings.PERIOD * 2), "DS:wr_bytes:COUNTER:%d:0:100000000" % (settings.PERIOD * 2), "DS:rx_bytes:COUNTER:%d:0:100000000" % (settings.PERIOD * 2), "DS:rx_packets:COUNTER:%d:0:100000000" % (settings.PERIOD * 2), "DS:tx_bytes:COUNTER:%d:0:100000000" % (settings.PERIOD * 2), "DS:tx_packets:COUNTER:%d:0:100000000" % (settings.PERIOD * 2), ] for s in settings.STATS: rarg.append("RRA:AVERAGE:0.5:%d:%d" % (s[0], s[1])) try: ret = rrdtool.create(rarg) # all data = 3,1MB if ret: log.error(0, 'update error: %s' % (rrdtool.error())) except Exception, e: log.exception(0, e)
def get(self): try: t = self.pop(0) self.append(t) return t except Exception, e: log.exception(0, e)
def run(self): copied = 0 prev_progress = 0 try: size = os.path.getsize(self.src_image.path) dirpath = os.path.dirname(self.dest_image.path) if not os.path.exists(dirpath): os.mkdir(dirpath) src = open(self.src_image.path, "r") dst = open(self.dest_image.path, "w") while 1: buff = src.read(1024 * 1024) # Should be less than MTU? if len(buff) > 0 and copied <= size: dst.write(buff) copied = copied + len(buff) else: break # Update image information: progress = 100 * copied / size if progress > prev_progress: prev_progress = progress self.dest_image.progress = progress self.dest_image.save(update_fields=['progress']) self.dest_image.state = image_states['ok'] self.dest_image.size = self.src_image.size self.dest_image.save(update_fields=['progress', 'state', 'size']) src.close() dst.close() except Exception, e: log.exception(self.dest_image.user.id, "Failed to copy image: %s" % str(e)) self.dest_image.state = image_states['failed'] self.dest_image.save(update_fields=['state'])
def delete(self): """ Method releases resources taken by deleted ex VM. """ VM.objects.update() self = VM.objects.get(pk=self.id) if self.save_vm > 0: log.debug(self.user.id, 'Saving image') self.save_image() log.debug(self.user.id, 'Removing image') self.remove() log.debug(self.user.id, 'Releasing resources') self.release_resources() # Update vm state self.set_state('closed') """ #TODO: if self.is_head(): self.farm.state = farm_states['closed'] """ self.stop_time = datetime.now() try: self.save(update_fields=['state', 'stop_time']) except Exception, e: log.exception(self.user.id, "Cannot commit changes: %s" % e)
def register_node(vm): """ Called from CLM when registering worker nodes of the farm @parameter{vm,vm} VM database mapper """ log.debug(vm.user_id, "machine %d: registered as worker node" % vm.id) try: hosts = vm.farm.hosts() log.debug( vm.user_id, "vm: %d, host list to inject into WNs: %s" % (vm.id, str(hosts))) Command.execute('add_ssh_key', vm.user_id, vm.id, user=vm.ssh_username, ssh_key=vm.ssh_key) Command.execute('update_hosts', vm.user_id, vm.id, hosts_list=hosts, user=vm.ssh_username) Command.execute('set_hostname', vm.user_id, vm.id, hostname=vm.name.replace(vm.farm.name, 'farm')) except Exception: log.exception(vm.user_id, 'configuring farm failed for machine %d' % vm.id) raise Exception('configuring farm failed') log.info(vm.user_id, 'WN %d registered' % vm.id)
def prepare_temporary_pool_xml(self, image): """ Create temporary Libvirt Pool description to copy from/to images. storage and user parameters are used to define storage path @raises{cm_template_create,CMException} """ try: django_settings.configure() except Exception: pass try: # Open template file template = open("%s/storage_dir.xml" % settings.TEMPLATE_DIR).read() # Create django template st_template = loader.get_template_from_string(template) c = Context({ 'parent_pool': image.storage.name, 'user': image.user.id, 'cc_userid': 331, 'cc_groupid': 331 }) t = st_template.render(c) log.info(self.user.id, "Rendered template: %s" % t) except Exception, e: log.exception(self.user.id, "Cannot create template: %s" % str(e)) raise CMException('cm_template_create')
def download(caller_id, name, description, path, disk_controller): """ Downloads specified IsoImage and saves it with specified name and description. @cmview_user @param_post{name,string} @param_post{description,string} @param_post{path,string} HTTP or FTP path to IsoImage to download @param_post{disk_controller} """ user = User.get(caller_id) if not any([path.startswith('http://'), path.startswith('https://'), path.startswith('ftp://')]): path = 'http://' + path.strip() # size value is taken try: connection = urllib.urlopen(path) size = int(connection.info()["Content-Length"]) except IOError: log.exception('Cannot find image') raise CMException('image_not_found') except KeyError: log.exception(caller_id, 'Cannot calculate size') raise CMException('image_calculate_size') user.check_storage(size / (1024 * 1024)) image = IsoImage.create(user=user, description=description, name=name, disk_controller=disk_controller, disk_dev=1) try: image.save() except Exception, e: log.error(caller_id, "Unable to save image to DB: %s" % str(e)) raise CMException('image_create')
def destroy(vms): """ @parameter{vms} @response result """ results = [] for vm in vms: vm = VM.objects.get(pk=vm.id) log.debug(vm.user.id, "Killing VM id: %s, state: %s" % (vm.id, vm.state)) # Check for VM state if vm.state in (vm_states['closing'], vm_states['saving']): results.append({'status': 'vm_already_closing', 'data': ''}) continue if vm.state in (vm_states['erased'], vm_states['closed']): results.append({'status': 'vm_wrong_state', 'data': ''}) continue vm.save_vm = 0 try: vm.save() transaction.commit() vm.lv_destroy() except Exception, e: log.exception(vm.user.id, 'error destroying VM: %s' % str(e)) results.append({'status': 'vm_destroy', 'data': ''}) message.error(vm.user_id, 'vm_destroy', {'id': vm.id, 'name': vm.name}) continue results.append({'status': 'ok', 'data': ''})
def detach(self, vm): """ Requests Libvirt to detach from given VM this StorageImage. @parameter{vm,VM} VM from which StorageImage should be detached. @raises{storage_image_detach,CMException} cannot detach StorageImage """ domain = vm.lv_domain() disk_controller_name = disk_controllers_reversed[self.disk_controller] try: device_desc = """<disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='%(path)s'/> <target dev='%(dev)s' bus='%(bus)s'/> <alias name='%(bus)s-%(dev)s'/> </disk>""" % { 'path': self.path, 'dev': 'sd%s' % chr(self.disk_dev + 96), 'bus': disk_controller_name } domain.detachDevice(device_desc) except: log.exception(self.user.id, 'iso detach') raise CMException('iso_image_detach') self.vm = None
def add(user_id, data): try: global MESSAGES if user_id not in MESSAGES: MESSAGES[user_id] = [] MESSAGES[user_id].append(data) except Exception: log.exception(user_id, 'Add message')
def ctx_log(*arg, **kw): """ Decorator for functions requiring only \b guest's privilidges. src.cm.utils.decorators.genericlog() is called with parameters: - \c is_user=False - \c is_superuser=False @par Decorated function's declaration @code @guest_log[(log=<False|True>)] function (*arg, **kw) @endcode @par Decorated function's call @code function (*arg, **kw) @endcode """ def logwrapper(fun): @wraps(fun) def wrapper(request, *args, **kwargs): data = request.GET.dict() data['remote_ip'] = request.META.get('REMOTE_ADDR') gen_exception = False log_enabled = kw.get('log', False) name = '%s.%s' % (fun.__module__.replace('cm.views.', ''), fun.__name__) if log_enabled: log.debug(0, '=' * 100) log.debug(0, 'Function: %s' % name) log.debug(0, 'Args:\n%s' % json.dumps(data, indent=4)) with transaction.commit_manually(): try: # Execute function resp = fun(**data) transaction.commit() except CMException, e: transaction.rollback() log.exception(0, 'CMException %s' % e) resp = e.response except Exception, e: transaction.rollback() gen_exception = True resp = response('cm_error', str(e)) if resp['status'] != 'ok' and not log_enabled: log.debug(0, '=' * 100) log.debug(0, 'Function: %s' % name) log.debug(0, 'ARGS: %s' % str(data)) if resp['status'] != 'ok' or log_enabled: if gen_exception: log.exception(0, 'General exception') log.debug(0, 'Response: %s' % resp or 'None') return HttpResponse(json.dumps(resp, default=json_convert))
def remove(self): """ """ if not self.state in (vm_states['closing'], vm_states['saving']): self.set_state('closing') try: self.save(update_fields=['state']) except Exception, e: log.exception(self.user.id, 'closing img') return
def run(self): try: if self.url.startswith('/'): src_image = open(self.url, 'r') else: src_image = urllib2.urlopen(self.url) except Exception, e: log.exception(self.image.user.id, "Cannot open url %s: %s" % (self.url, str(e))) self.image.state = image_states['failed'] return
def execute(name, user_id, vm_id, **kwargs): """ Method executes command @prm{name} on the specified VM. User with id @prm{user_id} must be the owner of that VM. @parameter{name,string} name of the function to execute @parameter{user_id,long} id of the declared VM owner @parameter{vm_id,int} id of the VM on which command needs to be executed @parameter{kwargs,dict} keyword args for the called function @raises{ctx_timeout,CMException} @raises{ctx_execute_command,CMException} """ vm = VM.get(user_id, vm_id) try: cmd = Command.add_command(name, user_id, vm_id, **kwargs) transaction.commit() log.debug(user_id, "Command state %s for machine %s" % (cmd.state, vm_id)) dom = vm.lv_domain() dom.sendKey(0, 500, [113], 1, 0) retry = 3 retry_factor = 1.2 retry_time = 1 try: while retry > 0: log.debug(user_id, "Check if command %s is finished for machine %s" % (cmd.id, vm_id)) Command.objects.update() cmd = Command.objects.get(id=cmd.id) log.debug(user_id, "Checked command status: %s, %s, %s" % (cmd.state, command_states['finished'], bool(cmd.state == command_states['finished']))) if cmd.state == command_states['finished']: log.debug(user_id, "Response %s from machine %s" % (cmd.response, vm_id)) break elif cmd.state == command_states['failed']: raise CMException('ctx_' + name) retry -= 1 retry_time *= retry_factor sleep(retry_time) except: raise finally: cmd.delete() if retry == 0: log.debug(user_id, "Command %s for machine %s - TIMEOUT" % (name, vm_id)) raise CMException('ctx_timeout') return cmd.response or '' except CMException: raise except Exception: log.exception(user_id, 'Execute command') raise CMException('ctx_execute_command')
def save_image(self): """ Method saves VM to image with VM's name, description and parameters. """ self.set_state('saving') try: self.save(update_fields=['state']) transaction.commit() except Exception, e: log.exception(self.user.id, 'save img') return
def run(self): try: while self.running: time.sleep(settings.CLEANING_PERIOD) rrds = cm.utils.monia.RrdHandler().get_list() for vm in rrds: if time.time() - settings.TIME_TO_REMOVE > rrds[vm][1]: cm.utils.monia.RrdHandler({'name': str(vm), 'data': None}).remove() log.info(0, "CleanerThread stopped") except Exception, e: log.exception(0, 'CleanerThread: %s' % (e))
def register_head(vm): """ Head registration process: - Creates ssh keys and sets their values for WN; - Inserts VMs into the database; - Then starts VMThreads which create actual machines. Called when registering farms head. @parameter{vm,VM} instance of the VM to be registered as head """ log.debug(vm.user_id, "machine %d: registered as head" % vm.id) log.debug(vm.user_id, "creating lock for machine %d in farm %d" % (vm.id, vm.farm_id)) # skip if farm is already configured - reboot head if vm.is_head() == True and vm.farm.state == farm_states['running']: return vms = [] if vm.farm.state == farm_states['init_head']: vm.farm.state = farm_states['running'] vm.farm.save() log.info(vm.user_id, 'generating ssh keys on head %d' % vm.id) try: r = Command.execute('generate_key', vm.user_id, vm.id) r = json.loads(r) log.info(vm.user_id, 'generated key: %s for machine %d' % (r, vm.id)) for wn in vm.farm.vms.all(): wn.ssh_username = '******' wn.ssh_key = r wn.save() if not wn.is_head(): vms.append(wn) ssh_username = '******' ssh_key = r log.debug(vm.user_id, 'appended %d vms to farm [id:%d]' % (vm.farm.vms.count() - 1, vm.id)) # excluding head Command.add_command('add_ssh_key', vm.user_id, vm.id, user=ssh_username, ssh_key=ssh_key) Command.add_command('update_hosts', vm.user_id, vm.id, hosts_list=vm.farm.hosts(), user=ssh_username) Command.execute('set_hostname', vm.user_id, vm.id, hostname=vm.name.replace(vm.farm.name, 'farm')) except Exception: log.exception(vm.user_id, '') vm.farm.state = farm_states['unconfigured'] message.error(vm.id, 'farm_create', {'id': vm.farm.id, 'name': vm.farm.name}) log.info(vm.user_id, 'Head %d registered' % vm.id) shared = {"counter": len(vms), "lock": threading.Lock()} for vm in vms: thread = VMThread(vm, 'create', shared) thread.start() log.debug(vm.user_id, 'vm thread created [vm id:%d]' % vm.id)
def create(caller_id, name, description, image_id, head_template_id, worker_template_id, public_ip_id, iso_list, disk_list, vnc, groups, count): """ Method creates new Farm for caller: -#. Creates VMs described by \c machine dict. -#. Creates farm named by \c machine[name] consisting of those VMs. -#. Creates thread for this farm. @decoratedby{src.cm.utils.decorators.user_log} @parameter{machine,dict} \n fields: @dictkey{name,string} farm's name @dictkey{count,int} number of Worker Nodes @dictkey{template_id,int} Worker Node's template @dictkey{head_template_id,int} Head's template @dictkey{image_id,int} image for WNs and Head @dictkey{groups,list} optional @dictkey{node_id} optional on which node farm is to be created @dictkey{description,string} description of the farm @response{None} @raises{farm_create,CMException} """ user = User.get(caller_id) try: user.check_points() except: message.warn(caller_id, 'point_limit', {'used_points': user.used_points, 'point_limit': user.points}) farm = Farm.create(user=user, name=name, description=description) vms = VM.create(user, name=name, description=description, image_id=image_id, template_id=worker_template_id, head_template_id=head_template_id, public_ip_id=public_ip_id, iso_list=iso_list, disk_list=disk_list, vnc=vnc, groups=groups, farm=farm, count=count) farm.save() for vm in vms: vm.farm = farm if not vm.is_head(): # disable autosave vm.save_vm = 0 vm.save() try: farm.save() except Exception: log.exception(caller_id, 'farm_create') raise CMException('farm_create') VMThread(vms[0], 'create').start() return [vm.dict for vm in vms]
def wrapper(request, *args, **kwargs): log.debug(0, "request\n%s: " % json.dumps(request.GET.dict(), indent=4)) log_enabled = kw.get('log', False) name = '%s.%s' % (fun.__module__.replace('cm.views.', ''), fun.__name__) if log_enabled: log.debug(0, '=' * 100) log.debug(0, 'Function: %s' % name) resp = None try: resp = fun(request, *args, **kwargs) except CMException, e: log.exception(0, 'CMException %s' % e)
def detach_node(self): """ @raises{lease_detached,CMException} Network was not defined """ if self.vm_id == None: raise CMException('lease_detached') # Destroy network try: conn = libvirt.open(self.vm.node.conn_string) except Exception, e: log.exception(self.user_network.user_id, "Cannot connet to libvirt: ") raise CMException('lease_detach')
def delete(self): """ Ends VM's thread. -# Unassigns public IP. -# Deletes VM. """ try: VM.objects.update() vm = VM.objects.get(pk=self.vm.id) except Exception, e: log.exception(0, 'Cannot find vm %d: %s' % (self.vm.id, e)) return
def attach(self, vm): """ Attaches this StorageImage to specified VM. It searches for first free device and if there's any, tries to attach this to it via Libvirt. Further it updates DB information. @parameter{vm,VM} instance of the existing VM @raises{storage_image_attach,CMException} no free device found or cannot attach StorageImage """ domain = vm.lv_domain() log.debug(self.user.id, self.disk_controller) # Get all block devices and find first, unused sdX # attached_devices = [d.disk_dev for d in Session.query(StorageImage).filter(StorageImage.vm_id == vm.id).all()] attached_devices = [ d.disk_dev for d in StorageImage.objects.filter(vm_id__exact=vm.id) ] free_dev = None # find the first free numbers to be given to disk volume (sda is now integer) for i in range(2, 12): if not i in attached_devices: free_dev = i break if free_dev == None: raise CMException('storage_image_attach') try: device_desc = """<disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='%(path)s'/> <target dev='%(dev)s' bus='%(bus)s'/> <alias name='%(bus)s-%(dev)s'/> </disk>""" % { 'path': self.path, # disk_dev name will be in format sd+letter corresponding to the number (e.g: 2->sdb) 'dev': 'sd%s' % chr(free_dev + 98), 'bus': self.disk_controller_name } log.debug(self.user.id, device_desc) domain.attachDevice(device_desc) except: log.exception(self.user.id, 'storage attach') raise CMException('storage_image_attach') # Update database information self.disk_dev = free_dev self.vm = vm
def run(self): try: while self.running: time.sleep(settings.CLEANING_PERIOD) rrds = cm.utils.monia.RrdHandler().get_list() for vm in rrds: if time.time() - settings.TIME_TO_REMOVE > rrds[vm][1]: cm.utils.monia.RrdHandler({ 'name': str(vm), 'data': None }).remove() log.info(0, "CleanerThread stopped") except Exception, e: log.exception(0, 'CleanerThread: %s' % (e))
def download(caller_id, description, name, path, disk_controller, network_device, platform, video_device): """ Downloads image depending on the \c data parameter. @cmview_user @parameter{path,string} HTTP or FTP path to image to download @parameter{name,string} @parameter{description,string} @parameter{type,image_types} type of image, automatically set, type is in the URL requested @response{None} @raises{image_not_found,CMException} @raises{image_create,CMException} """ user = User.get(caller_id) if not any([path.startswith("http://"), path.startswith("https://"), path.startswith("ftp://")]): path = "http://" + path.strip() # size value is taken try: connection = urllib.urlopen(path) size = int(connection.info()["Content-Length"]) except IOError: log.exception(caller_id, "Cannot find image") raise CMException("image_not_found") except KeyError: log.exception(caller_id, "Cannot calculate size") raise CMException("image_calculate_size") user = User.get(caller_id) user.check_storage(size / (1024 * 1024)) image = SystemImage.create( name=name, description=description, user=user, platform=platform, disk_controller=disk_controller, network_device=network_device, video_device=video_device, ) try: image.save() except Exception, e: log.error(caller_id, "Unable to save image to DB: %s" % str(e)) raise CMException("image_create")
def convert_to_storage_image(caller_id, system_image_id): """ Changes type of the given Image. @cmview_user @param_post{system_image_id,int} ID of an Image to change type of """ image = SystemImage.get(caller_id, system_image_id) try: image.recast('cm.storageimage') image.save() except Exception: log.exception(caller_id, "convert_to_storage_image") raise CMException('image_change_type')
def convert_to_storage_image(caller_id, system_image_id): """ Changes type of the given Image. @cmview_user @param_post{system_image_id,int} ID of an Image to change type of """ image = SystemImage.get(caller_id, system_image_id) try: image.recast("cm.storageimage") image.save() except Exception: log.exception(caller_id, "convert_to_storage_image") raise CMException("image_change_type")
def attach(self, vm): """ Attaches this StorageImage to specified VM. It searches for first free device and if there's any, tries to attach this to it via Libvirt. Further it updates DB information. @parameter{vm,VM} instance of the existing VM @raises{storage_image_attach,CMException} no free device found or cannot attach StorageImage """ domain = vm.lv_domain() log.debug(self.user.id, self.disk_controller) # Get all block devices and find first, unused sdX # attached_devices = [d.disk_dev for d in Session.query(StorageImage).filter(StorageImage.vm_id == vm.id).all()] attached_devices = [d.disk_dev for d in StorageImage.objects.filter(vm_id__exact=vm.id)] free_dev = None # find the first free numbers to be given to disk volume (sda is now integer) for i in range(2, 12): if not i in attached_devices: free_dev = i break if free_dev == None: raise CMException('storage_image_attach') try: device_desc = """<disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='%(path)s'/> <target dev='%(dev)s' bus='%(bus)s'/> <alias name='%(bus)s-%(dev)s'/> </disk>""" % { 'path': self.path, # disk_dev name will be in format sd+letter corresponding to the number (e.g: 2->sdb) 'dev': 'sd%s' % chr(free_dev + 98), 'bus': self.disk_controller_name } log.debug(self.user.id, device_desc) domain.attachDevice(device_desc) except: log.exception(self.user.id, 'storage attach') raise CMException('storage_image_attach') # Update database information self.disk_dev = free_dev self.vm = vm
def wrapper(request, *args, **kwargs): log.debug( 0, "request\n%s: " % json.dumps(request.GET.dict(), indent=4)) log_enabled = kw.get('log', False) name = '%s.%s' % (fun.__module__.replace('cm.views.', ''), fun.__name__) if log_enabled: log.debug(0, '=' * 100) log.debug(0, 'Function: %s' % name) resp = None try: resp = fun(request, *args, **kwargs) except CMException, e: log.exception(0, 'CMException %s' % e)
def run(self): """ Runs proper action depending on \ self.action. """ with transaction.commit_manually(): try: if self.action == 'create': self.create() elif self.action == 'delete': self.delete() elif self.action == 'reset': self.reset() transaction.commit() except: log.exception(0, 'thread_exception') transaction.rollback()
def get_vm_info(self, vm): """ return information about steps, start & end time, and available stats time: 190us faster than regex """ if not check_stat_exists(vm): raise CMException('stat_not_exists') filepath = get_path(vm) try: ds_info = rrdtool.info(filepath) except Exception, e: log.exception(0, e) return 0
def get(user_id): """ Returns the User instance by passed id. @parameter{user_id,int} id of the requested User @returns{User} instance of requested User @raises{user_get,CMException} cannot get user """ try: user = User.objects.get(pk=user_id) except User.DoesNotExist: log.exception(user_id, 'Cannot get user') raise CMException('user_get') return user
def convert_to_storage_image(caller_id, system_image_id): """ Changes type of the given Image. @cmview_user @parameter{system_image_id,int} ID of an Image to change type of @response{None} """ image = SystemImage.get(caller_id, system_image_id) try: image.recast('cm.storageimage') image.save() except Exception: log.exception(caller_id, "convert_to_storage_image") raise CMException('image_change_type')
def create(caller_id, name, description, image_id, head_template_id, worker_template_id, public_ip_id, iso_list, disk_list, vnc, groups, count): """ Method creates new caller's Farm. @cmview_user @param_post{name,string} Farm's name @param_post{description,string} @param_post{image_id,int} image for WNs and Head @param_post{head_template_id,int} Head's template @param_post{worker_template_id,int} Worker Node's template @param_post{public_ip_id,int} Worker Node's template @param_post{iso_list,list} @param_post{disk_list,list} @param_post{vnc,list} @param_post{groups,list} @param_post{count,int} number of Worker Nodes @raises{farm_create,CMException} """ user = User.get(caller_id) try: user.check_points() except: message.warn(caller_id, 'point_limit', {'used_points': user.used_points, 'point_limit': user.points}) farm = Farm.create(user=user, name=name, description=description) vms = VM.create(user, name=name, description=description, image_id=image_id, template_id=worker_template_id, head_template_id=head_template_id, public_ip_id=public_ip_id, iso_list=iso_list, disk_list=disk_list, vnc=vnc, groups=groups, farm=farm, count=count) farm.save() for vm in vms: vm.farm = farm if not vm.is_head(): # disable autosave vm.save_vm = 0 vm.save() try: farm.save() except Exception: log.exception(caller_id, 'farm_create') raise CMException('farm_create') VMThread(vms[0], 'create').start() return [vm.dict for vm in vms]
def attach(self, vm): """ Attaches this StorageImage to specified VM. It searches for first free device and if there's any, tries to attach this to it via Libvirt. Further it updates DB information. @parameter{vm,VM} instance of the existing VM @raises{storage_image_attach,CMException} no free device found or cannot attach StorageImage """ domain = vm.lv_domain() log.debug(self.user.id, self.disk_controller) disk_controller_name = disk_controllers_reversed[self.disk_controller] # Get all block devices and find first, unused sdX # attached_devices = [d.disk_dev for d in Session.query(StorageImage).filter(StorageImage.vm_id == vm.id).all()] attached_devices = [ d.disk_dev for d in IsoImage.objects.filter(vm_id__exact=vm.id) ] free_dev = 'sdz' if free_dev == attached_devices: raise CMException('iso_image_attach') try: device_desc = """<disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='%(path)s'/> <target dev='%(dev)s' bus='%(bus)s'/> <alias name='%(bus)s-%(dev)s'/> </disk>""" % { 'path': self.path, 'dev': 'sd%s' % free_dev, 'bus': disk_controller_name } log.debug(self.user.id, device_desc) domain.attachDevice(device_desc) except: log.exception(self.user.id, 'iso attach') raise CMException('iso_image_attach') # Update database information self.disk_dev = free_dev self.vm = vm
def set_private(caller_id, system_image_id): """ Removes SystemImage from public pool. @cmview_admin_cm @param_post{system_image_id,int} """ image = SystemImage.admin_get(system_image_id) image.access = image_access['private'] # delete the existing group association try: image.save() image.systemimagegroup_set.all().delete() except: log.exception(caller_id, 'image_set_private') raise CMException('image_set_private')
def unassign(caller_id, lease_id): """ Detaches specified PublicIP from owners VM. Unlinks PublicLease instance from its Lease instance. @cmview_admin_cm @param_post{lease_id,int} id of the VM's lease from which IP should be detached. @raises{lease_not_found,CMException} @raises{public_lease_unassign,CMException} """ try: lease = Lease.objects.get(id=lease_id) except Exception, e: log.exception(caller_id, str(e)) raise CMException("lease_not_found")
def erase(caller_id, farm_ids): """ Cleanes up after failed Farm. Only admin may erase Farm so that he previously may perform some analytics. @cmview_admin_cm @param_post{farm_ids,list(int)} ids of the Farms to erase """ for fid in farm_ids: farm = Farm.admin_get(fid) for vm in farm.vms.all(): VM.erase(vm) farm.state = farm_states['closed'] try: farm.save() except Exception: log.exception('Cannot commit changes.')
def unassign(caller_id, lease_id): """ Method detaches PublicIP from caller's VM. @cmview_user @param_post{lease_id,int} id of the VM's Lease from which PublicIP should be detached. @raises{lease_not_found,CMException} @raises{public_lease_unassign,CMException} """ user = User.get(caller_id) try: lease = Lease.objects.get(id=lease_id) except Exception, e: log.exception(caller_id, str(e)) raise CMException("lease_not_found")