import datetime
import logging
import time
from enum import Enum
[docs]class VmState(Enum):
"""
Standard states for a Virtual Machine.
:var RUNNING: Vm is running.
:var NEARBY_SHUTDOWN: Vm is running but it's minutes are numbered.
:var AFTER_TIME_SHUTDOWN: Vm is running but it should be dead now.
:var TERMINATED: Vm is terminated. This node can't be started later on.
:var PENDING: Vm is pending.
:var UNKNOWN: Vm state is unknown.
:var ERROR: Vm is an error state. Usually no operations can be performed
on the node once it ends up in the error state.
"""
RUNNING = 'running'
NEARBY_SHUTDOWN = 'nearby_shutdown'
AFTER_TIME_SHUTDOWN = 'after_time_shutdown'
TERMINATED = 'terminated'
PENDING = 'pending'
UNKNOWN = 'unknown'
ERROR = 'error'
[docs]class Vm:
"""
Vm class definition.
Define API to implement in specific IaasDrivers like Openstack or EC2.
"""
def __init__(self, manager, id, name, ip, created, state=VmState.UNKNOWN, metadata=None, tags=None,
flavor=None, image=None, timed_shutdown_at=None):
""" Init for VM.
:arg AbstractIaasDriver manager: class implementing Vm actions.
:arg string id: Vm uniq id.
:arg string name: Vm name/preset_name ??.
:arg list ip: Vm ip list.
:arg datetime/int created: Timestamp when Vm was created
:arg VmState state: Vm state.
:arg dict metadata: Vm metadata.
:arg list tags: Vm tags.
:arg string flavor: Vm flavor name.
:arg string image: Vm image name.
:arg int timed_shutdown_at: Timestamp when VM will be terminated.
"""
self.manager = manager
self.id = id
self.name = name
self.ip = ip
self.state = state
self.metadata = metadata
self.tags = tags
self.flavor = flavor
self.image = image
self.timed_shutdown_at = timed_shutdown_at
if isinstance(created, datetime.datetime):
self.created = created
elif isinstance(created, (int, float)):
self.created = datetime.datetime.fromtimestamp(created)
else:
# actually it's not so crucial to fail
self.created = time.time()
def __str__(self):
return f'VM id={self.id} preset={self.name} state={self.state} ip={self.ip}'
def __eq__(self, other):
for prop in ('id', 'ip', 'name', 'flavor', 'image'):
if getattr(self, prop) != getattr(other, prop):
return False
return True
def __gt__(self, other):
return self.created > other.created
def __hash__(self):
return hash(self.id)
[docs] async def terminate(self):
""" Terminate vm.
"""
logging.debug('Terminate: %s', self)
self.state = VmState.TERMINATED
return await self.manager.terminate_vm(self.id)
[docs] def is_running(self):
return self.state in (VmState.RUNNING, VmState.NEARBY_SHUTDOWN)
[docs] def is_dead(self):
return self.state in (VmState.TERMINATED, VmState.ERROR, VmState.AFTER_TIME_SHUTDOWN)
[docs] def get_state(self):
return self.state.value