From 8c63a67b1336b435dc586fd74beeff2a458aa6d2 Mon Sep 17 00:00:00 2001 From: Ignacio Penas Fernandez <11061525+ignacio-penas@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:49:34 +0100 Subject: [PATCH] fix: Fixed update process for K8s NuvlaEdges. * fix: Update K8s validation node. * fix: Update K8s validation node. --- conf/targets/ubuntu_vm_k8s.toml | 4 ++-- poetry.lock | 10 +++++----- validation_framework/deployer/coe/coe_base.py | 4 ++-- validation_framework/deployer/coe/docker.py | 6 +++--- validation_framework/deployer/coe/kubernetes.py | 17 ++++++++++------- validation_framework/deployer/engine_handler.py | 6 +++--- .../test_basic_app_deployments.py | 3 +-- .../nuvla_operations/test_engine_reboot.py | 2 -- .../nuvla_operations/test_ssh_management.py | 3 +-- .../tests/nuvla_operations/test_update.py | 15 ++++++++++++++- .../validators/validation_base.py | 6 ++++-- 11 files changed, 45 insertions(+), 31 deletions(-) diff --git a/conf/targets/ubuntu_vm_k8s.toml b/conf/targets/ubuntu_vm_k8s.toml index c05ad2b..793c7e3 100644 --- a/conf/targets/ubuntu_vm_k8s.toml +++ b/conf/targets/ubuntu_vm_k8s.toml @@ -4,12 +4,12 @@ alias = "ubuntu_VM" coe = "kubernetes" # Network data -address = "194.182.163.87" +address = "85.217.161.47" port = 22 hostname = "" # Naming data -user = "ubuntu" +user = "root" # Security data pub_key_path = "~/.ssh/id_rsa.pub" diff --git a/poetry.lock b/poetry.lock index 0348ae0..5d46d67 100644 --- a/poetry.lock +++ b/poetry.lock @@ -347,20 +347,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "fabric" diff --git a/validation_framework/deployer/coe/coe_base.py b/validation_framework/deployer/coe/coe_base.py index 97185eb..8a9c105 100644 --- a/validation_framework/deployer/coe/coe_base.py +++ b/validation_framework/deployer/coe/coe_base.py @@ -100,11 +100,11 @@ def engine_running(self) -> bool: pass @abstractmethod - def remove_engine(self): + def remove_engine(self, uuid: NuvlaUUID = None): pass @abstractmethod - def purge_engine(self): + def purge_engine(self, uuid: NuvlaUUID = None): pass @abstractmethod diff --git a/validation_framework/deployer/coe/docker.py b/validation_framework/deployer/coe/docker.py index bcbde47..6cee200 100644 --- a/validation_framework/deployer/coe/docker.py +++ b/validation_framework/deployer/coe/docker.py @@ -179,7 +179,7 @@ def engine_running(self) -> bool: result: Result = self.device.run_command(f'docker ps | grep {cte.PROJECT_NAME}') return result.stdout.strip() != '' - def remove_engine(self): + def remove_engine(self, uuid: NuvlaUUID = None): """ Removes docker containers, services, volumes and networks from the device :return: None @@ -205,9 +205,9 @@ def get_coe_type(self): def finish_tasks(self): pass - def purge_engine(self): + def purge_engine(self, uuid: NuvlaUUID = None): self.stop_engine() - self.remove_engine() + self.remove_engine(uuid) def download_files(self, source, version) -> list[str]: self.engine_folder = cte.ROOT_PATH + cte.ENGINE_PATH + version diff --git a/validation_framework/deployer/coe/kubernetes.py b/validation_framework/deployer/coe/kubernetes.py index fa0dddf..51276aa 100644 --- a/validation_framework/deployer/coe/kubernetes.py +++ b/validation_framework/deployer/coe/kubernetes.py @@ -48,12 +48,12 @@ def start_engine(self, idparts = uuid.split('/') self.nuvla_uuid = idparts[1] - add_repo_cmd = f'sudo helm repo add {cte.NUVLAEDGE_KUBE_LOCAL_REPO_NAME} {cte.NUVLAEDGE_KUBE_REPO}' + add_repo_cmd = f'helm repo add {cte.NUVLAEDGE_KUBE_LOCAL_REPO_NAME} {cte.NUVLAEDGE_KUBE_REPO}' result: Result = self.device.run_sudo_command(add_repo_cmd, envs=_KUBECONFIG_ENV) if result.failed: self.logger.error(f'Could not add repo to helm {cte.NUVLAEDGE_KUBE_REPO}: {result.stderr}') - update_repo_cmd = f'sudo helm repo update nuvlaedge {cte.NUVLAEDGE_KUBE_LOCAL_REPO_NAME}' + update_repo_cmd = f'helm repo update nuvlaedge {cte.NUVLAEDGE_KUBE_LOCAL_REPO_NAME}' result: Result = self.device.run_sudo_command(update_repo_cmd, envs=_KUBECONFIG_ENV) if result.failed: self.logger.error(f'Could not update helm repo {cte.NUVLAEDGE_KUBE_LOCAL_REPO_NAME}: {result.stderr}') @@ -188,21 +188,24 @@ def finish_tasks(self): self.logger.debug("Waiting for credentials check thread to close") self.cred_check_thread.join(50) - def remove_engine(self): + def remove_engine(self, uuid: NuvlaUUID = None): self.logger.debug(f'Removing engine in device {self.device}') self.finish_tasks() + if not self.nuvla_uuid: + self.nuvla_uuid = uuid + ne_id = self.nuvla_uuid.split('/')[1] self.namespaces_running = self.__get_namespaces_running() commands: list = ['sudo kubectl delete ' 'clusterrolebindings.rbac.authorization.k8s.io ' 'nuvla-crb ' - f'nuvlaedge-service-account-cluster-role-binding-{self.nuvla_uuid}'] + f'nuvlaedge-service-account-cluster-role-binding-{ne_id}'] for namespace in self.namespaces_running: if namespace.__contains__('kube') or namespace == 'default': continue commands.append(f'sudo kubectl delete ns {namespace}') - commands.append(f'sudo helm uninstall {namespace}') + commands.append(f'helm uninstall {namespace}') for cmd in commands: try: @@ -230,13 +233,13 @@ def peripherals_running(self, peripherals: set) -> bool: peripherals.remove(res.group(1)) return not bool(peripherals) - def purge_engine(self): + def purge_engine(self, uuid: NuvlaUUID = None): """ This will remove all pods and namespaces for kubernetes :return: """ self.stop_engine() - self.remove_engine() + self.remove_engine(uuid) def __get_current_nuvlaedge_namespace_running(self): get_curr_nuvlaedge_namespace_cmd = ('sudo kubectl get namespaces -o json | jq ' diff --git a/validation_framework/deployer/engine_handler.py b/validation_framework/deployer/engine_handler.py index 7dc7799..70d7745 100644 --- a/validation_framework/deployer/engine_handler.py +++ b/validation_framework/deployer/engine_handler.py @@ -87,7 +87,7 @@ def start_engine(self, nuvlaedge_uuid: NuvlaUUID, if remove_old_installation: # 1. - Clean target self.logger.info('Removing possible old installations of NuvlaEdge') - self.coe.purge_engine() + self.coe.purge_engine(nuvlaedge_uuid) # 2. Start Engine self.logger.info('Download NuvlaEdge related files and images') @@ -99,7 +99,7 @@ def get_system_up_time_in_engine(self) -> float: def restart_engine(self) -> Result: return self.coe.restart_system() - def stop_engine(self, retrieve_logs: bool = False) -> bool: + def stop_engine(self, retrieve_logs: bool = False, uuid: NuvlaUUID = None) -> bool: """ :return: @@ -112,7 +112,7 @@ def stop_engine(self, retrieve_logs: bool = False) -> bool: if retrieve_logs: self.coe.get_engine_logs() - self.coe.purge_engine() + self.coe.purge_engine(uuid) def check_if_peripherals_running(self, peripherals: set) -> bool: """ diff --git a/validation_framework/validators/tests/nuvla_operations/test_basic_app_deployments.py b/validation_framework/validators/tests/nuvla_operations/test_basic_app_deployments.py index 4ec5168..22df126 100644 --- a/validation_framework/validators/tests/nuvla_operations/test_basic_app_deployments.py +++ b/validation_framework/validators/tests/nuvla_operations/test_basic_app_deployments.py @@ -2,14 +2,13 @@ """ import time -import unittest from nuvla.api.resources import Deployment from validation_framework.validators import ValidationBase from validation_framework.validators.tests.nuvla_operations import validator from validation_framework.common.constants import DEFAULT_DEPLOYMENTS_TIMEOUT -from nuvla.api.models import CimiResponse, CimiResource, CimiCollection +from nuvla.api.models import CimiResource, CimiCollection @validator('BasicAppDeployment') diff --git a/validation_framework/validators/tests/nuvla_operations/test_engine_reboot.py b/validation_framework/validators/tests/nuvla_operations/test_engine_reboot.py index 4b5d515..65ca16e 100644 --- a/validation_framework/validators/tests/nuvla_operations/test_engine_reboot.py +++ b/validation_framework/validators/tests/nuvla_operations/test_engine_reboot.py @@ -7,8 +7,6 @@ from validation_framework.validators.tests.nuvla_operations import validator from nuvla.api.models import CimiResource, CimiResponse import time -from fabric import Result -from pprint import pprint as pp @validator('EngineReboot') diff --git a/validation_framework/validators/tests/nuvla_operations/test_ssh_management.py b/validation_framework/validators/tests/nuvla_operations/test_ssh_management.py index 6d3bbee..998f9c6 100644 --- a/validation_framework/validators/tests/nuvla_operations/test_ssh_management.py +++ b/validation_framework/validators/tests/nuvla_operations/test_ssh_management.py @@ -2,8 +2,7 @@ """ import time -from pprint import pprint as pp -from nuvla.api.models import CimiResource, CimiResponse, CimiCollection +from nuvla.api.models import CimiResource, CimiResponse from validation_framework.validators.tests.nuvla_operations import validator from validation_framework.common.constants import DEFAULT_JOBS_TIMEOUT diff --git a/validation_framework/validators/tests/nuvla_operations/test_update.py b/validation_framework/validators/tests/nuvla_operations/test_update.py index 165a841..8220aa9 100644 --- a/validation_framework/validators/tests/nuvla_operations/test_update.py +++ b/validation_framework/validators/tests/nuvla_operations/test_update.py @@ -11,6 +11,7 @@ from nuvla.api import Api as NuvlaClient from nuvla.api.models import CimiResource, CimiResponse +from packaging.version import Version from pydantic import BaseModel, ConfigDict from validation_framework.common.constants import DEFAULT_JOBS_TIMEOUT @@ -29,6 +30,7 @@ GH_API_URL = "https://api.github.com/repos/{repo}/releases" NUVLA_RELEASE_ENDPOINT = "https://nuvla.io/api/nuvlabox-release" +MINIMUM_K8S_VERSION = "2.18.0" @dataclass class FutureResult: @@ -45,10 +47,19 @@ def __init__(self, *args, **kwargs): self.engines: dict[str, EngineHandler] = {} self.uuids: dict[str, str] = {} + self.is_skip: bool = False def run_update(self, origin, target): + self.logger.info(f"Starting update from {origin}(Minimum {MINIMUM_K8S_VERSION}) to {target}") + self.logger.info("Engine keys are: " + str(self.engines.keys())) self.custom_setup(origin, target) engine = self.engines[origin] + + if Version(origin) < Version(MINIMUM_K8S_VERSION) and engine.coe_type == 'kubernetes': + self.logger.info(f"Skipping {origin} to {target} update. Minimum NuvlaEdge version for Kubernetes validation update is {MINIMUM_K8S_VERSION}") + self.is_skip = True + self.skipTest("Minimum NuvlaEdge version for Kubernetes validation update is not met") + uuid = self.uuids[origin] self.wait_for_commissioned(engine=engine, uuid=NuvlaUUID(uuid)) @@ -196,7 +207,9 @@ def setUp(self) -> None: self.nuvla_client: NuvlaClient = NuvlaClient(reauthenticate=True) self.nuvla_client.login_apikey(self.nuvla_api_key, self.nuvla_api_secret) - + def tearDown(self) -> None: + if not self.is_skip: + super().tearDown() def underscore_to_hyphen(field_name: str) -> str: """ diff --git a/validation_framework/validators/validation_base.py b/validation_framework/validators/validation_base.py index 5aefb40..1ea7d29 100644 --- a/validation_framework/validators/validation_base.py +++ b/validation_framework/validators/validation_base.py @@ -79,6 +79,7 @@ def parametrize(testcase_class, for release in releases: method_name = f"test_update_{release[0].replace(".", "_")}_to_{nuvlaedge_branch}" method = create_update_method(release[0], nuvlaedge_branch) + logging.info("Adding method %s to %s", method_name, testcase_class) setattr(testcase_class, method_name, method) setattr(testcase_class, 'release_id', release[1]) @@ -314,5 +315,6 @@ def tearDown(self) -> None: self.retrieve_logs = True self.logger.error(f'Test failed with exception: {self.failureException}') - self.engine_handler.stop_engine(retrieve_logs=self.retrieve_logs) - self.remove_nuvlaedge_from_nuvla() + if self.engine_handler and self.uuid: + self.engine_handler.stop_engine(retrieve_logs=self.retrieve_logs, uuid=self.uuid) + self.remove_nuvlaedge_from_nuvla()