diff --git a/wrapanapi/exceptions.py b/wrapanapi/exceptions.py index 88184446..f309055d 100644 --- a/wrapanapi/exceptions.py +++ b/wrapanapi/exceptions.py @@ -150,3 +150,15 @@ class VMError(Exception): class VMCreationDateError(Exception): """Raised when we cannot determine a creation date for a VM""" pass + + +class VMInstanceNotStopped(Exception): + """Raised if a VM or instance is not in stopped state.""" + def __init__(self, vm_name, action="action"): + self.vm_name = vm_name + self.action = action + + def __str__(self): + return "Could not perform '{a}' on '{vm}' because it's not stopped.".format( + a=self.action, vm=self.vm_name + ) diff --git a/wrapanapi/systems/virtualcenter.py b/wrapanapi/systems/virtualcenter.py index 6bbe60c6..6dc4ca7d 100644 --- a/wrapanapi/systems/virtualcenter.py +++ b/wrapanapi/systems/virtualcenter.py @@ -27,8 +27,8 @@ from wrapanapi.entities.base import Entity from wrapanapi.exceptions import (HostNotRemoved, NotFoundError, VMCreationDateError, VMInstanceNotCloned, - VMInstanceNotFound, VMInstanceNotSuspended, - VMNotFoundViaIP) + VMInstanceNotFound, VMInstanceNotStopped, + VMInstanceNotSuspended, VMNotFoundViaIP) from wrapanapi.systems.base import System @@ -492,6 +492,56 @@ def creation_time(self): # localize and make tz-naive return creation_time.astimezone(pytz.UTC) + @property + def cpu_hot_plug(self): + return self.raw.config.cpuHotAddEnabled + + @property + def memory_hot_plug(self): + return self.raw.config.memoryHotAddEnabled + + @cpu_hot_plug.setter + def cpu_hot_plug(self, value): + """ + Set cpuHotPlug (enabled/disabled) for VM/Instance. + + Args: + value (bool): cpu hot plug state + """ + if self.cpu_hot_plug != value: + if self.is_stopped: + spec = vim.vm.ConfigSpec() + spec.cpuHotAddEnabled = value + task = self.raw.ReconfigVM_Task(spec) + + try: + wait_for(lambda: task.info.state not in ["running", "queued"]) + except TimedOutError: + self.logger.exception("Task did not go to success state: %s", task) + else: + raise VMInstanceNotStopped(self.name, "cpuHotPlug") + + @memory_hot_plug.setter + def memory_hot_plug(self, value): + """ + Set memoryHotPlug (enabled/disabled) for VM/Instance + + Args: + value (bool): memory hot plug state + """ + if self.memory_hot_plug != value: + if self.is_stopped: + spec = vim.vm.ConfigSpec() + spec.memoryHotAddEnabled = value + task = self.raw.ReconfigVM_Task(spec) + + try: + wait_for(lambda: task.info.state not in ["running", "queued"]) + except TimedOutError: + self.logger.exception("Task did not go to success state: %s", task) + else: + raise VMInstanceNotStopped(self.name, "memoryHotPlug") + def start(self): if self.is_running: self.logger.info(" vSphere VM %s is already running", self.name)