mirror of
https://github.com/kubevirt/kubevirt.core.git
synced 2026-03-27 03:13:10 +00:00
Merge pull request #124 from 0xFelix/run-strategy
feat(kubevirt_vm): Add support for RunStrategy
This commit is contained in:
42
examples/play-create-run-strategy.yml
Normal file
42
examples/play-create-run-strategy.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
- name: Playbook creating a virtual machine with multus network
|
||||
hosts: localhost
|
||||
tasks:
|
||||
- name: Create VM
|
||||
kubevirt.core.kubevirt_vm:
|
||||
state: present
|
||||
name: testvm
|
||||
namespace: default
|
||||
labels:
|
||||
app: test
|
||||
instancetype:
|
||||
name: u1.medium
|
||||
preference:
|
||||
name: fedora
|
||||
run_strategy: Manual
|
||||
spec:
|
||||
domain:
|
||||
devices:
|
||||
interfaces:
|
||||
- name: default
|
||||
masquerade: {}
|
||||
- name: bridge-network
|
||||
bridge: {}
|
||||
networks:
|
||||
- name: default
|
||||
pod: {}
|
||||
- name: bridge-network
|
||||
multus:
|
||||
networkName: kindexgw
|
||||
volumes:
|
||||
- containerDisk:
|
||||
image: quay.io/containerdisks/fedora:latest
|
||||
name: containerdisk
|
||||
- cloudInitNoCloud:
|
||||
userData: |-
|
||||
#cloud-config
|
||||
# The default username is: fedora
|
||||
ssh_authorized_keys:
|
||||
- ssh-ed25519 AAAA...
|
||||
name: cloudinit
|
||||
wait: true
|
||||
@@ -61,8 +61,21 @@ options:
|
||||
running:
|
||||
description:
|
||||
- Specify whether the C(VirtualMachine) should be running or not.
|
||||
- Mutually exclusive with O(run_strategy).
|
||||
- Defaults to O(running=yes) when O(running) and O(run_strategy) are not set.
|
||||
type: bool
|
||||
default: yes
|
||||
run_strategy:
|
||||
description:
|
||||
- Specify the C(RunStrategy) of the C(VirtualMachine).
|
||||
- Mutually exclusive with O(running).
|
||||
type: str
|
||||
choices:
|
||||
- Always
|
||||
- Halted
|
||||
- Manual
|
||||
- RerunOnFailure
|
||||
- Once
|
||||
version_added: 2.0.0
|
||||
instancetype:
|
||||
description:
|
||||
- Specify the C(Instancetype) matcher of the C(VirtualMachine).
|
||||
@@ -280,6 +293,13 @@ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions imp
|
||||
CoreException,
|
||||
)
|
||||
|
||||
WAIT_CONDITION_READY = {"type": "Ready", "status": True}
|
||||
WAIT_CONDITION_VMI_NOT_EXISTS = {
|
||||
"type": "Ready",
|
||||
"status": False,
|
||||
"reason": "VMINotExists",
|
||||
}
|
||||
|
||||
|
||||
def create_vm(params: Dict) -> Dict:
|
||||
"""
|
||||
@@ -292,7 +312,6 @@ def create_vm(params: Dict) -> Dict:
|
||||
"namespace": params["namespace"],
|
||||
},
|
||||
"spec": {
|
||||
"running": params["running"],
|
||||
"template": {"spec": {"domain": {"devices": {}}}},
|
||||
},
|
||||
}
|
||||
@@ -312,6 +331,12 @@ def create_vm(params: Dict) -> Dict:
|
||||
if template_metadata:
|
||||
vm["spec"]["template"]["metadata"] = template_metadata
|
||||
|
||||
if (run_strategy := params.get("run_strategy")) is not None:
|
||||
vm["spec"]["runStrategy"] = run_strategy
|
||||
else:
|
||||
vm["spec"]["running"] = (
|
||||
running if (running := params.get("running")) is not None else True
|
||||
)
|
||||
if (instancetype := params.get("instancetype")) is not None:
|
||||
vm["spec"]["instancetype"] = instancetype
|
||||
if (preference := params.get("preference")) is not None:
|
||||
@@ -324,6 +349,21 @@ def create_vm(params: Dict) -> Dict:
|
||||
return vm
|
||||
|
||||
|
||||
def set_wait_condition(module: AnsibleK8SModule) -> None:
|
||||
"""
|
||||
set_wait_condition sets the wait_condition to allow waiting for the ready
|
||||
state of the VirtualMachine depending on the module parameters running
|
||||
and run_strategy.
|
||||
"""
|
||||
if (
|
||||
module.params["running"] is False
|
||||
or (run_strategy := module.params["run_strategy"]) == "Halted"
|
||||
):
|
||||
module.params["wait_condition"] = WAIT_CONDITION_VMI_NOT_EXISTS
|
||||
elif run_strategy != "Manual":
|
||||
module.params["wait_condition"] = WAIT_CONDITION_READY
|
||||
|
||||
|
||||
def arg_spec() -> Dict:
|
||||
"""
|
||||
arg_spec defines the argument spec of this module.
|
||||
@@ -335,7 +375,10 @@ def arg_spec() -> Dict:
|
||||
"namespace": {"required": True},
|
||||
"annotations": {"type": "dict"},
|
||||
"labels": {"type": "dict"},
|
||||
"running": {"type": "bool", "default": True},
|
||||
"running": {"type": "bool"},
|
||||
"run_strategy": {
|
||||
"choices": ["Always", "Halted", "Manual", "RerunOnFailure", "Once"]
|
||||
},
|
||||
"instancetype": {"type": "dict"},
|
||||
"preference": {"type": "dict"},
|
||||
"data_volume_templates": {"type": "list", "elements": "dict"},
|
||||
@@ -376,6 +419,7 @@ def main() -> None:
|
||||
argument_spec=arg_spec(),
|
||||
mutually_exclusive=[
|
||||
("name", "generate_name"),
|
||||
("running", "run_strategy"),
|
||||
],
|
||||
required_one_of=[
|
||||
("name", "generate_name"),
|
||||
@@ -387,14 +431,7 @@ def main() -> None:
|
||||
module.params["resource_definition"] = create_vm(module.params)
|
||||
|
||||
# Set wait_condition to allow waiting for the ready state of the VirtualMachine
|
||||
if module.params["running"]:
|
||||
module.params["wait_condition"] = {"type": "Ready", "status": True}
|
||||
else:
|
||||
module.params["wait_condition"] = {
|
||||
"type": "Ready",
|
||||
"status": False,
|
||||
"reason": "VMINotExists",
|
||||
}
|
||||
set_wait_condition(module)
|
||||
|
||||
try:
|
||||
runner.run_module(module)
|
||||
|
||||
@@ -101,11 +101,27 @@ VM_DEFINITION_STOPPED = {
|
||||
},
|
||||
}
|
||||
|
||||
VM_DEFINITION_HALTED = {
|
||||
"apiVersion": "kubevirt.io/v1",
|
||||
"kind": "VirtualMachine",
|
||||
"metadata": {
|
||||
"name": "testvm",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": {
|
||||
"runStrategy": "Halted",
|
||||
"template": {
|
||||
"spec": {
|
||||
"domain": {"devices": {}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
MODULE_PARAMS_DEFAULT = {
|
||||
"api_version": "kubevirt.io/v1",
|
||||
"annotations": None,
|
||||
"labels": None,
|
||||
"running": True,
|
||||
"instancetype": None,
|
||||
"preference": None,
|
||||
"data_volume_templates": None,
|
||||
@@ -174,6 +190,12 @@ MODULE_PARAMS_STOPPED = MODULE_PARAMS_DEFAULT | {
|
||||
"running": False,
|
||||
}
|
||||
|
||||
MODULE_PARAMS_HALTED = MODULE_PARAMS_DEFAULT | {
|
||||
"name": "testvm",
|
||||
"namespace": "default",
|
||||
"run_strategy": "Halted",
|
||||
}
|
||||
|
||||
MODULE_PARAMS_DELETE = MODULE_PARAMS_DEFAULT | {
|
||||
"name": "testvm",
|
||||
"namespace": "default",
|
||||
@@ -183,24 +205,37 @@ MODULE_PARAMS_DELETE = MODULE_PARAMS_DEFAULT | {
|
||||
|
||||
K8S_MODULE_PARAMS_CREATE = MODULE_PARAMS_CREATE | {
|
||||
"generate_name": None,
|
||||
"running": None,
|
||||
"run_strategy": None,
|
||||
"resource_definition": VM_DEFINITION_CREATE,
|
||||
"wait_condition": {"type": "Ready", "status": True},
|
||||
}
|
||||
|
||||
K8S_MODULE_PARAMS_RUNNING = MODULE_PARAMS_RUNNING | {
|
||||
"generate_name": None,
|
||||
"run_strategy": None,
|
||||
"resource_definition": VM_DEFINITION_RUNNING,
|
||||
"wait_condition": {"type": "Ready", "status": True},
|
||||
}
|
||||
|
||||
K8S_MODULE_PARAMS_STOPPED = MODULE_PARAMS_STOPPED | {
|
||||
"generate_name": None,
|
||||
"run_strategy": None,
|
||||
"resource_definition": VM_DEFINITION_STOPPED,
|
||||
"wait_condition": {"type": "Ready", "status": False, "reason": "VMINotExists"},
|
||||
}
|
||||
|
||||
K8S_MODULE_PARAMS_HALTED = MODULE_PARAMS_HALTED | {
|
||||
"generate_name": None,
|
||||
"running": None,
|
||||
"resource_definition": VM_DEFINITION_HALTED,
|
||||
"wait_condition": {"type": "Ready", "status": False, "reason": "VMINotExists"},
|
||||
}
|
||||
|
||||
K8S_MODULE_PARAMS_DELETE = MODULE_PARAMS_DELETE | {
|
||||
"generate_name": None,
|
||||
"running": None,
|
||||
"run_strategy": None,
|
||||
"resource_definition": VM_DEFINITION_RUNNING,
|
||||
"wait_condition": {"type": "Ready", "status": True},
|
||||
}
|
||||
@@ -227,6 +262,12 @@ K8S_MODULE_PARAMS_DELETE = MODULE_PARAMS_DELETE | {
|
||||
VM_DEFINITION_STOPPED,
|
||||
"update",
|
||||
),
|
||||
(
|
||||
MODULE_PARAMS_HALTED,
|
||||
K8S_MODULE_PARAMS_HALTED,
|
||||
VM_DEFINITION_HALTED,
|
||||
"update",
|
||||
),
|
||||
(
|
||||
MODULE_PARAMS_DELETE,
|
||||
K8S_MODULE_PARAMS_DELETE,
|
||||
@@ -262,10 +303,15 @@ def test_module(mocker, module_params, k8s_module_params, vm_definition, method)
|
||||
|
||||
CREATE_VM_PARAMS = {
|
||||
"api_version": "kubevirt.io/v1",
|
||||
"running": True,
|
||||
"namespace": "default",
|
||||
}
|
||||
|
||||
CREATE_VM_PARAMS_RUN_STRATEGY = {
|
||||
"api_version": "kubevirt.io/v1",
|
||||
"namespace": "default",
|
||||
"run_strategy": "Manual",
|
||||
}
|
||||
|
||||
CREATE_VM_PARAMS_ANNOTATIONS = CREATE_VM_PARAMS | {
|
||||
"annotations": {"test": "test"},
|
||||
}
|
||||
@@ -341,6 +387,24 @@ CREATED_VM = {
|
||||
},
|
||||
}
|
||||
|
||||
CREATED_VM_RUN_STRATEGY = {
|
||||
"apiVersion": "kubevirt.io/v1",
|
||||
"kind": "VirtualMachine",
|
||||
"metadata": {
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": {
|
||||
"runStrategy": "Manual",
|
||||
"template": {
|
||||
"spec": {
|
||||
"domain": {
|
||||
"devices": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
CREATED_VM_LABELS = {
|
||||
"apiVersion": "kubevirt.io/v1",
|
||||
"kind": "VirtualMachine",
|
||||
@@ -528,6 +592,7 @@ CREATED_VM_SPECS = {
|
||||
"params,expected",
|
||||
[
|
||||
(CREATE_VM_PARAMS, CREATED_VM),
|
||||
(CREATE_VM_PARAMS_RUN_STRATEGY, CREATED_VM_RUN_STRATEGY),
|
||||
(CREATE_VM_PARAMS_ANNOTATIONS, CREATED_VM_ANNOTATIONS),
|
||||
(CREATE_VM_PARAMS_LABELS, CREATED_VM_LABELS),
|
||||
(CREATE_VM_PARAMS_INSTANCETYPE, CREATED_VM_INSTANCETYPE),
|
||||
@@ -540,3 +605,46 @@ CREATED_VM_SPECS = {
|
||||
)
|
||||
def test_create_vm(params, expected):
|
||||
assert kubevirt_vm.create_vm(params) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"params,expected",
|
||||
[
|
||||
({"running": None, "run_strategy": "Manual"}, {}),
|
||||
(
|
||||
{"running": None, "run_strategy": None},
|
||||
{"wait_condition": kubevirt_vm.WAIT_CONDITION_READY},
|
||||
),
|
||||
(
|
||||
{"running": True, "run_strategy": None},
|
||||
{"wait_condition": kubevirt_vm.WAIT_CONDITION_READY},
|
||||
),
|
||||
(
|
||||
{"running": None, "run_strategy": "Always"},
|
||||
{"wait_condition": kubevirt_vm.WAIT_CONDITION_READY},
|
||||
),
|
||||
(
|
||||
{"running": None, "run_strategy": "RerunOnFailure"},
|
||||
{"wait_condition": kubevirt_vm.WAIT_CONDITION_READY},
|
||||
),
|
||||
(
|
||||
{"running": None, "run_strategy": "Once"},
|
||||
{"wait_condition": kubevirt_vm.WAIT_CONDITION_READY},
|
||||
),
|
||||
(
|
||||
{"running": False, "run_strategy": None},
|
||||
{"wait_condition": kubevirt_vm.WAIT_CONDITION_VMI_NOT_EXISTS},
|
||||
),
|
||||
(
|
||||
{"running": None, "run_strategy": "Halted"},
|
||||
{"wait_condition": kubevirt_vm.WAIT_CONDITION_VMI_NOT_EXISTS},
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_set_wait_condition(mocker, params, expected):
|
||||
module = mocker.Mock()
|
||||
module.params = params
|
||||
|
||||
kubevirt_vm.set_wait_condition(module)
|
||||
|
||||
assert module.params == params | expected
|
||||
|
||||
Reference in New Issue
Block a user