Beispiel #1
0
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')
Beispiel #2
0
    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': ''})
Beispiel #3
0
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')
Beispiel #4
0
    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
Beispiel #5
0
        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))
Beispiel #6
0
 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
Beispiel #7
0
    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)
Beispiel #8
0
 def get(self):
     try:
         t = self.pop(0)
         self.append(t)
         return t
     except Exception, e:
         log.exception(0, e)
Beispiel #9
0
    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'])
Beispiel #10
0
 def get(self):
     try:
         t = self.pop(0)
         self.append(t)
         return t
     except Exception, e:
         log.exception(0, e)
Beispiel #11
0
    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)
Beispiel #12
0
    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)
Beispiel #13
0
    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)
Beispiel #14
0
    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')
Beispiel #15
0
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')
Beispiel #16
0
    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': ''})
Beispiel #17
0
    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
Beispiel #18
0
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')
Beispiel #19
0
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))
Beispiel #20
0
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))
Beispiel #21
0
 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
Beispiel #22
0
 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
Beispiel #23
0
 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
Beispiel #24
0
    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')
Beispiel #25
0
 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
Beispiel #26
0
 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
Beispiel #27
0
 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))
Beispiel #28
0
    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)
Beispiel #29
0
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]
Beispiel #30
0
        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)
Beispiel #31
0
    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')
Beispiel #32
0
    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')
Beispiel #33
0
    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
Beispiel #34
0
    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
Beispiel #35
0
    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
Beispiel #36
0
 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))
Beispiel #37
0
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")
Beispiel #38
0
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')
Beispiel #39
0
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")
Beispiel #40
0
    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
Beispiel #41
0
        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)
Beispiel #42
0
 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()
Beispiel #43
0
    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
Beispiel #44
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
Beispiel #45
0
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')
Beispiel #46
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
Beispiel #47
0
 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()
Beispiel #48
0
    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
Beispiel #49
0
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]
Beispiel #50
0
    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
Beispiel #51
0
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')
Beispiel #52
0
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')
Beispiel #53
0
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")
Beispiel #54
0
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.')
Beispiel #55
0
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")