예제 #1
0
 def lock_keys(self):
     if IVirtualCompute.providedBy(self.context):
         return (canonical_path(self.context),
                 canonical_path(self.context.__parent__),
                 canonical_path(self.context.__parent__.__parent__)) + self._additional_keys
     else:
         return (canonical_path(self.context),) + self._additional_keys
예제 #2
0
    def execute(self, args):
        for machine in db.get_root()['oms_root']['machines']:
            if not ICompute.providedBy(machine) or IVirtualCompute.providedBy(
                    machine):
                continue

            InstallSaltAction(machine).execute(DetachedProtocol(), object())
예제 #3
0
 def _add(self, item):
     machines = db.get_root()['oms_root']['machines']
     # TODO: fix adding computes to vms instead of hangar
     if not machines.hangar['vms']:
         pass
     return (machines.hangar
             if IVirtualCompute.providedBy(item) else machines).add(item)
예제 #4
0
        def get_vms_if_not_empty():
            vms = follow_symlinks(self.context['vms']) or []

            for vm in vms:
                if IVirtualCompute.providedBy(vm):
                    return vms

            log.msg('%s: no VMs' % (self.context.hostname), system='metrics', logLevel=logging.DEBUG)
예제 #5
0
    def _execute(self, cmd, args):
        if IVirtualCompute.providedBy(self.context):
            cmd.write('Only applicable to HNs\n')
            return

        log.msg('Installing salt-minion...', system='install-salt')
        yield IInstallPkg(self.context).run('salt-minion')
        log.msg('Installation of salt-minion successful!', system='install-salt')
예제 #6
0
 def lock_keys(self):
     if IVirtualCompute.providedBy(self.context):
         return (canonical_path(
             self.context), canonical_path(self.context.__parent__),
                 canonical_path(self.context.__parent__.__parent__)
                 ) + self._additional_keys
     else:
         return (canonical_path(self.context), ) + self._additional_keys
예제 #7
0
        def get_vms_if_not_empty():
            vms = follow_symlinks(self.context['vms']) or []

            for vm in vms:
                if IVirtualCompute.providedBy(vm):
                    return vms

            log.msg('%s: no VMs' % (self.context.hostname), system='metrics', logLevel=logging.DEBUG)
예제 #8
0
 def get_computes(self, args):
     computes = db.get_root()['oms_root']['computes']
     user_vms = []
     for c in map(follow_symlinks, computes.listcontent()):
         if not IVirtualCompute.providedBy(c):
             continue
         if c.__owner__ == args.u:
             user_vms.append(c)
     return user_vms
예제 #9
0
 def allowed_classes_gen(item):
     from opennode.knot.model.compute import ICompute, IVirtualCompute
     from opennode.knot.model.machines import Machines
     from opennode.knot.model.virtualizationcontainer import IVirtualizationContainer
     yield isinstance(item, Machines)
     yield isinstance(item, Templates)
     yield IVirtualizationContainer.providedBy(item)
     yield ICompute.providedBy(item)
     yield IVirtualCompute.providedBy(item)
예제 #10
0
 def allowed_classes_gen(item):
     from opennode.knot.model.compute import ICompute, IVirtualCompute
     from opennode.knot.model.machines import Machines
     from opennode.knot.model.virtualizationcontainer import IVirtualizationContainer
     yield isinstance(item, Machines)
     yield isinstance(item, Templates)
     yield IVirtualizationContainer.providedBy(item)
     yield ICompute.providedBy(item)
     yield IVirtualCompute.providedBy(item)
예제 #11
0
 def get_computes(self, username):
     computes = db.get_root()['oms_root']['computes']
     user_computes = []
     for compute in map(follow_symlinks, computes.listcontent()):
         if not IVirtualCompute.providedBy(compute):
             continue
         if compute.__owner__ == username and IDeployed.providedBy(compute):
             user_computes.append(compute)
     return user_computes
예제 #12
0
 def get_computes(self, args):
     computes = db.get_root()['oms_root']['computes']
     user_vms = []
     for c in map(follow_symlinks, computes.listcontent()):
         if not IVirtualCompute.providedBy(c):
             continue
         if c.__owner__ == args.u:
             user_vms.append(c)
     return user_vms
예제 #13
0
    def _execute(self, cmd, args):
        if IVirtualCompute.providedBy(self.context):
            cmd.write('Only applicable to HNs\n')
            return

        log.msg('Installing salt-minion...', system='install-salt')
        yield IInstallPkg(self.context).run('salt-minion')
        log.msg('Installation of salt-minion successful!',
                system='install-salt')
예제 #14
0
    def _execute(self, cmd, args):
        self._full = getattr(args, 'full', False)

        log.msg('Executing SyncAction on %s (%s) (Full: %s)' %
                (self.context, canonical_path(self.context), self._full),
                system='sync-action')

        if any_stack_installed(self.context):
            try:
                yield self.sync_agent_version(self._full)
            except OperationRemoteError:
                log.err(system='sync-action')

            yield self.sync_hw(self._full)

            try:
                yield self.ensure_vms(self._full)
            except Exception:
                log.err(system='sync-action')

            if self._full:
                try:
                    yield SyncTemplatesAction(self.context)._execute(
                        DetachedProtocol(), object())
                except Exception:
                    log.err(system='sync-action')
        else:
            log.msg('No stacks installed on %s: %s' %
                    (self.context, self.context.features))

        try:
            default = yield self.default_console()
            yield self.sync_consoles()

            if IVirtualCompute.providedBy(self.context):
                yield self._sync_virtual()

            yield self._create_default_console(default)
        except Exception:
            log.err(system='sync-action')

        @db.transact
        def set_additional_keys():
            vms = follow_symlinks(self.context['vms'])
            if vms:
                self._additional_keys = (canonical_path(vms), )

        yield set_additional_keys()

        dl = yield self.reacquire()
        if dl is not None:
            return

        yield self.sync_vms()
예제 #15
0
    def _execute(self, cmd, args):
        self._full = getattr(args, 'full', False)

        log.msg('Executing SyncAction on %s (%s) (Full: %s)' % (self.context,
                                                                canonical_path(self.context),
                                                                self._full), system='sync-action')

        if any_stack_installed(self.context):
            try:
                yield self.sync_agent_version(self._full)
            except OperationRemoteError:
                log.err(system='sync-action')

            yield self.sync_hw(self._full)

            try:
                yield self.ensure_vms(self._full)
            except Exception:
                log.err(system='sync-action')

            if self._full:
                try:
                    yield SyncTemplatesAction(self.context)._execute(DetachedProtocol(), object())
                except Exception:
                    log.err(system='sync-action')
        else:
            log.msg('No stacks installed on %s: %s' % (self.context, self.context.features))

        try:
            default = yield self.default_console()
            yield self.sync_consoles()

            if IVirtualCompute.providedBy(self.context):
                yield self._sync_virtual()

            yield self._create_default_console(default)
        except Exception:
            log.err(system='sync-action')

        @db.transact
        def set_additional_keys():
            vms = follow_symlinks(self.context['vms'])
            if vms:
                self._additional_keys = (canonical_path(vms),)

        yield set_additional_keys()

        dl = yield self.reacquire()
        if dl is not None:
            return

        yield self.sync_vms()
예제 #16
0
    def put_filter_attributes(self, request, data):
        data = super(ComputeView, self).put_filter_attributes(request, data)

        if 'template' in data and not IVirtualCompute.providedBy(self.context):
            del data['template']

        def filter_readonly_properties(pair):
            k, v = pair
            return k not in ('ipv4_address', 'ipv6_address', 'nicknames', 'effective_state', 'templates',
                             'license_activated', 'owner')

        data = dict(filter(filter_readonly_properties, data.iteritems()))
        return data
예제 #17
0
    def _sync_hw(self, info, disk_space, disk_usage, routes, uptime):
        with SuppressEvents(self.context):
            self.context.uptime = float(uptime)

            if any((not info, 'cpuModel' not in info, 'kernelVersion'
                    not in info)):
                log.msg(
                    'Nothing to update: info does not include required data',
                    system='sync-hw')
                return

            if IVirtualCompute.providedBy(self.context):
                self.context.cpu_info = self.context.__parent__.__parent__.cpu_info
            else:
                self.context.cpu_info = unicode(info['cpuModel'])

            self.context.architecture = (unicode(info['platform']), u'linux',
                                         self.distro(info))
            self.context.kernel = unicode(info['kernelVersion'])
            self.context.memory = int(info['systemMemory'])
            self.context.num_cores = int(info['numCpus'])
            self.context.os_release = unicode(info['os'])
            self.context.swap_size = int(info['systemSwap'])
            self.context.diskspace = disk_space
            self.context.diskspace_usage = disk_usage
            self.context.template = u'Hardware node'

            # XXX TODO: handle removal of routes
            for r in routes:
                destination = netaddr.IPNetwork(
                    '%s/%s' % (r['destination'], r['netmask']))
                route_name = str(destination.cidr).replace('/', '_')

                if self.context.routes[route_name]:
                    continue

                gateway = netaddr.IPAddress(r['router'])

                route = NetworkRoute()
                route.destination = str(destination.cidr)
                route.gateway = str(gateway)
                route.flags = r['flags']
                route.metrics = int(r['metrics'])
                route.__name__ = route_name

                interface = self.context.interfaces[r['interface']]
                if interface:
                    route.add(Symlink('interface', interface))

                self.context.routes.add(route)
예제 #18
0
    def get_computes(self, username):
        computes = db.get_root()['oms_root']['computes']
        user_computes = []
        for compute in map(follow_symlinks, computes.listcontent()):
            if not IVirtualCompute.providedBy(compute):
                continue

            if not compute.license_activated:
                continue

            if compute.__owner__ == username and IDeployed.providedBy(compute):
                user_computes.append(compute)

        return user_computes
예제 #19
0
    def put_filter_attributes(self, request, data):
        data = super(ComputeView, self).put_filter_attributes(request, data)

        if 'template' in data and not IVirtualCompute.providedBy(self.context):
            del data['template']

        def filter_readonly_properties(pair):
            k, v = pair
            return k not in ('ipv4_address', 'ipv6_address', 'nicknames',
                             'effective_state', 'templates',
                             'license_activated', 'owner')

        data = dict(filter(filter_readonly_properties, data.iteritems()))
        return data
예제 #20
0
    def _sync_hw(self, info, disk_space, disk_usage, routes, uptime):
        with SuppressEvents(self.context):
            self.context.uptime = float(uptime)

            if any((not info, 'cpuModel' not in info, 'kernelVersion' not in info)):
                log.msg('Nothing to update: info does not include required data', system='sync-hw')
                return

            if IVirtualCompute.providedBy(self.context):
                self.context.cpu_info = self.context.__parent__.__parent__.cpu_info
            else:
                self.context.cpu_info = unicode(info['cpuModel'])

            self.context.architecture = (unicode(info['platform']), u'linux', self.distro(info))
            self.context.kernel = unicode(info['kernelVersion'])
            self.context.memory = int(info['systemMemory'])
            self.context.num_cores = int(info['numCpus'])
            self.context.os_release = unicode(info['os'])
            self.context.swap_size = int(info['systemSwap'])
            self.context.diskspace = disk_space
            self.context.diskspace_usage = disk_usage
            self.context.template = u'Hardware node'

            # XXX TODO: handle removal of routes
            for r in routes:
                destination = netaddr.IPNetwork('%s/%s' % (r['destination'], r['netmask']))
                route_name = str(destination.cidr).replace('/', '_')

                if self.context.routes[route_name]:
                    continue

                gateway = netaddr.IPAddress(r['router'])

                route = NetworkRoute()
                route.destination = str(destination.cidr)
                route.gateway = str(gateway)
                route.flags = r['flags']
                route.metrics = int(r['metrics'])
                route.__name__ = route_name

                interface = self.context.interfaces[r['interface']]
                if interface:
                    route.add(Symlink('interface', interface))

                self.context.routes.add(route)
예제 #21
0
    def _execute(self, cmd, args):
        # XXX for some strange reason args is object()
        if type(args) == argparse.Namespace:
            self._full = args.full
        log.msg('Executing SyncAction on %s (%s)' % (self.context, canonical_path(self.context)),
                 system='sync-action')

        if any_stack_installed(self.context):
            yield self.sync_agent_version(self._full)
            yield self.sync_hw(self._full)
            yield self.ensure_vms(self._full)
            if self._full:
                yield SyncTemplatesAction(self.context)._execute(DetachedProtocol(), object())
        else:
            log.msg('No stacks installed on %s: %s' % (self.context, self.context.features))

        default = yield self.default_console()
        yield self.sync_consoles()

        if IVirtualCompute.providedBy(self.context):
            yield self._sync_virtual()

        yield self._create_default_console(default)

        @db.transact
        def set_additional_keys():
            vms = follow_symlinks(self.context['vms'])
            if vms:
                self._additional_keys = (canonical_path(vms),)

        yield set_additional_keys()
        dl = yield self.reacquire()
        if dl is not None:
            return

        yield self.sync_vms()
예제 #22
0
 def subject(self, args):
     return tuple(machine
                  for machine in db.get_root()['oms_root']['machines']
                  if ICompute.providedBy(machine)
                  and not IVirtualCompute.providedBy(machine))
예제 #23
0
    def execute(self, args):
        for machine in db.get_root()['oms_root']['machines']:
            if not ICompute.providedBy(machine) or IVirtualCompute.providedBy(machine):
                continue

            InstallSaltAction(machine).execute(DetachedProtocol(), object())
예제 #24
0
 def subject(self, args):
     return tuple(machine for machine in db.get_root()['oms_root']['machines']
                  if ICompute.providedBy(machine) and not IVirtualCompute.providedBy(machine))
예제 #25
0
    def _execute(self, cmd, args):

        @db.ro_transact
        def get_destination():
            return (args.__parent__ if IVirtualizationContainer.providedBy(args)
                    else cmd.traverse(args.dest_path))

        @db.ro_transact
        def get_hostname(target):
            return target.hostname

        name = yield db.get(self.context, '__name__')
        source_vms = yield db.get(self.context, '__parent__')

        destination = yield get_destination()
        assert ICompute.providedBy(destination), 'Destination must be a Compute'
        assert not IVirtualCompute.providedBy(destination), 'Cannot migrate to a VM'
        destination_hostname = yield get_hostname(destination)
        destination_vms = follow_symlinks(destination['vms'])
        assert (yield db.get(destination_vms, 'backend')) == (yield db.get(source_vms, 'backend')),\
                'Destination backend is different from source'

        @db.transact
        def set_additional_keys():
            self._additional_keys = [canonical_path(destination_vms), canonical_path(destination)]
        yield set_additional_keys()

        yield self.reacquire_until_clear()

        log.msg('Initiating migration for %s to %s' % (name, destination_hostname), system='migrate')

        try:
            if not (yield self._check_vm_pre(name, destination_hostname, destination_vms)):
                return

            source_submitter = IVirtualizationContainerSubmitter(source_vms)
            yield source_submitter.submit(IMigrateVM, name, destination_hostname, (not args.offline), False)
            log.msg('Migration done. Checking... %s' % destination_vms, system='migrate')

            if (yield self._check_vm_post(cmd, name, destination_hostname, destination_vms)):
                log.msg('Migration finished successfully!', system='migrate')

                @db.transact
                def mv_and_inherit():
                    machines = db.get_root()['oms_root']['machines']
                    computes = db.get_root()['oms_root']['computes']
                    try:
                        destination_compute = machines[destination.__name__]
                        vm_compute = follow_symlinks(computes[self.context.__name__])
                        vm_compute.failure = destination_compute.failure
                        vm_compute.suspicious = destination_compute.suspicious
                        dvms = follow_symlinks(destination_compute['vms'])
                        dvms.add(vm_compute)
                        log.msg('Model moved.', system='migrate')
                    except IndexError:
                        log.msg('Model NOT moved: destination compute or vms do not exist', system='migrate')
                    except KeyError:
                        log.msg('Model NOT moved: already moved by sync?', system='migrate')
                yield mv_and_inherit()
        except OperationRemoteError as e:
            self._action_log(cmd, 'Failed migration of %s to %s: remote error %s' % (
                name, destination_hostname, '\n%s' % e.remote_tb if e.remote_tb else ''),
                logLevel=ERROR, system='migrate')
예제 #26
0
    def _execute(self, cmd, args):
        @db.ro_transact
        def get_destination():
            return (args.__parent__
                    if IVirtualizationContainer.providedBy(args) else
                    cmd.traverse(args.dest_path))

        @db.ro_transact
        def get_hostname(target):
            return target.hostname

        name = yield db.get(self.context, '__name__')
        source_vms = yield db.get(self.context, '__parent__')

        destination = yield get_destination()
        assert ICompute.providedBy(
            destination), 'Destination must be a Compute'
        assert not IVirtualCompute.providedBy(
            destination), 'Cannot migrate to a VM'
        destination_hostname = yield get_hostname(destination)
        destination_vms = follow_symlinks(destination['vms'])
        assert (yield db.get(destination_vms, 'backend')) == (yield db.get(source_vms, 'backend')),\
                'Destination backend is different from source'

        @db.transact
        def set_additional_keys():
            self._additional_keys = [
                canonical_path(destination_vms),
                canonical_path(destination)
            ]

        yield set_additional_keys()

        yield self.reacquire_until_clear()

        log.msg('Initiating migration for %s to %s' %
                (name, destination_hostname),
                system='migrate')

        try:
            if not (yield self._check_vm_pre(cmd, name, destination_hostname,
                                             destination_vms)):
                return

            source_submitter = IVirtualizationContainerSubmitter(source_vms)
            yield source_submitter.submit(IMigrateVM, name,
                                          destination_hostname,
                                          (not args.offline), False)
            log.msg('Migration done. Checking... %s' % destination_vms,
                    system='migrate')

            if (yield self._check_vm_post(cmd, name, destination_hostname,
                                          destination_vms)):
                log.msg('Migration finished successfully!', system='migrate')

                @db.transact
                def mv_and_inherit():
                    machines = db.get_root()['oms_root']['machines']
                    computes = db.get_root()['oms_root']['computes']
                    try:
                        destination_compute = machines[destination.__name__]
                        vm_compute = follow_symlinks(
                            computes[self.context.__name__])
                        vm_compute.failure = destination_compute.failure
                        vm_compute.suspicious = destination_compute.suspicious
                        dvms = follow_symlinks(destination_compute['vms'])
                        dvms.add(vm_compute)
                        log.msg('Model moved.', system='migrate')
                    except IndexError:
                        log.msg(
                            'Model NOT moved: destination compute or vms do not exist',
                            system='migrate')
                    except KeyError:
                        log.msg('Model NOT moved: already moved by sync?',
                                system='migrate')

                yield mv_and_inherit()
        except OperationRemoteError as e:
            self._action_log(cmd,
                             'Failed migration of %s to %s: remote error %s' %
                             (name, destination_hostname,
                              '\n%s' % e.remote_tb if e.remote_tb else ''),
                             logLevel=ERROR,
                             system='migrate')
예제 #27
0
    def _sync_vms_transact(self, remote_vms):
        local_vms = [i for i in self.context.listcontent() if IVirtualCompute.providedBy(i)]

        remote_uuids = set(i['uuid'] for i in remote_vms)
        local_uuids = set(i.__name__ for i in local_vms)

        root = db.get_root()['oms_root']
        machines = root['machines']

        for vm_uuid in remote_uuids.difference(local_uuids):
            remote_vm = [rvm for rvm in remote_vms if rvm['uuid'] == vm_uuid][0]

            existing_machine = follow_symlinks(machines['by-name'][remote_vm['name']])
            if existing_machine:
                # XXX: this VM is a nested VM, for now let's hack it this way
                new_compute = Symlink(existing_machine.__name__, existing_machine)
                self.context._add(new_compute)
            else:
                log.msg('Adding virtual compute %s...' % vm_uuid,
                        system='v12n-sync', logLevel=logging.WARNING)
                new_compute = Compute(unicode(remote_vm['name']), unicode(remote_vm['state']))
                new_compute.__name__ = vm_uuid
                new_compute.template = unicode(remote_vm['template'])
                alsoProvides(new_compute, IVirtualCompute)
                alsoProvides(new_compute, IDeployed)

                # for now let's force new synced computes to not have salt installed
                # XXX: not sure if removing a parent interface will remove the child also
                noLongerProvides(new_compute, IManageable)
                self.context.add(new_compute)

        for vm_uuid in remote_uuids.intersection(local_uuids):
            noLongerProvides(self.context[vm_uuid], IUndeployed)
            alsoProvides(self.context[vm_uuid], IDeployed)

        for vm_uuid in local_uuids.difference(remote_uuids):
            if IDeploying.providedBy(self.context[vm_uuid]):
                log.msg("Don't delete undeployed VM while in IDeploying state", system='v12n')
                continue

            noLongerProvides(self.context[vm_uuid], IDeployed)
            alsoProvides(self.context[vm_uuid], IUndeployed)
            self.context[vm_uuid].state = u'inactive'

            if get_config().getboolean('sync', 'delete_on_sync'):
                log.msg("Deleting compute %s" % vm_uuid, system='v12n-sync', logLevel=logging.WARNING)
                compute = self.context[vm_uuid]
                del self.context[vm_uuid]
                handle(compute, ModelDeletedEvent(self.context))

        # TODO: eliminate cross-import between compute and v12ncontainer
        from opennode.knot.backend.compute import ICompute
        from opennode.knot.backend.syncaction import SyncAction

        # sync each vm
        for compute in self.context.listcontent():
            if not IVirtualCompute.providedBy(compute):
                continue

            log.msg('Attempting to sync %s' % compute, system='sync-vms')
            if not ICompute.providedBy(compute.__parent__.__parent__):
                log.msg('Inconsistent data: %s, Compute is expected. Attempting to fix %s'
                        % (compute.__parent__.__parent__, compute),
                        system='sync-vms', logLevel=logging.WARNING)

                compute.__parent__ = self.context

                log.msg('Fixing %s %s' % (compute,
                                          'successful!'
                                          if ICompute.providedBy(compute.__parent__.__parent__)
                                          else 'failed!'),
                        system='sync-vms', logLevel=logging.WARNING)

                if not ICompute.providedBy(compute.__parent__.__parent__):
                    return

            action = SyncAction(compute)

            matching = [rvm for rvm in remote_vms if rvm['uuid'] == compute.__name__]

            if not matching:
                continue

            remote_vm = matching[0]

            # todo delegate all this into the action itself
            default_console = action._default_console()
            action._sync_consoles()
            action.sync_owner_transact(remote_vm)
            action.sync_vm(remote_vm)
            action.create_default_console(default_console)