|
|
|
@ -149,6 +149,12 @@ options:
|
|
|
|
|
Prefix uses IEC 60027-2 standard (for example 1GiB, 1024MiB).
|
|
|
|
|
- C(memory_guaranteed) parameter can't be lower than C(memory) parameter.
|
|
|
|
|
- Default value is set by engine.
|
|
|
|
|
memory_max:
|
|
|
|
|
description:
|
|
|
|
|
- Upper bound of virtual machine memory up to which memory hot-plug can be performed.
|
|
|
|
|
Prefix uses IEC 60027-2 standard (for example 1GiB, 1024MiB).
|
|
|
|
|
- Default value is set by engine.
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
cpu_shares:
|
|
|
|
|
description:
|
|
|
|
|
- Set a CPU shares for this Virtual Machine.
|
|
|
|
@ -459,6 +465,67 @@ options:
|
|
|
|
|
- C(storage_domain) - Specifies the target storage domain for
|
|
|
|
|
converted disks. This is required parameter.
|
|
|
|
|
version_added: "2.3"
|
|
|
|
|
cpu_mode:
|
|
|
|
|
description:
|
|
|
|
|
- "CPU mode of the virtual machine. It can be some of the following: I(host_passthrough), I(host_model) or I(custom)."
|
|
|
|
|
- "For I(host_passthrough) CPU type you need to set C(placement_policy) to I(pinned)."
|
|
|
|
|
- "If no value is passed, default value is set by oVirt/RHV engine."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
placement_policy:
|
|
|
|
|
description:
|
|
|
|
|
- "The configuration of the virtual machine's placement policy."
|
|
|
|
|
- "Placement policy can be one of the following values:"
|
|
|
|
|
- "C(migratable) - Allow manual and automatic migration."
|
|
|
|
|
- "C(pinned) - Do not allow migration."
|
|
|
|
|
- "C(user_migratable) - Allow manual migration only."
|
|
|
|
|
- "If no value is passed, default value is set by oVirt/RHV engine."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
cpu_pinning:
|
|
|
|
|
description:
|
|
|
|
|
- "CPU Pinning topology to map virtual machine CPU to host CPU."
|
|
|
|
|
- "CPU Pinning topology is a list of dictionary which can have following values:"
|
|
|
|
|
- "C(cpu) - Number of the host CPU."
|
|
|
|
|
- "C(vcpu) - Number of the virtual machine CPU."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
soundcard_enabled:
|
|
|
|
|
description:
|
|
|
|
|
- "If I(true), the sound card is added to the virtual machine."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
smartcard_enabled:
|
|
|
|
|
description:
|
|
|
|
|
- "If I(true), use smart card authentication."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
io_threads_enabled:
|
|
|
|
|
description:
|
|
|
|
|
- "If I(true), use IO threads."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
ballooning_enabled:
|
|
|
|
|
description:
|
|
|
|
|
- "If I(true), use memory ballooning."
|
|
|
|
|
- "Memory balloon is a guest device, which may be used to re-distribute / reclaim the host memory
|
|
|
|
|
based on VM needs in a dynamic way. In this way it's possible to create memory over commitment states."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
rng_device:
|
|
|
|
|
description:
|
|
|
|
|
- "Random number generator (RNG). You can choose of one the following devices I(urandom), I(random) or I(hwrng)."
|
|
|
|
|
- "In order to select I(hwrng), you must have it enabled on cluster first."
|
|
|
|
|
- "/dev/urandom is used for cluster version >= 4.1, and /dev/random for cluster version <= 4.0"
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
custom_properties:
|
|
|
|
|
description:
|
|
|
|
|
- "Properties sent to VDSM to configure various hooks."
|
|
|
|
|
- "Custom properties is a list of dictionary which can have following values:"
|
|
|
|
|
- "C(name) - Name of the custom property. For example: I(hugepages), I(vhost), I(sap_agent), etc."
|
|
|
|
|
- "C(regexp) - Regular expression to set for custom property."
|
|
|
|
|
- "C(value) - Value to set for custom property."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
watchdog:
|
|
|
|
|
description:
|
|
|
|
|
- "Assign watchdog device for the virtual machine."
|
|
|
|
|
- "Watchdogs is a dictionary which can have following values:"
|
|
|
|
|
- "C(model) - Model of the watchdog device. For example: I(i6300esb), I(diag288) or I(null)."
|
|
|
|
|
- "C(action) - Watchdog action to be performed when watchdog is triggered. For example: I(none), I(reset), I(poweroff), I(pause) or I(dump)."
|
|
|
|
|
version_added: "2.5"
|
|
|
|
|
notes:
|
|
|
|
|
- If VM is in I(UNASSIGNED) or I(UNKNOWN) state before any operation, the module will fail.
|
|
|
|
|
If VM is in I(IMAGE_LOCKED) state before any operation, we try to wait for VM to be I(DOWN).
|
|
|
|
@ -875,10 +942,24 @@ class VmsModule(BaseModule):
|
|
|
|
|
cores=self.param('cpu_cores'),
|
|
|
|
|
sockets=self.param('cpu_sockets'),
|
|
|
|
|
threads=self.param('cpu_threads'),
|
|
|
|
|
)
|
|
|
|
|
) if (
|
|
|
|
|
any((self.param('cpu_cores'), self.param('cpu_sockets'), self.param('cpu_threads')))
|
|
|
|
|
) else None,
|
|
|
|
|
) if any((
|
|
|
|
|
self.param('cpu_cores'),
|
|
|
|
|
self.param('cpu_sockets'),
|
|
|
|
|
self.param('cpu_threads')
|
|
|
|
|
)) else None,
|
|
|
|
|
cpu_tune=otypes.CpuTune(
|
|
|
|
|
vcpu_pins=[
|
|
|
|
|
otypes.VcpuPin(vcpu=int(pin['vcpu']), cpu_set=str(pin['cpu'])) for pin in self.param('cpu_pinning')
|
|
|
|
|
],
|
|
|
|
|
) if self.param('cpu_pinning') else None,
|
|
|
|
|
mode=otypes.CpuMode(self.param('cpu_mode')) if self.param('cpu_mode') else None,
|
|
|
|
|
) if any((
|
|
|
|
|
self.param('cpu_cores'),
|
|
|
|
|
self.param('cpu_sockets'),
|
|
|
|
|
self.param('cpu_threads'),
|
|
|
|
|
self.param('cpu_mode'),
|
|
|
|
|
self.param('cpu_pinning')
|
|
|
|
|
)) else None,
|
|
|
|
|
cpu_shares=self.param('cpu_shares'),
|
|
|
|
|
os=otypes.OperatingSystem(
|
|
|
|
|
type=self.param('operating_system'),
|
|
|
|
@ -898,7 +979,13 @@ class VmsModule(BaseModule):
|
|
|
|
|
) if self.param('memory') else None,
|
|
|
|
|
memory_policy=otypes.MemoryPolicy(
|
|
|
|
|
guaranteed=convert_to_bytes(self.param('memory_guaranteed')),
|
|
|
|
|
) if self.param('memory_guaranteed') else None,
|
|
|
|
|
ballooning=self.param('ballooning_enabled'),
|
|
|
|
|
max=convert_to_bytes(self.param('memory_max')),
|
|
|
|
|
) if any((
|
|
|
|
|
self.param('memory_guaranteed'),
|
|
|
|
|
self.param('ballooning_enabled') is not None,
|
|
|
|
|
self.param('memory_max')
|
|
|
|
|
)) else None,
|
|
|
|
|
instance_type=otypes.InstanceType(
|
|
|
|
|
id=get_id_by_name(
|
|
|
|
|
self._connection.system_service().instance_types_service(),
|
|
|
|
@ -917,18 +1004,68 @@ class VmsModule(BaseModule):
|
|
|
|
|
self.param('serial_policy') is not None or
|
|
|
|
|
self.param('serial_policy_value') is not None
|
|
|
|
|
) else None,
|
|
|
|
|
placement_policy=otypes.VmPlacementPolicy(
|
|
|
|
|
affinity=otypes.VmAffinity(self.param('placement_policy')),
|
|
|
|
|
hosts=[
|
|
|
|
|
otypes.Host(name=self.param('host')),
|
|
|
|
|
] if self.param('host') else None,
|
|
|
|
|
) if self.param('placement_policy') else None,
|
|
|
|
|
soundcard_enabled=self.param('soundcard_enabled'),
|
|
|
|
|
display=otypes.Display(
|
|
|
|
|
smartcard_enabled=self.param('smartcard_enabled')
|
|
|
|
|
) if self.param('smartcard_enabled') is not None else None,
|
|
|
|
|
io=otypes.Io(
|
|
|
|
|
threads=int(self.param('io_threads_enabled')),
|
|
|
|
|
) if self.param('io_threads_enabled') is not None else None,
|
|
|
|
|
rng_device=otypes.RngDevice(
|
|
|
|
|
source=otypes.RngSource(self.param('rng_device')),
|
|
|
|
|
) if self.param('rng_device') else None,
|
|
|
|
|
custom_properties=[
|
|
|
|
|
otypes.CustomProperty(
|
|
|
|
|
name=cp.get('name'),
|
|
|
|
|
regexp=cp.get('regexp'),
|
|
|
|
|
value=str(cp.get('value')),
|
|
|
|
|
) for cp in self.param('custom_properties')
|
|
|
|
|
] if self.param('custom_properties') is not None else None
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def update_check(self, entity):
|
|
|
|
|
def check_cpu_pinning():
|
|
|
|
|
if self.param('cpu_pinning'):
|
|
|
|
|
current = []
|
|
|
|
|
if entity.cpu.cpu_tune:
|
|
|
|
|
current = [(str(pin.cpu_set), int(pin.vcpu)) for pin in entity.cpu.cpu_tune.vcpu_pins]
|
|
|
|
|
passed = [(str(pin['cpu']), int(pin['vcpu'])) for pin in self.param('cpu_pinning')]
|
|
|
|
|
return sorted(current) == sorted(passed)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def check_custom_properties():
|
|
|
|
|
if self.param('custom_properties'):
|
|
|
|
|
current = []
|
|
|
|
|
if entity.custom_properties:
|
|
|
|
|
current = [(cp.name, cp.regexp, str(cp.value)) for cp in entity.custom_properties]
|
|
|
|
|
passed = [(cp.get('name'), cp.get('regexp'), str(cp.get('value'))) for cp in self.param('custom_properties')]
|
|
|
|
|
return sorted(current) == sorted(passed)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
cpu_mode = getattr(entity.cpu, 'mode')
|
|
|
|
|
return (
|
|
|
|
|
check_cpu_pinning() and
|
|
|
|
|
check_custom_properties() and
|
|
|
|
|
equal(self.param('cluster'), get_link_name(self._connection, entity.cluster)) and equal(convert_to_bytes(self.param('memory')), entity.memory) and
|
|
|
|
|
equal(convert_to_bytes(self.param('memory_guaranteed')), entity.memory_policy.guaranteed) and
|
|
|
|
|
equal(convert_to_bytes(self.param('memory_max')), entity.memory_policy.max) and
|
|
|
|
|
equal(self.param('cpu_cores'), entity.cpu.topology.cores) and
|
|
|
|
|
equal(self.param('cpu_sockets'), entity.cpu.topology.sockets) and
|
|
|
|
|
equal(self.param('cpu_threads'), entity.cpu.topology.threads) and
|
|
|
|
|
equal(self.param('cpu_mode'), str(cpu_mode) if cpu_mode else None) and
|
|
|
|
|
equal(self.param('type'), str(entity.type)) and
|
|
|
|
|
equal(self.param('operating_system'), str(entity.os.type)) and
|
|
|
|
|
equal(self.param('boot_menu'), entity.bios.boot_menu.enabled) and
|
|
|
|
|
equal(self.param('soundcard_enabled'), entity.soundcard_enabled) and
|
|
|
|
|
equal(self.param('smartcard_enabled'), entity.display.smartcard_enabled) and
|
|
|
|
|
equal(self.param('io_threads_enabled'), bool(entity.io.threads)) and
|
|
|
|
|
equal(self.param('ballooning_enabled'), entity.memory_policy.ballooning) and
|
|
|
|
|
equal(self.param('serial_console'), entity.console.enabled) and
|
|
|
|
|
equal(self.param('usb_support'), entity.usb.enabled) and
|
|
|
|
|
equal(self.param('sso'), True if entity.sso.methods else False) and
|
|
|
|
@ -946,7 +1083,10 @@ class VmsModule(BaseModule):
|
|
|
|
|
equal(self.param('comment'), entity.comment) and
|
|
|
|
|
equal(self.param('timezone'), getattr(entity.time_zone, 'name', None)) and
|
|
|
|
|
equal(self.param('serial_policy'), str(getattr(entity.serial_number, 'policy', None))) and
|
|
|
|
|
equal(self.param('serial_policy_value'), getattr(entity.serial_number, 'value', None))
|
|
|
|
|
equal(self.param('serial_policy_value'), getattr(entity.serial_number, 'value', None)) and
|
|
|
|
|
equal(self.param('placement_policy'), str(entity.placement_policy.affinity)) and
|
|
|
|
|
equal(self.param('rng_device'), str(entity.rng_device.source) if entity.rng_device else None) and
|
|
|
|
|
self.param('host') in [self._connection.follow_link(host).name for host in entity.placement_policy.hosts]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def pre_create(self, entity):
|
|
|
|
@ -956,12 +1096,13 @@ class VmsModule(BaseModule):
|
|
|
|
|
self._module.params['template'] = 'Blank'
|
|
|
|
|
|
|
|
|
|
def post_update(self, entity):
|
|
|
|
|
self.post_create(entity)
|
|
|
|
|
self.post_present(entity)
|
|
|
|
|
|
|
|
|
|
def post_create(self, entity):
|
|
|
|
|
def post_present(self, entity):
|
|
|
|
|
# After creation of the VM, attach disks and NICs:
|
|
|
|
|
self.changed = self.__attach_disks(entity)
|
|
|
|
|
self.changed = self.__attach_nics(entity)
|
|
|
|
|
self.changed = self.__attach_watchdog(entity)
|
|
|
|
|
|
|
|
|
|
def pre_remove(self, entity):
|
|
|
|
|
# Forcibly stop the VM, if it's not in DOWN state:
|
|
|
|
@ -1175,6 +1316,36 @@ class VmsModule(BaseModule):
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def __attach_watchdog(self, entity):
|
|
|
|
|
watchdogs_service = self._service.service(entity.id).watchdogs_service()
|
|
|
|
|
watchdog = self.param('watchdog')
|
|
|
|
|
if watchdog is not None:
|
|
|
|
|
current_watchdog = next(iter(watchdogs_service.list()), None)
|
|
|
|
|
if watchdog.get('model') is None and current_watchdog:
|
|
|
|
|
watchdogs_service.watchdog_service(current_watchdog.id).remove()
|
|
|
|
|
return True
|
|
|
|
|
elif watchdog.get('model') is not None and current_watchdog is None:
|
|
|
|
|
watchdogs_service.add(
|
|
|
|
|
otypes.Watchdog(
|
|
|
|
|
model=otypes.WatchdogModel(watchdog.get('model').lower()),
|
|
|
|
|
action=otypes.WatchdogAction(watchdog.get('action')),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return True
|
|
|
|
|
elif current_watchdog is not None:
|
|
|
|
|
if (
|
|
|
|
|
str(current_watchdog.model).lower() != watchdog.get('model').lower() or
|
|
|
|
|
str(current_watchdog.action).lower() != watchdog.get('action').lower()
|
|
|
|
|
):
|
|
|
|
|
watchdogs_service.watchdog_service(current_watchdog.id).update(
|
|
|
|
|
otypes.Watchdog(
|
|
|
|
|
model=otypes.WatchdogModel(watchdog.get('model')),
|
|
|
|
|
action=otypes.WatchdogAction(watchdog.get('action')),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def __attach_nics(self, entity):
|
|
|
|
|
# Attach NICs to VM, if specified:
|
|
|
|
|
nics_service = self._service.service(entity.id).nics_service()
|
|
|
|
@ -1492,6 +1663,7 @@ def main():
|
|
|
|
|
disks=dict(type='list', default=[]),
|
|
|
|
|
memory=dict(type='str'),
|
|
|
|
|
memory_guaranteed=dict(type='str'),
|
|
|
|
|
memory_max=dict(type='str'),
|
|
|
|
|
cpu_sockets=dict(type='int'),
|
|
|
|
|
cpu_cores=dict(type='int'),
|
|
|
|
|
cpu_shares=dict(type='int'),
|
|
|
|
@ -1550,6 +1722,16 @@ def main():
|
|
|
|
|
vmware=dict(type='dict'),
|
|
|
|
|
xen=dict(type='dict'),
|
|
|
|
|
kvm=dict(type='dict'),
|
|
|
|
|
cpu_mode=dict(type='str'),
|
|
|
|
|
placement_policy=dict(type='str'),
|
|
|
|
|
cpu_pinning=dict(type='list'),
|
|
|
|
|
soundcard_enabled=dict(type='bool', default=None),
|
|
|
|
|
smartcard_enabled=dict(type='bool', default=None),
|
|
|
|
|
io_threads_enabled=dict(type='bool', default=None),
|
|
|
|
|
ballooning_enabled=dict(type='bool', default=None),
|
|
|
|
|
rng_device=dict(type='str'),
|
|
|
|
|
custom_properties=dict(type='list'),
|
|
|
|
|
watchdog=dict(type='dict'),
|
|
|
|
|
)
|
|
|
|
|
module = AnsibleModule(
|
|
|
|
|
argument_spec=argument_spec,
|
|
|
|
@ -1590,6 +1772,7 @@ def main():
|
|
|
|
|
clone=module.params['clone'],
|
|
|
|
|
clone_permissions=module.params['clone_permissions'],
|
|
|
|
|
)
|
|
|
|
|
vms_module.post_present(vm)
|
|
|
|
|
|
|
|
|
|
# Run the VM if it was just created, else don't run it:
|
|
|
|
|
if state == 'running':
|
|
|
|
@ -1644,6 +1827,7 @@ def main():
|
|
|
|
|
action_condition=lambda vm: vm.status == otypes.VmStatus.UP,
|
|
|
|
|
wait_condition=lambda vm: vm.status == otypes.VmStatus.UP,
|
|
|
|
|
)
|
|
|
|
|
ret['changed'] = vms_module.changed
|
|
|
|
|
elif state == 'stopped':
|
|
|
|
|
if module.params['xen'] or module.params['kvm'] or module.params['vmware']:
|
|
|
|
|
vms_module.changed = import_vm(module, connection)
|
|
|
|
|