コード例 #1
0
ファイル: provider.py プロジェクト: openstack-infra/nodepool
    def unmanagedQuotaUsed(self):
        '''
        Sums up the quota used by servers unmanaged by nodepool.

        :return: Calculated quota in use by unmanaged servers
        '''
        flavors = self.listFlavorsById()
        used_quota = QuotaInformation()

        node_ids = set([n.id for n in self._zk.nodeIterator()])

        for server in self.listNodes():
            meta = server.get('metadata', {})

            nodepool_provider_name = meta.get('nodepool_provider_name')
            if (nodepool_provider_name and
                nodepool_provider_name == self.provider.name):
                # This provider (regardless of the launcher) owns this
                # server so it must not be accounted for unmanaged
                # quota; unless it has leaked.
                nodepool_node_id = meta.get('nodepool_node_id')
                # FIXME(tobiash): Add a test case for this
                if nodepool_node_id and nodepool_node_id in node_ids:
                    # It has not leaked.
                    continue

            flavor = flavors.get(server.flavor.id)
            used_quota.add(QuotaInformation.construct_from_flavor(flavor))

        return used_quota
コード例 #2
0
ファイル: provider.py プロジェクト: progmaticlab/nodepool
    def unmanagedQuotaUsed(self):
        '''
        Sums up the quota used by servers unmanaged by nodepool.

        :return: Calculated quota in use by unmanaged servers
        '''
        flavors = self.listFlavorsById()
        used_quota = QuotaInformation()

        node_ids = set([n.id for n in self._zk.nodeIterator()])

        for server in self.listNodes():
            meta = server.get('metadata', {})

            nodepool_provider_name = meta.get('nodepool_provider_name')
            if (nodepool_provider_name
                    and nodepool_provider_name == self.provider.name):
                # This provider (regardless of the launcher) owns this
                # server so it must not be accounted for unmanaged
                # quota; unless it has leaked.
                nodepool_node_id = meta.get('nodepool_node_id')
                # FIXME(tobiash): Add a test case for this
                if nodepool_node_id and nodepool_node_id in node_ids:
                    # It has not leaked.
                    continue

            flavor = flavors.get(server.flavor.id)
            used_quota.add(QuotaInformation.construct_from_flavor(flavor))

        return used_quota
コード例 #3
0
    def estimatedNodepoolQuotaUsed(self, zk, pool=None):
        '''
        Sums up the quota used (or planned) currently by nodepool. If pool is
        given it is filtered by the pool.

        :param zk: the object to access zookeeper
        :param pool: If given, filtered by the pool.
        :return: Calculated quota in use by nodepool
        '''
        used_quota = QuotaInformation()

        for node in zk.nodeIterator():
            if node.provider == self.provider.name:
                if pool and not node.pool == pool.name:
                    continue
                provider_pool = self.provider.pools.get(node.pool)
                if not provider_pool:
                    self.log.warning("Cannot find provider pool for node %s" %
                                     node)
                    # This node is in a funny state we log it for debugging
                    # but move on and don't account it as we can't properly
                    # calculate its cost without pool info.
                    continue
                node_resources = self.quotaNeededByNodeType(
                    node.type[0], provider_pool)
                used_quota.add(node_resources)
        return used_quota
コード例 #4
0
ファイル: provider.py プロジェクト: openstack-infra/nodepool
    def quotaNeededByNodeType(self, ntype, pool):
        provider_label = pool.labels[ntype]

        flavor = self.findFlavor(provider_label.flavor_name,
                                 provider_label.min_ram)

        return QuotaInformation.construct_from_flavor(flavor)
コード例 #5
0
    def quotaNeededByNodeType(self, ntype, pool):
        provider_label = pool.labels[ntype]

        flavor = self.findFlavor(provider_label.flavor_name,
                                 provider_label.min_ram)

        return QuotaInformation.construct_from_flavor(flavor)
コード例 #6
0
ファイル: handler.py プロジェクト: openstack-infra/nodepool
    def hasRemainingQuota(self, ntype):
        '''
        Apply max_servers check, ignoring other quotas.

        :returns: True if we have room, False otherwise.
        '''
        needed_quota = QuotaInformation(cores=1, instances=1, ram=1, default=1)
        n_running = self.manager.countNodes(self.pool.name)
        pool_quota = QuotaInformation(
            cores=math.inf,
            instances=self.pool.max_servers - n_running,
            ram=math.inf,
            default=math.inf)
        pool_quota.subtract(needed_quota)
        self.log.debug("hasRemainingQuota({},{}) = {}".format(
            self.pool, ntype, pool_quota))
        return pool_quota.non_negative()
コード例 #7
0
ファイル: handler.py プロジェクト: leki75/nodepool
    def hasRemainingQuota(self, ntype):
        needed_quota = self.manager.quotaNeededByNodeType(ntype, self.pool)

        # Calculate remaining quota which is calculated as:
        # quota = <total nodepool quota> - <used quota> - <quota for node>
        cloud_quota = self.manager.estimatedNodepoolQuota()
        cloud_quota.subtract(self.manager.estimatedNodepoolQuotaUsed(self.zk))
        cloud_quota.subtract(needed_quota)
        self.log.debug("Predicted remaining tenant quota: %s", cloud_quota)

        if not cloud_quota.non_negative():
            return False

        # Now calculate pool specific quota. Values indicating no quota default
        # to math.inf representing infinity that can be calculated with.
        pool_quota = QuotaInformation(cores=self.pool.max_cores,
                                      instances=self.pool.max_servers,
                                      ram=self.pool.max_ram,
                                      default=math.inf)
        pool_quota.subtract(
            self.manager.estimatedNodepoolQuotaUsed(self.zk, self.pool))
        pool_quota.subtract(needed_quota)
        self.log.debug("Predicted remaining pool quota: %s", pool_quota)

        return pool_quota.non_negative()
コード例 #8
0
ファイル: handler.py プロジェクト: openstack-infra/nodepool
    def hasProviderQuota(self, node_types):
        '''
        Apply max_servers check to a whole request

        :returns: True if we have room, False otherwise.
        '''
        needed_quota = QuotaInformation(
            cores=1,
            instances=len(node_types),
            ram=1,
            default=1)
        pool_quota = QuotaInformation(
            cores=math.inf,
            instances=self.pool.max_servers,
            ram=math.inf,
            default=math.inf)
        pool_quota.subtract(needed_quota)
        self.log.debug("hasProviderQuota({},{}) = {}".format(
            self.pool, node_types, pool_quota))
        return pool_quota.non_negative()
コード例 #9
0
ファイル: handler.py プロジェクト: openstack-infra/nodepool
    def hasRemainingQuota(self, ntype):
        needed_quota = self.manager.quotaNeededByNodeType(ntype, self.pool)

        if not self.pool.ignore_provider_quota:
            # Calculate remaining quota which is calculated as:
            # quota = <total nodepool quota> - <used quota> - <quota for node>
            cloud_quota = self.manager.estimatedNodepoolQuota()
            cloud_quota.subtract(
                self.manager.estimatedNodepoolQuotaUsed())
            cloud_quota.subtract(needed_quota)
            self.log.debug("Predicted remaining provider quota: %s",
                           cloud_quota)

            if not cloud_quota.non_negative():
                return False

        # Now calculate pool specific quota. Values indicating no quota default
        # to math.inf representing infinity that can be calculated with.
        pool_quota = QuotaInformation(cores=self.pool.max_cores,
                                      instances=self.pool.max_servers,
                                      ram=self.pool.max_ram,
                                      default=math.inf)
        pool_quota.subtract(
            self.manager.estimatedNodepoolQuotaUsed(self.pool))
        self.log.debug("Current pool quota: %s" % pool_quota)
        pool_quota.subtract(needed_quota)
        self.log.debug("Predicted remaining pool quota: %s", pool_quota)

        return pool_quota.non_negative()
コード例 #10
0
    def unmanagedQuotaUsed(self):
        '''
        Sums up the quota used by servers unmanaged by nodepool.

        :return: Calculated quota in use by unmanaged servers
        '''
        flavors = self.listFlavorsById()
        used_quota = QuotaInformation()

        for server in self.listNodes():
            meta = server.get('metadata', {})

            nodepool_provider_name = meta.get('nodepool_provider_name')
            if nodepool_provider_name and \
                    nodepool_provider_name == self.provider.name:
                # This provider (regardless of the launcher) owns this server
                # so it must not be accounted for unmanaged quota.
                continue

            flavor = flavors.get(server.flavor.id)
            used_quota.add(QuotaInformation.construct_from_flavor(flavor))

        return used_quota
コード例 #11
0
ファイル: provider.py プロジェクト: progmaticlab/nodepool
    def estimatedNodepoolQuotaUsed(self, pool=None):
        '''
        Sums up the quota used (or planned) currently by nodepool. If pool is
        given it is filtered by the pool.

        :param pool: If given, filtered by the pool.
        :return: Calculated quota in use by nodepool
        '''
        used_quota = QuotaInformation()

        for node in self._zk.nodeIterator():
            if node.provider == self.provider.name:
                try:
                    if pool and not node.pool == pool.name:
                        continue
                    provider_pool = self.provider.pools.get(node.pool)
                    if not provider_pool:
                        self.log.warning(
                            "Cannot find provider pool for node %s" % node)
                        # This node is in a funny state we log it for debugging
                        # but move on and don't account it as we can't properly
                        # calculate its cost without pool info.
                        continue
                    if node.type[0] not in provider_pool.labels:
                        self.log.warning("Node type is not in provider pool "
                                         "for node %s" % node)
                        # This node is also in a funny state; the config
                        # may have changed under it.  It should settle out
                        # eventually when it's deleted.
                        continue
                    node_resources = self.quotaNeededByNodeType(
                        node.type[0], provider_pool)
                    used_quota.add(node_resources)
                except Exception:
                    self.log.exception("Couldn't consider invalid node %s "
                                       "for quota:" % node)
        return used_quota
コード例 #12
0
ファイル: provider.py プロジェクト: openstack-infra/nodepool
    def estimatedNodepoolQuotaUsed(self, pool=None):
        '''
        Sums up the quota used (or planned) currently by nodepool. If pool is
        given it is filtered by the pool.

        :param pool: If given, filtered by the pool.
        :return: Calculated quota in use by nodepool
        '''
        used_quota = QuotaInformation()

        for node in self._zk.nodeIterator():
            if node.provider == self.provider.name:
                try:
                    if pool and not node.pool == pool.name:
                        continue
                    provider_pool = self.provider.pools.get(node.pool)
                    if not provider_pool:
                        self.log.warning(
                            "Cannot find provider pool for node %s" % node)
                        # This node is in a funny state we log it for debugging
                        # but move on and don't account it as we can't properly
                        # calculate its cost without pool info.
                        continue
                    if node.type[0] not in provider_pool.labels:
                        self.log.warning("Node type is not in provider pool "
                                         "for node %s" % node)
                        # This node is also in a funny state; the config
                        # may have changed under it.  It should settle out
                        # eventually when it's deleted.
                        continue
                    node_resources = self.quotaNeededByNodeType(
                        node.type[0], provider_pool)
                    used_quota.add(node_resources)
                except Exception:
                    self.log.exception("Couldn't consider invalid node %s "
                                       "for quota:" % node)
        return used_quota
コード例 #13
0
ファイル: handler.py プロジェクト: leki75/nodepool
    def hasProviderQuota(self, node_types):
        needed_quota = QuotaInformation()

        for ntype in node_types:
            needed_quota.add(
                self.manager.quotaNeededByNodeType(ntype, self.pool))

        cloud_quota = self.manager.estimatedNodepoolQuota()
        cloud_quota.subtract(needed_quota)

        if not cloud_quota.non_negative():
            return False

        # Now calculate pool specific quota. Values indicating no quota default
        # to math.inf representing infinity that can be calculated with.
        pool_quota = QuotaInformation(cores=self.pool.max_cores,
                                      instances=self.pool.max_servers,
                                      ram=self.pool.max_ram,
                                      default=math.inf)
        pool_quota.subtract(needed_quota)
        return pool_quota.non_negative()
コード例 #14
0
ファイル: handler.py プロジェクト: progmaticlab/nodepool
    def hasRemainingQuota(self, ntype):
        '''
        Apply max_servers check, ignoring other quotas.

        :returns: True if we have room, False otherwise.
        '''
        needed_quota = QuotaInformation(cores=1, instances=1, ram=1, default=1)
        n_running = self.manager.countNodes(self.pool.name)
        pool_quota = QuotaInformation(cores=math.inf,
                                      instances=self.pool.max_servers -
                                      n_running,
                                      ram=math.inf,
                                      default=math.inf)
        pool_quota.subtract(needed_quota)
        self.log.debug("hasRemainingQuota({},{}) = {}".format(
            self.pool, ntype, pool_quota))
        return pool_quota.non_negative()
コード例 #15
0
    def estimatedNodepoolQuota(self):
        '''
        Determine how much quota is available for nodepool managed resources.
        This needs to take into account the quota of the tenant, resources
        used outside of nodepool and the currently used resources by nodepool,
        max settings in nodepool config. This is cached for MAX_QUOTA_AGE
        seconds.

        :return: Total amount of resources available which is currently
                 available to nodepool including currently existing nodes.
        '''

        if self._current_nodepool_quota:
            now = time.time()
            if now < self._current_nodepool_quota['timestamp'] + MAX_QUOTA_AGE:
                return copy.deepcopy(self._current_nodepool_quota['quota'])

        limits = self._client.get_compute_limits()

        # This is initialized with the full tenant quota and later becomes
        # the quota available for nodepool.
        nodepool_quota = QuotaInformation.construct_from_limits(limits)
        self.log.debug("Provider quota for %s: %s", self.provider.name,
                       nodepool_quota)

        # Subtract the unmanaged quota usage from nodepool_max
        # to get the quota available for us.
        nodepool_quota.subtract(self.unmanagedQuotaUsed())

        self._current_nodepool_quota = {
            'quota': nodepool_quota,
            'timestamp': time.time()
        }

        self.log.debug("Available quota for %s: %s", self.provider.name,
                       nodepool_quota)

        return copy.deepcopy(nodepool_quota)
コード例 #16
0
ファイル: provider.py プロジェクト: openstack-infra/nodepool
    def estimatedNodepoolQuota(self):
        '''
        Determine how much quota is available for nodepool managed resources.
        This needs to take into account the quota of the tenant, resources
        used outside of nodepool and the currently used resources by nodepool,
        max settings in nodepool config. This is cached for MAX_QUOTA_AGE
        seconds.

        :return: Total amount of resources available which is currently
                 available to nodepool including currently existing nodes.
        '''

        if self._current_nodepool_quota:
            now = time.time()
            if now < self._current_nodepool_quota['timestamp'] + MAX_QUOTA_AGE:
                return copy.deepcopy(self._current_nodepool_quota['quota'])

        limits = self._client.get_compute_limits()

        # This is initialized with the full tenant quota and later becomes
        # the quota available for nodepool.
        nodepool_quota = QuotaInformation.construct_from_limits(limits)
        self.log.debug("Provider quota for %s: %s",
                       self.provider.name, nodepool_quota)

        # Subtract the unmanaged quota usage from nodepool_max
        # to get the quota available for us.
        nodepool_quota.subtract(self.unmanagedQuotaUsed())

        self._current_nodepool_quota = {
            'quota': nodepool_quota,
            'timestamp': time.time()
        }

        self.log.debug("Available quota for %s: %s",
                       self.provider.name, nodepool_quota)

        return copy.deepcopy(nodepool_quota)
コード例 #17
0
ファイル: handler.py プロジェクト: progmaticlab/nodepool
    def hasProviderQuota(self, node_types):
        '''
        Apply max_servers check to a whole request

        :returns: True if we have room, False otherwise.
        '''
        needed_quota = QuotaInformation(cores=1,
                                        instances=len(node_types),
                                        ram=1,
                                        default=1)
        pool_quota = QuotaInformation(cores=math.inf,
                                      instances=self.pool.max_servers,
                                      ram=math.inf,
                                      default=math.inf)
        pool_quota.subtract(needed_quota)
        self.log.debug("hasProviderQuota({},{}) = {}".format(
            self.pool, node_types, pool_quota))
        return pool_quota.non_negative()
コード例 #18
0
ファイル: handler.py プロジェクト: openstack-infra/nodepool
    def hasProviderQuota(self, node_types):
        needed_quota = QuotaInformation()

        for ntype in node_types:
            needed_quota.add(
                self.manager.quotaNeededByNodeType(ntype, self.pool))

        if not self.pool.ignore_provider_quota:
            cloud_quota = self.manager.estimatedNodepoolQuota()
            cloud_quota.subtract(needed_quota)

            if not cloud_quota.non_negative():
                return False

        # Now calculate pool specific quota. Values indicating no quota default
        # to math.inf representing infinity that can be calculated with.
        pool_quota = QuotaInformation(cores=self.pool.max_cores,
                                      instances=self.pool.max_servers,
                                      ram=self.pool.max_ram,
                                      default=math.inf)
        pool_quota.subtract(needed_quota)
        return pool_quota.non_negative()