Refactored the compute model and its elements
In this changeset, I refactored the whole Watcher codebase to adopt a naming convention about the various elements of the Compute model so that it reflects the same naming convention adopted by Nova. Change-Id: I28adba5e1f27175f025330417b072686134d5f51 Partially-Implements: blueprint cluster-model-objects-wrapper
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
@@ -40,7 +39,7 @@ class CollectorManager(object):
|
||||
for collector_name in available_collectors:
|
||||
collector = self.collector_loader.load(collector_name)
|
||||
collectors[collector_name] = collector
|
||||
self._collectors = collectors
|
||||
self._collectors = collectors
|
||||
|
||||
return self._collectors
|
||||
|
||||
|
||||
@@ -20,10 +20,8 @@ from oslo_log import log
|
||||
|
||||
from watcher.common import nova_helper
|
||||
from watcher.decision_engine.model.collector import base
|
||||
from watcher.decision_engine.model import hypervisor as obj_hypervisor
|
||||
from watcher.decision_engine.model import element
|
||||
from watcher.decision_engine.model import model_root
|
||||
from watcher.decision_engine.model import resource
|
||||
from watcher.decision_engine.model import vm as obj_vm
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
@@ -50,45 +48,46 @@ class NovaClusterDataModelCollector(base.BaseClusterDataModelCollector):
|
||||
LOG.debug("Building latest Nova cluster data model")
|
||||
|
||||
model = model_root.ModelRoot()
|
||||
mem = resource.Resource(resource.ResourceType.memory)
|
||||
num_cores = resource.Resource(resource.ResourceType.cpu_cores)
|
||||
disk = resource.Resource(resource.ResourceType.disk)
|
||||
disk_capacity = resource.Resource(resource.ResourceType.disk_capacity)
|
||||
mem = element.Resource(element.ResourceType.memory)
|
||||
num_cores = element.Resource(element.ResourceType.cpu_cores)
|
||||
disk = element.Resource(element.ResourceType.disk)
|
||||
disk_capacity = element.Resource(element.ResourceType.disk_capacity)
|
||||
model.create_resource(mem)
|
||||
model.create_resource(num_cores)
|
||||
model.create_resource(disk)
|
||||
model.create_resource(disk_capacity)
|
||||
|
||||
flavor_cache = {}
|
||||
hypervisors = self.wrapper.get_hypervisors_list()
|
||||
for h in hypervisors:
|
||||
service = self.wrapper.nova.services.find(id=h.service['id'])
|
||||
# create hypervisor in cluster_model_collector
|
||||
hypervisor = obj_hypervisor.Hypervisor()
|
||||
hypervisor.uuid = service.host
|
||||
hypervisor.hostname = h.hypervisor_hostname
|
||||
nodes = self.wrapper.get_compute_node_list()
|
||||
for n in nodes:
|
||||
service = self.wrapper.nova.services.find(id=n.service['id'])
|
||||
# create node in cluster_model_collector
|
||||
node = element.ComputeNode()
|
||||
node.uuid = service.host
|
||||
node.hostname = n.hypervisor_hostname
|
||||
# set capacity
|
||||
mem.set_capacity(hypervisor, h.memory_mb)
|
||||
disk.set_capacity(hypervisor, h.free_disk_gb)
|
||||
disk_capacity.set_capacity(hypervisor, h.local_gb)
|
||||
num_cores.set_capacity(hypervisor, h.vcpus)
|
||||
hypervisor.state = h.state
|
||||
hypervisor.status = h.status
|
||||
model.add_hypervisor(hypervisor)
|
||||
vms = self.wrapper.get_vms_by_hypervisor(str(service.host))
|
||||
for v in vms:
|
||||
mem.set_capacity(node, n.memory_mb)
|
||||
disk.set_capacity(node, n.free_disk_gb)
|
||||
disk_capacity.set_capacity(node, n.local_gb)
|
||||
num_cores.set_capacity(node, n.vcpus)
|
||||
node.state = n.state
|
||||
node.status = n.status
|
||||
model.add_node(node)
|
||||
instances = self.wrapper.get_instances_by_node(str(service.host))
|
||||
for v in instances:
|
||||
# create VM in cluster_model_collector
|
||||
vm = obj_vm.VM()
|
||||
vm.uuid = v.id
|
||||
# nova/nova/compute/vm_states.py
|
||||
vm.state = getattr(v, 'OS-EXT-STS:vm_state')
|
||||
instance = element.Instance()
|
||||
instance.uuid = v.id
|
||||
# nova/nova/compute/instance_states.py
|
||||
instance.state = getattr(v, 'OS-EXT-STS:instance_state')
|
||||
|
||||
# set capacity
|
||||
self.wrapper.get_flavor_instance(v, flavor_cache)
|
||||
mem.set_capacity(vm, v.flavor['ram'])
|
||||
disk.set_capacity(vm, v.flavor['disk'])
|
||||
num_cores.set_capacity(vm, v.flavor['vcpus'])
|
||||
mem.set_capacity(instance, v.flavor['ram'])
|
||||
disk.set_capacity(instance, v.flavor['disk'])
|
||||
num_cores.set_capacity(instance, v.flavor['vcpus'])
|
||||
|
||||
model.get_mapping().map(node, instance)
|
||||
model.add_instance(instance)
|
||||
|
||||
model.get_mapping().map(hypervisor, vm)
|
||||
model.add_vm(vm)
|
||||
return model
|
||||
|
||||
39
watcher/decision_engine/model/element/__init__.py
Normal file
39
watcher/decision_engine/model/element/__init__.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2016 b<>com
|
||||
#
|
||||
# Authors: Vincent FRANCOISE <vincent.francoise@b-com.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from watcher.decision_engine.model.element import disk_info
|
||||
from watcher.decision_engine.model.element import instance
|
||||
from watcher.decision_engine.model.element import node
|
||||
from watcher.decision_engine.model.element import resource
|
||||
|
||||
ServiceState = node.ServiceState
|
||||
PowerState = node.PowerState
|
||||
ComputeNode = node.ComputeNode
|
||||
|
||||
InstanceState = instance.InstanceState
|
||||
Instance = instance.Instance
|
||||
|
||||
DiskInfo = disk_info.DiskInfo
|
||||
|
||||
ResourceType = resource.ResourceType
|
||||
Resource = resource.Resource
|
||||
|
||||
|
||||
__all__ = [
|
||||
'ServiceState', 'PowerState', 'ComputeNode', 'InstanceState', 'Instance',
|
||||
'DiskInfo', 'ResourceType', 'Resource']
|
||||
@@ -1,11 +1,13 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2015 b<>com
|
||||
# Copyright (c) 2016 b<>com
|
||||
#
|
||||
# Authors: Vincent FRANCOISE <vincent.francoise@b-com.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -14,11 +16,14 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import enum
|
||||
import abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
class HypervisorState(enum.Enum):
|
||||
ONLINE = 'up'
|
||||
OFFLINE = 'down'
|
||||
ENABLED = 'enabled'
|
||||
DISABLED = 'disabled'
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Element(object):
|
||||
|
||||
@abc.abstractmethod
|
||||
def accept(self, visitor):
|
||||
raise NotImplementedError()
|
||||
@@ -14,8 +14,15 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import abc
|
||||
|
||||
class ComputeResource(object):
|
||||
import six
|
||||
|
||||
from watcher.decision_engine.model.element import base
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ComputeResource(base.Element):
|
||||
|
||||
def __init__(self):
|
||||
self._uuid = ""
|
||||
@@ -14,8 +14,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from watcher.decision_engine.model.element import base
|
||||
|
||||
|
||||
class DiskInfo(base.Element):
|
||||
|
||||
class DiskInfo(object):
|
||||
def __init__(self):
|
||||
self.name = ""
|
||||
self.major = 0
|
||||
@@ -23,6 +26,9 @@ class DiskInfo(object):
|
||||
self.size = 0
|
||||
self.scheduler = ""
|
||||
|
||||
def accept(self, visitor):
|
||||
raise NotImplementedError()
|
||||
|
||||
def set_size(self, size):
|
||||
"""DiskInfo
|
||||
|
||||
54
watcher/decision_engine/model/element/instance.py
Normal file
54
watcher/decision_engine/model/element/instance.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2015 b<>com
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import enum
|
||||
|
||||
from watcher.decision_engine.model.element import compute_resource
|
||||
|
||||
|
||||
class InstanceState(enum.Enum):
|
||||
ACTIVE = 'active' # Instance is running
|
||||
BUILDING = 'building' # Instance only exists in DB
|
||||
PAUSED = 'paused'
|
||||
SUSPENDED = 'suspended' # Instance is suspended to disk.
|
||||
STOPPED = 'stopped' # Instance is shut off, the disk image is still there.
|
||||
RESCUED = 'rescued' # A rescue image is running with the original image
|
||||
# attached.
|
||||
RESIZED = 'resized' # a Instance with the new size is active.
|
||||
|
||||
SOFT_DELETED = 'soft-delete'
|
||||
# still available to restore.
|
||||
DELETED = 'deleted' # Instance is permanently deleted.
|
||||
|
||||
ERROR = 'error'
|
||||
|
||||
|
||||
class Instance(compute_resource.ComputeResource):
|
||||
|
||||
def __init__(self):
|
||||
super(Instance, self).__init__()
|
||||
self._state = InstanceState.ACTIVE.value
|
||||
|
||||
def accept(self, visitor):
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
@state.setter
|
||||
def state(self, state):
|
||||
self._state = state
|
||||
@@ -14,17 +14,46 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from watcher.decision_engine.model import compute_resource
|
||||
from watcher.decision_engine.model import hypervisor_state
|
||||
from watcher.decision_engine.model import power_state
|
||||
import enum
|
||||
|
||||
from watcher.decision_engine.model.element import compute_resource
|
||||
|
||||
|
||||
class Hypervisor(compute_resource.ComputeResource):
|
||||
class ServiceState(enum.Enum):
|
||||
ONLINE = 'up'
|
||||
OFFLINE = 'down'
|
||||
ENABLED = 'enabled'
|
||||
DISABLED = 'disabled'
|
||||
|
||||
|
||||
class PowerState(enum.Enum):
|
||||
# away mode
|
||||
g0 = "g0"
|
||||
# power on suspend (processor caches are flushed)
|
||||
# The power to the CPU(s) and RAM is maintained
|
||||
g1_S1 = "g1_S1"
|
||||
# CPU powered off. Dirty cache is flushed to RAM
|
||||
g1_S2 = "g1_S2"
|
||||
# Suspend to RAM
|
||||
g1_S3 = "g1_S3"
|
||||
# Suspend to Disk
|
||||
g1_S4 = "g1_S4"
|
||||
# switch outlet X OFF on the PDU (Power Distribution Unit)
|
||||
switch_off = "switch_off"
|
||||
# switch outlet X ON on the PDU (Power Distribution Unit)
|
||||
switch_on = "switch_on"
|
||||
|
||||
|
||||
class ComputeNode(compute_resource.ComputeResource):
|
||||
|
||||
def __init__(self):
|
||||
super(Hypervisor, self).__init__()
|
||||
self._state = hypervisor_state.HypervisorState.ONLINE
|
||||
self._status = hypervisor_state.HypervisorState.ENABLED
|
||||
self._power_state = power_state.PowerState.g0
|
||||
super(ComputeNode, self).__init__()
|
||||
self._state = ServiceState.ONLINE
|
||||
self._status = ServiceState.ENABLED
|
||||
self._power_state = PowerState.g0
|
||||
|
||||
def accept(self, visitor):
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
@@ -14,9 +14,10 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo_log import log
|
||||
import threading
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from watcher._i18n import _LW
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
@@ -25,110 +26,108 @@ LOG = log.getLogger(__name__)
|
||||
class Mapping(object):
|
||||
def __init__(self, model):
|
||||
self.model = model
|
||||
self._mapping_hypervisors = {}
|
||||
self.mapping_vm = {}
|
||||
self.compute_node_mapping = {}
|
||||
self.instance_mapping = {}
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def map(self, hypervisor, vm):
|
||||
"""Select the hypervisor where the instance is launched
|
||||
def map(self, node, instance):
|
||||
"""Select the node where the instance is launched
|
||||
|
||||
:param hypervisor: the hypervisor
|
||||
:param vm: the virtual machine or instance
|
||||
:param node: the node
|
||||
:param instance: the virtual machine or instance
|
||||
"""
|
||||
|
||||
try:
|
||||
self.lock.acquire()
|
||||
|
||||
# init first
|
||||
if hypervisor.uuid not in self._mapping_hypervisors.keys():
|
||||
self._mapping_hypervisors[hypervisor.uuid] = []
|
||||
if node.uuid not in self.compute_node_mapping.keys():
|
||||
self.compute_node_mapping[node.uuid] = []
|
||||
|
||||
# map node => vms
|
||||
self._mapping_hypervisors[hypervisor.uuid].append(
|
||||
vm.uuid)
|
||||
# map node => instances
|
||||
self.compute_node_mapping[node.uuid].append(
|
||||
instance.uuid)
|
||||
|
||||
# map vm => node
|
||||
self.mapping_vm[vm.uuid] = hypervisor.uuid
|
||||
# map instance => node
|
||||
self.instance_mapping[instance.uuid] = node.uuid
|
||||
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def unmap(self, hypervisor, vm):
|
||||
"""Remove the instance from the hypervisor
|
||||
def unmap(self, node, instance):
|
||||
"""Remove the instance from the node
|
||||
|
||||
:param hypervisor: the hypervisor
|
||||
:param vm: the virtual machine or instance
|
||||
:param node: the node
|
||||
:param instance: the virtual machine or instance
|
||||
"""
|
||||
|
||||
self.unmap_from_id(hypervisor.uuid, vm.uuid)
|
||||
self.unmap_from_id(node.uuid, instance.uuid)
|
||||
|
||||
def unmap_from_id(self, node_uuid, vm_uuid):
|
||||
"""Remove the instance (by id) from the hypervisor (by id)
|
||||
def unmap_from_id(self, node_uuid, instance_uuid):
|
||||
"""Remove the instance (by id) from the node (by id)
|
||||
|
||||
:rtype : object
|
||||
"""
|
||||
|
||||
try:
|
||||
self.lock.acquire()
|
||||
if str(node_uuid) in self._mapping_hypervisors:
|
||||
self._mapping_hypervisors[str(node_uuid)].remove(str(vm_uuid))
|
||||
# remove vm
|
||||
self.mapping_vm.pop(vm_uuid)
|
||||
if str(node_uuid) in self.compute_node_mapping:
|
||||
self.compute_node_mapping[str(node_uuid)].remove(
|
||||
str(instance_uuid))
|
||||
# remove instance
|
||||
self.instance_mapping.pop(instance_uuid)
|
||||
else:
|
||||
LOG.warning(_LW(
|
||||
"trying to delete the virtual machine %(vm)s but it was "
|
||||
"not found on hypervisor %(hyp)s"),
|
||||
{'vm': vm_uuid, 'hyp': node_uuid})
|
||||
"Trying to delete the instance %(instance)s but it was "
|
||||
"not found on node %(node)s"),
|
||||
{'instance': instance_uuid, 'node': node_uuid})
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def get_mapping(self):
|
||||
return self._mapping_hypervisors
|
||||
return self.compute_node_mapping
|
||||
|
||||
def get_mapping_vm(self):
|
||||
return self.mapping_vm
|
||||
def get_node_from_instance(self, instance):
|
||||
return self.get_node_from_instance_id(instance.uuid)
|
||||
|
||||
def get_node_from_vm(self, vm):
|
||||
return self.get_node_from_vm_id(vm.uuid)
|
||||
def get_node_from_instance_id(self, instance_uuid):
|
||||
"""Getting host information from the guest instance
|
||||
|
||||
def get_node_from_vm_id(self, vm_uuid):
|
||||
"""Getting host information from the guest VM
|
||||
|
||||
:param vm: the uuid of the instance
|
||||
:return: hypervisor
|
||||
:param instance: the uuid of the instance
|
||||
:return: node
|
||||
"""
|
||||
|
||||
return self.model.get_hypervisor_from_id(
|
||||
self.get_mapping_vm()[str(vm_uuid)])
|
||||
return self.model.get_node_from_id(
|
||||
self.instance_mapping[str(instance_uuid)])
|
||||
|
||||
def get_node_vms(self, hypervisor):
|
||||
"""Get the list of instances running on the hypervisor
|
||||
def get_node_instances(self, node):
|
||||
"""Get the list of instances running on the node
|
||||
|
||||
:param hypervisor:
|
||||
:param node:
|
||||
:return:
|
||||
"""
|
||||
return self.get_node_vms_from_id(hypervisor.uuid)
|
||||
return self.get_node_instances_from_id(node.uuid)
|
||||
|
||||
def get_node_vms_from_id(self, node_uuid):
|
||||
if str(node_uuid) in self._mapping_hypervisors.keys():
|
||||
return self._mapping_hypervisors[str(node_uuid)]
|
||||
def get_node_instances_from_id(self, node_uuid):
|
||||
if str(node_uuid) in self.compute_node_mapping.keys():
|
||||
return self.compute_node_mapping[str(node_uuid)]
|
||||
else:
|
||||
# empty
|
||||
return []
|
||||
|
||||
def migrate_vm(self, vm, src_hypervisor, dest_hypervisor):
|
||||
"""Migrate single instance from src_hypervisor to dest_hypervisor
|
||||
def migrate_instance(self, instance, source_node, destination_node):
|
||||
"""Migrate single instance from source_node to destination_node
|
||||
|
||||
:param vm:
|
||||
:param src_hypervisor:
|
||||
:param dest_hypervisor:
|
||||
:param instance:
|
||||
:param source_node:
|
||||
:param destination_node:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if src_hypervisor == dest_hypervisor:
|
||||
if source_node == destination_node:
|
||||
return False
|
||||
# unmap
|
||||
self.unmap(src_hypervisor, vm)
|
||||
self.unmap(source_node, instance)
|
||||
# map
|
||||
self.map(dest_hypervisor, vm)
|
||||
self.map(destination_node, instance)
|
||||
return True
|
||||
|
||||
@@ -17,16 +17,14 @@
|
||||
from watcher._i18n import _
|
||||
from watcher.common import exception
|
||||
from watcher.common import utils
|
||||
from watcher.decision_engine.model import hypervisor
|
||||
from watcher.decision_engine.model import element
|
||||
from watcher.decision_engine.model import mapping
|
||||
from watcher.decision_engine.model import vm
|
||||
|
||||
|
||||
class ModelRoot(object):
|
||||
|
||||
def __init__(self, stale=False):
|
||||
self._hypervisors = utils.Struct()
|
||||
self._vms = utils.Struct()
|
||||
self._nodes = utils.Struct()
|
||||
self._instances = utils.Struct()
|
||||
self.mapping = mapping.Mapping(self)
|
||||
self.resource = utils.Struct()
|
||||
self.stale = stale
|
||||
@@ -36,46 +34,46 @@ class ModelRoot(object):
|
||||
|
||||
__bool__ = __nonzero__
|
||||
|
||||
def assert_hypervisor(self, obj):
|
||||
if not isinstance(obj, hypervisor.Hypervisor):
|
||||
def assert_node(self, obj):
|
||||
if not isinstance(obj, element.ComputeNode):
|
||||
raise exception.IllegalArgumentException(
|
||||
message=_("'obj' argument type is not valid"))
|
||||
|
||||
def assert_vm(self, obj):
|
||||
if not isinstance(obj, vm.VM):
|
||||
def assert_instance(self, obj):
|
||||
if not isinstance(obj, element.Instance):
|
||||
raise exception.IllegalArgumentException(
|
||||
message=_("'obj' argument type is not valid"))
|
||||
|
||||
def add_hypervisor(self, hypervisor):
|
||||
self.assert_hypervisor(hypervisor)
|
||||
self._hypervisors[hypervisor.uuid] = hypervisor
|
||||
def add_node(self, node):
|
||||
self.assert_node(node)
|
||||
self._nodes[node.uuid] = node
|
||||
|
||||
def remove_hypervisor(self, hypervisor):
|
||||
self.assert_hypervisor(hypervisor)
|
||||
if str(hypervisor.uuid) not in self._hypervisors.keys():
|
||||
raise exception.HypervisorNotFound(hypervisor.uuid)
|
||||
def remove_node(self, node):
|
||||
self.assert_node(node)
|
||||
if str(node.uuid) not in self._nodes:
|
||||
raise exception.ComputeNodeNotFound(node.uuid)
|
||||
else:
|
||||
del self._hypervisors[hypervisor.uuid]
|
||||
del self._nodes[node.uuid]
|
||||
|
||||
def add_vm(self, vm):
|
||||
self.assert_vm(vm)
|
||||
self._vms[vm.uuid] = vm
|
||||
def add_instance(self, instance):
|
||||
self.assert_instance(instance)
|
||||
self._instances[instance.uuid] = instance
|
||||
|
||||
def get_all_hypervisors(self):
|
||||
return self._hypervisors
|
||||
def get_all_compute_nodes(self):
|
||||
return self._nodes
|
||||
|
||||
def get_hypervisor_from_id(self, hypervisor_uuid):
|
||||
if str(hypervisor_uuid) not in self._hypervisors.keys():
|
||||
raise exception.HypervisorNotFound(hypervisor_uuid)
|
||||
return self._hypervisors[str(hypervisor_uuid)]
|
||||
def get_node_from_id(self, node_uuid):
|
||||
if str(node_uuid) not in self._nodes:
|
||||
raise exception.ComputeNodeNotFound(node_uuid)
|
||||
return self._nodes[str(node_uuid)]
|
||||
|
||||
def get_vm_from_id(self, uuid):
|
||||
if str(uuid) not in self._vms.keys():
|
||||
def get_instance_from_id(self, uuid):
|
||||
if str(uuid) not in self._instances:
|
||||
raise exception.InstanceNotFound(name=uuid)
|
||||
return self._vms[str(uuid)]
|
||||
return self._instances[str(uuid)]
|
||||
|
||||
def get_all_vms(self):
|
||||
return self._vms
|
||||
def get_all_instances(self):
|
||||
return self._instances
|
||||
|
||||
def get_mapping(self):
|
||||
return self.mapping
|
||||
@@ -83,5 +81,5 @@ class ModelRoot(object):
|
||||
def create_resource(self, r):
|
||||
self.resource[str(r.name)] = r
|
||||
|
||||
def get_resource_from_id(self, id):
|
||||
return self.resource[str(id)]
|
||||
def get_resource_from_id(self, resource_id):
|
||||
return self.resource[str(resource_id)]
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import enum
|
||||
|
||||
|
||||
class PowerState(enum.Enum):
|
||||
# away mode
|
||||
g0 = "g0"
|
||||
# power on suspend (processor caches are flushed)
|
||||
# The power to the CPU(s) and RAM is maintained
|
||||
g1_S1 = "g1_S1"
|
||||
# CPU powered off. Dirty cache is flushed to RAM
|
||||
g1_S2 = "g1_S2"
|
||||
# Suspend to RAM
|
||||
g1_S3 = "g1_S3"
|
||||
# Suspend to Disk
|
||||
g1_S4 = "g1_S4"
|
||||
# switch outlet X OFF on the PDU (Power Distribution Unit)
|
||||
switch_off = "switch_off"
|
||||
# switch outlet X ON on the PDU (Power Distribution Unit)
|
||||
switch_on = "switch_on"
|
||||
@@ -1,31 +0,0 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2015 b<>com
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from watcher.decision_engine.model import compute_resource
|
||||
from watcher.decision_engine.model import vm_state
|
||||
|
||||
|
||||
class VM(compute_resource.ComputeResource):
|
||||
def __init__(self):
|
||||
super(VM, self).__init__()
|
||||
self._state = vm_state.VMState.ACTIVE.value
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
@state.setter
|
||||
def state(self, state):
|
||||
self._state = state
|
||||
@@ -1,34 +0,0 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2015 b<>com
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import enum
|
||||
|
||||
|
||||
class VMState(enum.Enum):
|
||||
ACTIVE = 'active' # VM is running
|
||||
BUILDING = 'building' # VM only exists in DB
|
||||
PAUSED = 'paused'
|
||||
SUSPENDED = 'suspended' # VM is suspended to disk.
|
||||
STOPPED = 'stopped' # VM is powered off, the disk image is still there.
|
||||
RESCUED = 'rescued' # A rescue image is running with the original VM image
|
||||
# attached.
|
||||
RESIZED = 'resized' # a VM with the new size is active.
|
||||
|
||||
SOFT_DELETED = 'soft-delete'
|
||||
# still available to restore.
|
||||
DELETED = 'deleted' # VM is permanently deleted.
|
||||
|
||||
ERROR = 'error'
|
||||
Reference in New Issue
Block a user