Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
major_changes:
- Support HyperCore update to arbitrary version, even if it is not listed under available updates.
(https://github.com/ScaleComputing/HyperCoreAnsibleCollection/pull/364)
4 changes: 3 additions & 1 deletion examples/version_update_single_node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
check_mode: true

vars:
desired_version: 9.2.22.212325
desired_version: 9.5.5.219383
force_update: false

tasks:
- name: Show desired_version
Expand Down Expand Up @@ -36,3 +37,4 @@
name: scale_computing.hypercore.version_update_single_node
vars:
version_update_single_node_desired_version: "{{ desired_version }}"
version_update_single_node_force_update: "{{ force_update }}"
6 changes: 6 additions & 0 deletions plugins/module_utils/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ class AuthError(ScaleComputingError):
pass


class InvalidModuleParam(ScaleComputingError):
def __init__(self, message: str):
self.message = message
super(InvalidModuleParam, self).__init__(self.message)


class UnexpectedAPIResponse(ScaleComputingError):
def __init__(self, response: Request):
self.message = "Unexpected response - {0} {1}".format(
Expand Down
10 changes: 8 additions & 2 deletions plugins/module_utils/hypercore_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,15 @@ def get(
)
return cls.from_hypercore(update)

def apply(self, rest_client: RestClient, check_mode: bool = False) -> TypedTaskTag:
@classmethod
def apply_update(
cls: type["Update"],
rest_client: RestClient,
version: str,
check_mode: bool = False,
) -> TypedTaskTag:
return rest_client.create_record(
f"/rest/v1/Update/{self.uuid}/apply", payload=None, check_mode=check_mode
f"/rest/v1/Update/{version}/apply", payload=None, check_mode=check_mode
)


Expand Down
1 change: 1 addition & 0 deletions plugins/modules/dns_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ def build_entry_list(
if module_entry_list is None:
return api_entry_list, False

new_entry_list = [] # make pylint happy
if module_entry_list is not None:
if state == "set":
new_entry_list = module_entry_list
Expand Down
51 changes: 42 additions & 9 deletions plugins/modules/version_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
- Hypercore version update to be installed on the cluster.
type: str
required: true
force_update:
description:
- Upgrade the HyperCore cluster to the requested version,
even if requested version is not listed under available versions of the HyperCore cluster.
type: bool
default: false
notes:
- C(check_mode) is not supported.
"""
Expand All @@ -51,15 +57,19 @@
type: dict
contains:
uuid:
description: Unique identifier in format major_version.minor_version.revision.build_id
description: Unique identifier in format major_version.minor_version.revision.build_id.
type: str
sample: 9.2.11.210763
description:
description: Human-readable name for the update
description: |
Human-readable name for the update.
Empty if I(force_update=true).
type: str
sample: 9.2.11 General Availability
change_log:
description: Description of all changes that are in this update, in HTML format
description: |
Description of all changes that are in this update, in HTML format.
Empty if I(force_update=true).
type: str
sample: ...Please allow between 20-40 minutes per node for the update to complete...
build_id:
Expand All @@ -79,7 +89,9 @@
type: int
sample: 11
timestamp:
description: Unix timestamp when the update was released
description: |
Unix timestamp when the update was released.
Value of 0 is returned if I(force_update=true).
type: int
sample: 0
"""
Expand All @@ -99,7 +111,8 @@ def run(
module: AnsibleModule, rest_client: RestClient
) -> Tuple[bool, Optional[TypedUpdateToAnsible], Dict[Any, Any]]:
cluster = Cluster.get(rest_client)
if cluster.icos_version == module.params["icos_version"]:
new_icos_version = module.params["icos_version"]
if cluster.icos_version == new_icos_version:
return (
False,
None,
Expand All @@ -108,14 +121,33 @@ def run(
after=dict(icos_version=cluster.icos_version),
),
)
update = Update.get(rest_client, module.params["icos_version"], must_exist=True)
update.apply(rest_client) # type: ignore
update = None
if module.params["force_update"]:
if len(new_icos_version.split(".")) != 4:
msg = f"HyperCore version must be in format 'major_version.minor_version.revision.build_id' - value {new_icos_version} is not valid."
raise errors.InvalidModuleParam(msg)
update = Update(
uuid=new_icos_version,
description="",
change_log="",
build_id=new_icos_version.split(".")[3],
major_version=new_icos_version.split(".")[0],
minor_version=new_icos_version.split(".")[1],
revision=new_icos_version.split(".")[2],
timestamp=0,
)
else:
# check the requested version is listed under available versions
update = Update.get(rest_client, new_icos_version, must_exist=True)
if not isinstance(update, Update):
raise AssertionError("update is not of type Update") # mypy helper
Update.apply_update(rest_client, new_icos_version)
return (
True,
update.to_ansible(), # type: ignore
update.to_ansible(),
dict(
before=dict(icos_version=cluster.icos_version),
after=dict(icos_version=update.uuid), # type: ignore
after=dict(icos_version=new_icos_version),
),
)

Expand All @@ -126,6 +158,7 @@ def main() -> None:
argument_spec=dict(
arguments.get_spec("cluster_instance"),
icos_version=dict(type="str", required=True),
force_update=dict(type="bool", default=False),
),
)

Expand Down
1 change: 1 addition & 0 deletions roles/version_update_single_node/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
version_update_single_node_shutdown_wait_time: "{{ scale_computing_hypercore_shutdown_wait_time | default(300) }}"
version_update_single_node_shutdown_tags: "{{ scale_computing_hypercore_shutdown_tags | default([]) }}"
version_update_single_node_force_update: false
# renamed variables - if new name is not present, use deprecated name as default value
version_update_single_node_shutdown_vms: "{{ scale_computing_hypercore_shutdown_vms | default(omit) }}"
version_update_single_node_restart_vms: "{{ scale_computing_hypercore_restart_vms | default(omit) }}"
6 changes: 6 additions & 0 deletions roles/version_update_single_node/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ argument_specs:
- After wait time expires a force shutdown is issued. Force shutdown can corrupt VM disk data.
default: 300
type: int
version_update_single_node_force_update:
description:
- Upgrade the HyperCore cluster to the requested version,
even if requested version is not listed under available versions of the HyperCore cluster.
default: false
type: bool
# -------------
# Renamed/deprecated vars
scale_computing_hypercore_desired_version:
Expand Down
5 changes: 4 additions & 1 deletion roles/version_update_single_node/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
msg: >-
Requested update {{ version_update_single_node_desired_version }} is not
in version_update_single_node_available_updates {{ version_update_single_node_available_updates.records | map(attribute='uuid') | list }}
when: not version_update_single_node_desired_version in (version_update_single_node_available_updates.records | map(attribute='uuid') | list)
when:
- not version_update_single_node_force_update
- not version_update_single_node_desired_version in (version_update_single_node_available_updates.records | map(attribute='uuid') | list)

- name: Get all available running VMs
scale_computing.hypercore.vm_info:
Expand All @@ -69,6 +71,7 @@
- name: Update single-node system
scale_computing.hypercore.version_update:
icos_version: "{{ version_update_single_node_desired_version }}"
force_update: "{{ version_update_single_node_force_update }}"
register: version_update_single_node_update_result

- name: Check update status
Expand Down
14 changes: 2 additions & 12 deletions tests/unit/plugins/module_utils/test_hypercore_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,18 +278,8 @@ def test_update_equal_false(self):
assert update1 != update2

def test_apply_update(self, rest_client):
update = Update(
uuid="9.2.11.210763",
description="9.1.11 General Availability",
change_log="...Please allow between 20-40 minutes per node for the update to complete...",
build_id=210763,
major_version=9,
minor_version=2,
revision=11,
timestamp=0,
)

update.apply(rest_client)
new_icos_version = "9.2.11.210763"
Update.apply_update(rest_client, new_icos_version)

rest_client.create_record.assert_called_with(
"/rest/v1/Update/9.2.11.210763/apply", payload=None, check_mode=False
Expand Down
Loading