From 9590d7486c05b62b973636ca2513e573e17fcfba Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Sun, 5 Sep 2021 15:25:00 +0000 Subject: [PATCH 01/13] add distro option --- src/vm-repair/azext_vm_repair/_help.py | 3 +++ src/vm-repair/azext_vm_repair/_params.py | 1 + src/vm-repair/azext_vm_repair/custom.py | 16 ++++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/_help.py b/src/vm-repair/azext_vm_repair/_help.py index 6b00d64c923..cb8e52db7be 100644 --- a/src/vm-repair/azext_vm_repair/_help.py +++ b/src/vm-repair/azext_vm_repair/_help.py @@ -22,6 +22,9 @@ - name: Create a repair VM and set the VM authentication text: > az vm repair create -g MyResourceGroup -n myVM --repair-username username --repair-password password!234 --verbose + - name: Create a repair VM of a specific distro + text: > + az vm repair create -g MyResourceGroup -n myVM --distro 'rhel|suse|ubuntu|centos|oracle' """ helps['vm repair restore'] = """ diff --git a/src/vm-repair/azext_vm_repair/_params.py b/src/vm-repair/azext_vm_repair/_params.py index 3714404e979..52049dd1b06 100644 --- a/src/vm-repair/azext_vm_repair/_params.py +++ b/src/vm-repair/azext_vm_repair/_params.py @@ -31,6 +31,7 @@ def load_arguments(self, _): c.argument('unlock_encrypted_vm', help='Option to auto-unlock encrypted VMs using current subscription auth.') c.argument('enable_nested', help='enable nested hyperv.') c.argument('associate_public_ip', help='Option to create repair vm with public ip') + c.argument('distro', help='Option to create repair vm from a specific linux distro (rhel|suse|ubuntu|centos|oracle)') with self.argument_context('vm repair restore') as c: c.argument('repair_vm_id', help='Repair VM resource id.') diff --git a/src/vm-repair/azext_vm_repair/custom.py b/src/vm-repair/azext_vm_repair/custom.py index d72b6607522..0833b4a6be0 100644 --- a/src/vm-repair/azext_vm_repair/custom.py +++ b/src/vm-repair/azext_vm_repair/custom.py @@ -38,7 +38,7 @@ logger = get_logger(__name__) -def create(cmd, vm_name, resource_group_name, repair_password=None, repair_username=None, repair_vm_name=None, copy_disk_name=None, repair_group_name=None, unlock_encrypted_vm=False, enable_nested=False, associate_public_ip=False): +def create(cmd, vm_name, resource_group_name, repair_password=None, repair_username=None, repair_vm_name=None, copy_disk_name=None, repair_group_name=None, unlock_encrypted_vm=False, enable_nested=False, associate_public_ip=False, distro='ubuntu'): # Init command helper object command = command_helper(logger, cmd, 'vm repair create') # Main command calling block @@ -54,8 +54,20 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern # Fetch OS image urn and set OS type for disk create if is_linux: - os_image_urn = "UbuntuLTS" + #os_image_urn = "UbuntuLTS" os_type = 'Linux' + if distro == 'rhel': + os_image_urn = 'RedHat:RHEL:7-RAW:latest' + elif distro == 'suse': + os_image_urn = 'SUSE:sles-15-sp2:gen1:latest' + elif distro == 'centos': + os_image_urn = 'OpenLogic:CentOS:7_9:latest' + elif distro == 'oracle': + os_image_urn = 'Oracle:Oracle-Linux:ol79:latest' + elif distro == 'ubuntu': + os_image_urn = "UbuntuLTS" + else: + os_image_urn = "UbuntuLTS" else: os_image_urn = _fetch_compatible_windows_os_urn(source_vm) os_type = 'Windows' From fc45502831f2bbe6a1504a433249c04ce6e196a8 Mon Sep 17 00:00:00 2001 From: imabedalghafer Date: Fri, 15 Oct 2021 13:49:07 +0000 Subject: [PATCH 02/13] added distro option to select the distro for recovery VM --- src/vm-repair/azext_vm_repair/_help.py | 4 +- src/vm-repair/azext_vm_repair/_params.py | 2 +- src/vm-repair/azext_vm_repair/custom.py | 16 ++---- src/vm-repair/azext_vm_repair/exceptions.py | 3 ++ src/vm-repair/azext_vm_repair/repair_utils.py | 52 ++++++++++++++++++- src/vm-repair/azext_vm_repair/telemetry.py | 2 +- 6 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/_help.py b/src/vm-repair/azext_vm_repair/_help.py index cb8e52db7be..7439973de60 100644 --- a/src/vm-repair/azext_vm_repair/_help.py +++ b/src/vm-repair/azext_vm_repair/_help.py @@ -22,9 +22,9 @@ - name: Create a repair VM and set the VM authentication text: > az vm repair create -g MyResourceGroup -n myVM --repair-username username --repair-password password!234 --verbose - - name: Create a repair VM of a specific distro + - name: Create a repair VM of a specific distro , a specific URN could also be provided text: > - az vm repair create -g MyResourceGroup -n myVM --distro 'rhel|suse|ubuntu|centos|oracle' + az vm repair create -g MyResourceGroup -n myVM --distro 'rhel7|suse12|ubuntu20|centos6|oracle8' """ helps['vm repair restore'] = """ diff --git a/src/vm-repair/azext_vm_repair/_params.py b/src/vm-repair/azext_vm_repair/_params.py index 52049dd1b06..eab9113a8b7 100644 --- a/src/vm-repair/azext_vm_repair/_params.py +++ b/src/vm-repair/azext_vm_repair/_params.py @@ -31,7 +31,7 @@ def load_arguments(self, _): c.argument('unlock_encrypted_vm', help='Option to auto-unlock encrypted VMs using current subscription auth.') c.argument('enable_nested', help='enable nested hyperv.') c.argument('associate_public_ip', help='Option to create repair vm with public ip') - c.argument('distro', help='Option to create repair vm from a specific linux distro (rhel|suse|ubuntu|centos|oracle)') + c.argument('distro', help='Option to create repair vm from a specific linux distro (rhel7|rhel8|suse12|ubuntu20|centos7|oracle7)') with self.argument_context('vm repair restore') as c: c.argument('repair_vm_id', help='Repair VM resource id.') diff --git a/src/vm-repair/azext_vm_repair/custom.py b/src/vm-repair/azext_vm_repair/custom.py index 0833b4a6be0..db1e046c412 100644 --- a/src/vm-repair/azext_vm_repair/custom.py +++ b/src/vm-repair/azext_vm_repair/custom.py @@ -32,7 +32,8 @@ _unlock_singlepass_encrypted_disk, _invoke_run_command, _check_hyperV_gen, - _get_cloud_init_script + _get_cloud_init_script, + _select_distro_linux ) from .exceptions import AzCommandError, SkuNotAvailableError, UnmanagedDiskCopyError, WindowsOsNotAvailableError, RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV, ScriptReturnsError logger = get_logger(__name__) @@ -56,18 +57,7 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern if is_linux: #os_image_urn = "UbuntuLTS" os_type = 'Linux' - if distro == 'rhel': - os_image_urn = 'RedHat:RHEL:7-RAW:latest' - elif distro == 'suse': - os_image_urn = 'SUSE:sles-15-sp2:gen1:latest' - elif distro == 'centos': - os_image_urn = 'OpenLogic:CentOS:7_9:latest' - elif distro == 'oracle': - os_image_urn = 'Oracle:Oracle-Linux:ol79:latest' - elif distro == 'ubuntu': - os_image_urn = "UbuntuLTS" - else: - os_image_urn = "UbuntuLTS" + os_image_urn = _select_distro_linux(distro) else: os_image_urn = _fetch_compatible_windows_os_urn(source_vm) os_type = 'Windows' diff --git a/src/vm-repair/azext_vm_repair/exceptions.py b/src/vm-repair/azext_vm_repair/exceptions.py index 718d566dfad..b2be73eab9a 100644 --- a/src/vm-repair/azext_vm_repair/exceptions.py +++ b/src/vm-repair/azext_vm_repair/exceptions.py @@ -30,3 +30,6 @@ class SkuDoesNotSupportHyperV(Exception): class ScriptReturnsError(Exception): """Raised when run script returns error""" + +class SuseNotAvailableError(Exception): + """Raised when SUSE image not available""" \ No newline at end of file diff --git a/src/vm-repair/azext_vm_repair/repair_utils.py b/src/vm-repair/azext_vm_repair/repair_utils.py index b77bccb409e..2074bad202a 100644 --- a/src/vm-repair/azext_vm_repair/repair_utils.py +++ b/src/vm-repair/azext_vm_repair/repair_utils.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- +from logging import Logger, log import subprocess import shlex import os @@ -16,7 +17,7 @@ from .encryption_types import Encryption -from .exceptions import AzCommandError, WindowsOsNotAvailableError, RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV +from .exceptions import AzCommandError, WindowsOsNotAvailableError, RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV,SuseNotAvailableError # pylint: disable=line-too-long, deprecated-method REPAIR_MAP_URL = 'https://raw.githubusercontent.com/Azure/repair-script-library/master/map.json' @@ -388,6 +389,55 @@ def _fetch_compatible_windows_os_urn(source_vm): logger.debug('Returning Urn 0: %s', urns[0]) return urns[0] +def _suse_image_selector(distro): + fetch_urn_command = 'az vm image list --publisher SUSE --offer {offer} --sku gen1 --verbose --all --query "[].urn | reverse(sort(@))" -o json'.format(offer=distro) + logger.info('Fetching compatible SUSE OS images from gallery...') + urns = loads(_call_az_command(fetch_urn_command)) + + #Raise exception when not finding SUSE image + if not urns: + raise SuseNotAvailableError() + + logger.debug('Fetched urns: \n%s', urns) + #Returning the first URN as it is the latest image with no special use like HPC or SAP + logger.debug('Return the first URN : %s' , urns[0]) + return urns[0] + +def _select_distro_linux(distro): + if distro == 'rhel6': + os_image_urn = 'RedHat:RHEL:6.10:latest' + elif distro == 'rhel7': + os_image_urn = 'RedHat:rhel-raw:7-raw:latest' + elif distro == 'rhel8': + os_image_urn = 'RedHat:rhel-raw:8-raw:latest' + elif distro == 'ubuntu18': + os_image_urn = 'Canonical:UbuntuServer:18.04-LTS:latest' + elif distro == 'ubuntu20': + os_image_urn = "Canonical:0001-com-ubuntu-server-focal:20_04-lts:latest" + elif distro == 'centos6' : + os_image_urn = 'OpenLogic:CentOS:6.10:latest' + elif distro == 'centos7' : + os_image_urn = 'OpenLogic:CentOS:7_9:latest' + elif distro == 'centos8' : + os_image_urn = 'OpenLogic:CentOS:7_9:latest' + elif distro == 'oracle6' : + os_image_urn = 'Oracle:Oracle-Linux:6.10:latest' + elif distro == 'oracle7' : + os_image_urn = 'Oracle:Oracle-Linux:ol79:latest' + elif distro == 'oracle8' : + os_image_urn = 'Oracle:Oracle-Linux:ol84-lvm:latest' + elif distro == 'sles12': + os_image_urn = _suse_image_selector('sles-12') + elif distro == 'sles15': + os_image_urn = _suse_image_selector('sles-15') + else: + if distro.count(":") == 3: + logger.info('A custom URN was provided , will be used as distro for the recovery VM') + os_image_urn = distro + else: + logger.info('No specific distro was provided , using the default Ubuntu distro') + os_image_urn = "UbuntuLTS" + return os_image_urn def _resolve_api_version(rcf, resource_provider_namespace, parent_resource_path, resource_type): diff --git a/src/vm-repair/azext_vm_repair/telemetry.py b/src/vm-repair/azext_vm_repair/telemetry.py index 81f4da45158..b10586c5844 100644 --- a/src/vm-repair/azext_vm_repair/telemetry.py +++ b/src/vm-repair/azext_vm_repair/telemetry.py @@ -12,7 +12,7 @@ TEST_KEY = 'a6bdff92-33b5-426f-9123-33875d0ae98b' PROD_KEY = '3e7130f2-759b-41d4-afb8-f1405d1d7ed9' -tc = TelemetryClient(PROD_KEY) +tc = TelemetryClient(TEST_KEY) tc.context.application.ver = _get_current_vmrepair_version() From 462a5c8861686514b7c7cf4530c29e095a55d1aa Mon Sep 17 00:00:00 2001 From: imabedalghafer Date: Sat, 16 Oct 2021 06:00:03 +0000 Subject: [PATCH 03/13] adding gen2 support --- src/vm-repair/azext_vm_repair/custom.py | 12 ++- src/vm-repair/azext_vm_repair/repair_utils.py | 79 ++++++++++++++++++- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/custom.py b/src/vm-repair/azext_vm_repair/custom.py index db1e046c412..2a6ec6e0511 100644 --- a/src/vm-repair/azext_vm_repair/custom.py +++ b/src/vm-repair/azext_vm_repair/custom.py @@ -33,7 +33,9 @@ _invoke_run_command, _check_hyperV_gen, _get_cloud_init_script, - _select_distro_linux + _select_distro_linux, + _check_linux_hyperV_gen, + _select_distro_linux_gen2 ) from .exceptions import AzCommandError, SkuNotAvailableError, UnmanagedDiskCopyError, WindowsOsNotAvailableError, RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV, ScriptReturnsError logger = get_logger(__name__) @@ -57,7 +59,13 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern if is_linux: #os_image_urn = "UbuntuLTS" os_type = 'Linux' - os_image_urn = _select_distro_linux(distro) + hyperV_generation = _check_linux_hyperV_gen(source_vm) + if hyperV_generation == 'V2': + logger.info('Generation 2 VM detected, RHEL/Centos/Oracle 6 distros not available to be used for rescue VM ') + logger.debug('gen2 machine detected') + os_image_urn = _select_distro_linux_gen2(distro) + else: + os_image_urn = _select_distro_linux(distro) else: os_image_urn = _fetch_compatible_windows_os_urn(source_vm) os_type = 'Windows' diff --git a/src/vm-repair/azext_vm_repair/repair_utils.py b/src/vm-repair/azext_vm_repair/repair_utils.py index 2074bad202a..f0eebdecb16 100644 --- a/src/vm-repair/azext_vm_repair/repair_utils.py +++ b/src/vm-repair/azext_vm_repair/repair_utils.py @@ -288,6 +288,24 @@ def _check_hyperV_gen(source_vm): if hyperVGen == 'V2': raise SkuDoesNotSupportHyperV('Cannot support V2 HyperV generation. Please run command without --enabled-nested') +def _check_linux_hyperV_gen(source_vm): + disk_id = source_vm.storage_profile.os_disk.managed_disk.id + show_disk_command = 'az disk show --id {i} --query [hyperVgeneration] -o json' \ + .format(i=disk_id) + hyperVGen = loads(_call_az_command(show_disk_command)) + if hyperVGen != 'V2': + logger.info('Trying to check on the source VM if it has the parameter of gen2') + #if image is created from Marketplace gen2 image , the disk will not have the mark for gen2 + fetch_hypervgen_command = 'az vm get-instance-view --ids {id} --query "[instanceView.hyperVGeneration]" -o json'.format(id=source_vm.id) + hyperVGen_list = loads(_call_az_command(fetch_hypervgen_command)) + hyperVGen = hyperVGen_list[0] + if hyperVGen == 'V2': + return hyperVGen + else: + hyperVGen = 'V1' + return hyperVGen + else: + return hyperVGen def _secret_tag_check(resource_group_name, copy_disk_name, secreturl): DEFAULT_LINUXPASSPHRASE_FILENAME = 'LinuxPassPhraseFileName' @@ -403,6 +421,20 @@ def _suse_image_selector(distro): logger.debug('Return the first URN : %s' , urns[0]) return urns[0] +def _suse_image_selector_gen2(distro): + fetch_urn_command = 'az vm image list --publisher SUSE --offer {offer} --sku gen2 --verbose --all --query "[].urn | reverse(sort(@))" -o json'.format(offer=distro) + logger.info('Fetching compatible SUSE OS images from gallery...') + urns = loads(_call_az_command(fetch_urn_command)) + + #Raise exception when not finding SUSE image + if not urns: + raise SuseNotAvailableError() + + logger.debug('Fetched urns: \n%s', urns) + #Returning the first URN as it is the latest image with no special use like HPC or SAP + logger.debug('Return the first URN : %s' , urns[0]) + return urns[0] + def _select_distro_linux(distro): if distro == 'rhel6': os_image_urn = 'RedHat:RHEL:6.10:latest' @@ -419,13 +451,13 @@ def _select_distro_linux(distro): elif distro == 'centos7' : os_image_urn = 'OpenLogic:CentOS:7_9:latest' elif distro == 'centos8' : - os_image_urn = 'OpenLogic:CentOS:7_9:latest' + os_image_urn = 'OpenLogic:CentOS:8_4:latest' elif distro == 'oracle6' : os_image_urn = 'Oracle:Oracle-Linux:6.10:latest' elif distro == 'oracle7' : os_image_urn = 'Oracle:Oracle-Linux:ol79:latest' elif distro == 'oracle8' : - os_image_urn = 'Oracle:Oracle-Linux:ol84-lvm:latest' + os_image_urn = 'Oracle:Oracle-Linux:ol82:latest' elif distro == 'sles12': os_image_urn = _suse_image_selector('sles-12') elif distro == 'sles15': @@ -439,6 +471,49 @@ def _select_distro_linux(distro): os_image_urn = "UbuntuLTS" return os_image_urn +def _select_distro_linux_gen2(distro): + # base on the document : https://docs.microsoft.com/en-us/azure/virtual-machines/generation-2#generation-2-vm-images-in-azure-marketplace + # RHEL/Centos/Oracle 6 are not supported for Gen 2 + if distro == 'rhel6': + os_image_urn = 'RedHat:rhel-raw:7-raw-gen2:latest' + elif distro == 'rhel7': + os_image_urn = 'RedHat:rhel-raw:7-raw-gen2:latest' + elif distro == 'rhel8': + os_image_urn = 'RedHat:rhel-raw:8-raw-gen2:latest' + elif distro == 'ubuntu18': + os_image_urn = 'Canonical:UbuntuServer:18_04-lts-gen2:latest' + elif distro == 'ubuntu20': + os_image_urn = "Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest" + elif distro == 'centos6' : + os_image_urn = 'OpenLogic:CentOS:7_9-gen2:latest' + elif distro == 'centos7' : + os_image_urn = 'OpenLogic:CentOS:7_9-gen2:latest' + elif distro == 'centos8' : + os_image_urn = 'OpenLogic:CentOS:8_4-gen2:latest' + elif distro == 'oracle6' : + os_image_urn = 'Oracle:Oracle-Linux:ol79-gen2:latest' + elif distro == 'oracle7' : + os_image_urn = 'Oracle:Oracle-Linux:ol79-gen2:latest' + elif distro == 'oracle8' : + os_image_urn = 'Oracle:Oracle-Linux:ol82-gen2:latest' + elif distro == 'sles12': + os_image_urn = _suse_image_selector('sles-12') + elif distro == 'sles15': + os_image_urn = _suse_image_selector('sles-15') + else: + if distro.count(":") == 3: + logger.info('A custom URN was provided , will be used as distro for the recovery VM') + if distro.find('gen2'): + os_image_urn = distro + else: + logger.info('The provided URN does not contain Gen2 in it and this VM is a gen2 , dropping to default image') + os_image_urn = "Canonical:UbuntuServer:18_04-lts-gen2:latest" + else: + logger.info('No specific distro was provided , using the default Ubuntu distro') + os_image_urn = "Canonical:UbuntuServer:18_04-lts-gen2:latest" + return os_image_urn + + def _resolve_api_version(rcf, resource_provider_namespace, parent_resource_path, resource_type): provider = rcf.providers.get(resource_provider_namespace) From e2911b13bcab77d943dc11ad34e31a7530f3ee8b Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Sat, 16 Oct 2021 07:06:47 +0000 Subject: [PATCH 04/13] updated the support for gen2 machines --- src/vm-repair/azext_vm_repair/custom.py | 7 +++++-- src/vm-repair/azext_vm_repair/repair_utils.py | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/custom.py b/src/vm-repair/azext_vm_repair/custom.py index 2a6ec6e0511..7beca4de3a0 100644 --- a/src/vm-repair/azext_vm_repair/custom.py +++ b/src/vm-repair/azext_vm_repair/custom.py @@ -59,8 +59,8 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern if is_linux: #os_image_urn = "UbuntuLTS" os_type = 'Linux' - hyperV_generation = _check_linux_hyperV_gen(source_vm) - if hyperV_generation == 'V2': + hyperV_generation_linux = _check_linux_hyperV_gen(source_vm) + if hyperV_generation_linux == 'V2': logger.info('Generation 2 VM detected, RHEL/Centos/Oracle 6 distros not available to be used for rescue VM ') logger.debug('gen2 machine detected') os_image_urn = _select_distro_linux_gen2(distro) @@ -109,6 +109,9 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern # Only add hyperV variable when available if hyperV_generation: copy_disk_command += ' --hyper-v-generation {hyperV}'.format(hyperV=hyperV_generation) + elif is_linux and hyperV_generation_linux == 'V2': + logger.info('The disk did not contian the info of gen2 , but the machine is created from gen2 image') + copy_disk_command += ' --hyper-v-generation {hyperV}'.format(hyperV=hyperV_generation_linux) # Set availability zone for vm when available if source_vm.zones: zone = source_vm.zones[0] diff --git a/src/vm-repair/azext_vm_repair/repair_utils.py b/src/vm-repair/azext_vm_repair/repair_utils.py index f0eebdecb16..bab30efb7f5 100644 --- a/src/vm-repair/azext_vm_repair/repair_utils.py +++ b/src/vm-repair/azext_vm_repair/repair_utils.py @@ -497,9 +497,9 @@ def _select_distro_linux_gen2(distro): elif distro == 'oracle8' : os_image_urn = 'Oracle:Oracle-Linux:ol82-gen2:latest' elif distro == 'sles12': - os_image_urn = _suse_image_selector('sles-12') + os_image_urn = _suse_image_selector_gen2('sles-12') elif distro == 'sles15': - os_image_urn = _suse_image_selector('sles-15') + os_image_urn = _suse_image_selector_gen2('sles-15') else: if distro.count(":") == 3: logger.info('A custom URN was provided , will be used as distro for the recovery VM') From 41c33804e55258c8b18540b855f7d802b7d21045 Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Tue, 30 Nov 2021 11:52:34 +0000 Subject: [PATCH 05/13] updating the unlock script to match different distros --- .../scripts/linux-build_setup-cloud-init.txt | 5 ++- .../scripts/linux-mount-encrypted-disk.sh | 43 +++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/scripts/linux-build_setup-cloud-init.txt b/src/vm-repair/azext_vm_repair/scripts/linux-build_setup-cloud-init.txt index 3f61e4803f0..9d9174e566b 100644 --- a/src/vm-repair/azext_vm_repair/scripts/linux-build_setup-cloud-init.txt +++ b/src/vm-repair/azext_vm_repair/scripts/linux-build_setup-cloud-init.txt @@ -6,6 +6,7 @@ runcmd: - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o rustinstall.sh - chmod 700 rustinstall.sh - ./rustinstall.sh -y --default-toolchain nightly - - apt-get update - - apt install -y build-essential + #Commenting the below lines to stop for the alar2, till the complete of the distro feature , then it will updated on the next build. + #- apt-get update + #- apt install -y build-essential diff --git a/src/vm-repair/azext_vm_repair/scripts/linux-mount-encrypted-disk.sh b/src/vm-repair/azext_vm_repair/scripts/linux-mount-encrypted-disk.sh index b32808e035d..701e6d4029b 100644 --- a/src/vm-repair/azext_vm_repair/scripts/linux-mount-encrypted-disk.sh +++ b/src/vm-repair/azext_vm_repair/scripts/linux-mount-encrypted-disk.sh @@ -93,20 +93,30 @@ data_os_lvm_check () { echo ${lvm_part} >> ${logpath}/${logfile} if [ -z ${lvm_part} ] then - export root_part=`fdisk -l ${data_disk} 2>&1 | grep ^/ |awk '$4 > 60000000{print $1}'` >> ${logpath}/${logfile} + #Updaing the below command to use lsblk instead of fdisk for accounting for different distros + #export root_part=`fdisk -l ${data_disk} 2>&1 | grep ^/ |awk '$4 > 60000000{print $1}'` >> ${logpath}/${logfile} + export root_part=`lsblk ${data_disk} -l -n -p 2>&1 | grep -w -v ${data_disk} |awk '$4 > 60000000{print $1}'` >> ${logpath}/${logfile} echo "`date` LVM not found on the data disk" >> ${logpath}/${logfile} echo "`date` The OS partition on the data drive is ${root_part}" >> ${logpath}/${logfile} else - export root_part=${lvm_part} >> ${logpath}/${logfile} + #adding a check to see if the returned value is just the partition number or partition full path. + if grep -q ${data_disk} <<< ${lvm_part} + then + export root_part=${lvm_part} >> ${logpath}/${logfile} + else + export root_part=${data_disk}${lvm_part} >> ${logpath}/${logfile} + fi echo "`date` LVM found on the data disk" >> ${logpath}/${logfile} - echo "`date` The OS partition on the data drive is ${lvm_part}" >> ${logpath}/${logfile} + echo "`date` The OS partition on the data drive is ${root_part}" >> ${logpath}/${logfile} fi } locate_mount_data_boot () { trapper echo "`date` Locating the partitions on the data drive" >> ${logpath}/${logfile} - export data_parts=`fdisk -l ${data_disk} 2>&1 | grep ^/ | awk '{print $1}'` >> ${logpath}/${logfile} + #export data_parts=`fdisk -l ${data_disk} 2>&1 | grep ^/ | awk '{print $1}'` >> ${logpath}/${logfile} + #The below is updated to use lsblk, as fdisk output is diffferent between distros while the lsblk command is the same. + export data_parts=`lsblk ${data_disk} -l -o name -n -p | grep -v -w ${data_disk}` >> ${logpath}/${logfile} echo "`date` Your data partitions are: ${data_parts}" >> ${logpath}/${logfile} #create mountpoints for all the data parts @@ -138,6 +148,9 @@ mount_cmd () { mount_lvm () { trapper echo "`date` Mounting LVM structures found on ${root_part}" >> ${logpath}/${logfile} + #adding below lines to make sure that volume groups are activated before trying to mount. + vgs >> ${logpath}/${logfile} + vgchange -ay rootvg >> ${logpath}/${logfile} ${mount_cmd} /dev/rootvg/rootlv /investigateroot >> ${logpath}/${logfile} ${mount_cmd} /dev/rootvg/varlv /investigateroot/var/ >> ${logpath}/${logfile} ${mount_cmd} /dev/rootvg/homelv /investigateroot/home >> ${logpath}/${logfile} @@ -194,8 +207,30 @@ remount_boot () { echo "`date` Mounting the boot partition ${boot_part} on /investigateroot/boot" >> ${logpath}/${logfile} ${mount_cmd} ${boot_part} /investigateroot/boot >> ${logpath}/${logfile} } +install_required_packages() +{ + echo "`date` Checking about the required packages and instal the misssing ones" >> ${logpath}/${logfile} + echo "`date` Checking the distro of the recovery VM .." >> ${logpath}/${logfile} + output=`which apt` + if [ $? -eq 0 ] + then + echo "`date` This is ubuntu VM" >> ${logpath}/${logfile} + apt-get install -y cryptsetup lvm2 >> ${logpath}/${logfile} + else + output=`which zypper` + if [ $? -eq 0 ] + then + echo "`date` This is a sles VM" >> ${logpath}/${logfile} + zypper --non-interactive --no-refresh install cryptsetup lvm2 + else + echo "`date` This a yum based distro" >> ${logpath}/${logfile} + yum install -y cryptsetup lvm2 + fi + fi +} setlog +install_required_packages duplication_validation create_mountpoints locatebekvol From fc274946f32bcc471e0ac8ab62fda23482a5dc45 Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Thu, 3 Feb 2022 10:49:24 +0000 Subject: [PATCH 06/13] updating the fork from main branch and adding the feature --- src/vm-repair/azext_vm_repair/custom.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/custom.py b/src/vm-repair/azext_vm_repair/custom.py index 8e46ff2e102..247bad051c2 100644 --- a/src/vm-repair/azext_vm_repair/custom.py +++ b/src/vm-repair/azext_vm_repair/custom.py @@ -34,25 +34,17 @@ _invoke_run_command, _check_hyperV_gen, _get_cloud_init_script, -<<<<<<< HEAD _select_distro_linux, _check_linux_hyperV_gen, _select_distro_linux_gen2 -======= _set_repair_map_url, _is_gen2 ->>>>>>> 248b34cbb2eeb640525e4ab82d36d289781b54e5 ) from .exceptions import AzCommandError, SkuNotAvailableError, UnmanagedDiskCopyError, WindowsOsNotAvailableError, RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV, ScriptReturnsError logger = get_logger(__name__) -<<<<<<< HEAD def create(cmd, vm_name, resource_group_name, repair_password=None, repair_username=None, repair_vm_name=None, copy_disk_name=None, repair_group_name=None, unlock_encrypted_vm=False, enable_nested=False, associate_public_ip=False, distro='ubuntu'): -======= -def create(cmd, vm_name, resource_group_name, repair_password=None, repair_username=None, repair_vm_name=None, copy_disk_name=None, repair_group_name=None, unlock_encrypted_vm=False, enable_nested=False, associate_public_ip=False): - ->>>>>>> 248b34cbb2eeb640525e4ab82d36d289781b54e5 # Init command helper object command = command_helper(logger, cmd, 'vm repair create') # Main command calling block From c1339a73fbe26d2e746062b1358d1362c17295f0 Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Thu, 3 Feb 2022 10:51:56 +0000 Subject: [PATCH 07/13] Adding missing comma --- src/vm-repair/azext_vm_repair/custom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm-repair/azext_vm_repair/custom.py b/src/vm-repair/azext_vm_repair/custom.py index 247bad051c2..38ba2551b26 100644 --- a/src/vm-repair/azext_vm_repair/custom.py +++ b/src/vm-repair/azext_vm_repair/custom.py @@ -36,7 +36,7 @@ _get_cloud_init_script, _select_distro_linux, _check_linux_hyperV_gen, - _select_distro_linux_gen2 + _select_distro_linux_gen2, _set_repair_map_url, _is_gen2 ) From cffbce458402149e34794695b1aa283cd31bda8b Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Fri, 11 Feb 2022 11:49:24 +0000 Subject: [PATCH 08/13] fixing the style --- src/vm-repair/azext_vm_repair/custom.py | 2 +- src/vm-repair/azext_vm_repair/exceptions.py | 3 +- src/vm-repair/azext_vm_repair/repair_utils.py | 75 ++++++++++--------- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/custom.py b/src/vm-repair/azext_vm_repair/custom.py index 38ba2551b26..70bfafe9e06 100644 --- a/src/vm-repair/azext_vm_repair/custom.py +++ b/src/vm-repair/azext_vm_repair/custom.py @@ -64,7 +64,7 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern # Fetch OS image urn and set OS type for disk create if is_linux: - #os_image_urn = "UbuntuLTS" + # os_image_urn = "UbuntuLTS" os_type = 'Linux' hyperV_generation_linux = _check_linux_hyperV_gen(source_vm) if hyperV_generation_linux == 'V2': diff --git a/src/vm-repair/azext_vm_repair/exceptions.py b/src/vm-repair/azext_vm_repair/exceptions.py index b2be73eab9a..de1755c4609 100644 --- a/src/vm-repair/azext_vm_repair/exceptions.py +++ b/src/vm-repair/azext_vm_repair/exceptions.py @@ -31,5 +31,6 @@ class SkuDoesNotSupportHyperV(Exception): class ScriptReturnsError(Exception): """Raised when run script returns error""" + class SuseNotAvailableError(Exception): - """Raised when SUSE image not available""" \ No newline at end of file + """Raised when SUSE image not available""" diff --git a/src/vm-repair/azext_vm_repair/repair_utils.py b/src/vm-repair/azext_vm_repair/repair_utils.py index 1a5f2a59c0e..b7f93f52428 100644 --- a/src/vm-repair/azext_vm_repair/repair_utils.py +++ b/src/vm-repair/azext_vm_repair/repair_utils.py @@ -17,7 +17,8 @@ from .encryption_types import Encryption -from .exceptions import AzCommandError, WindowsOsNotAvailableError, RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV,SuseNotAvailableError +from .exceptions import (AzCommandError, WindowsOsNotAvailableError, + RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV, SuseNotAvailableError) # pylint: disable=line-too-long, deprecated-method REPAIR_MAP_URL = 'https://raw.githubusercontent.com/Azure/repair-script-library/master/map.json' @@ -306,6 +307,7 @@ def _check_hyperV_gen(source_vm): if hyperVGen == 'V2': raise SkuDoesNotSupportHyperV('Cannot support V2 HyperV generation. Please run command without --enabled-nested') + def _check_linux_hyperV_gen(source_vm): disk_id = source_vm.storage_profile.os_disk.managed_disk.id show_disk_command = 'az disk show --id {i} --query [hyperVgeneration] -o json' \ @@ -313,7 +315,7 @@ def _check_linux_hyperV_gen(source_vm): hyperVGen = loads(_call_az_command(show_disk_command)) if hyperVGen != 'V2': logger.info('Trying to check on the source VM if it has the parameter of gen2') - #if image is created from Marketplace gen2 image , the disk will not have the mark for gen2 + # if image is created from Marketplace gen2 image , the disk will not have the mark for gen2 fetch_hypervgen_command = 'az vm get-instance-view --ids {id} --query "[instanceView.hyperVGeneration]" -o json'.format(id=source_vm.id) hyperVGen_list = loads(_call_az_command(fetch_hypervgen_command)) hyperVGen = hyperVGen_list[0] @@ -323,7 +325,8 @@ def _check_linux_hyperV_gen(source_vm): hyperVGen = 'V1' return hyperVGen else: - return hyperVGen + return hyperVGen + def _secret_tag_check(resource_group_name, copy_disk_name, secreturl): DEFAULT_LINUXPASSPHRASE_FILENAME = 'LinuxPassPhraseFileName' @@ -425,34 +428,37 @@ def _fetch_compatible_windows_os_urn(source_vm): logger.debug('Returning Urn 0: %s', urns[0]) return urns[0] + def _suse_image_selector(distro): fetch_urn_command = 'az vm image list --publisher SUSE --offer {offer} --sku gen1 --verbose --all --query "[].urn | reverse(sort(@))" -o json'.format(offer=distro) logger.info('Fetching compatible SUSE OS images from gallery...') urns = loads(_call_az_command(fetch_urn_command)) - #Raise exception when not finding SUSE image + # Raise exception when not finding SUSE image if not urns: raise SuseNotAvailableError() logger.debug('Fetched urns: \n%s', urns) - #Returning the first URN as it is the latest image with no special use like HPC or SAP - logger.debug('Return the first URN : %s' , urns[0]) + # Returning the first URN as it is the latest image with no special use like HPC or SAP + logger.debug('Return the first URN : %s', urns[0]) return urns[0] + def _suse_image_selector_gen2(distro): fetch_urn_command = 'az vm image list --publisher SUSE --offer {offer} --sku gen2 --verbose --all --query "[].urn | reverse(sort(@))" -o json'.format(offer=distro) logger.info('Fetching compatible SUSE OS images from gallery...') urns = loads(_call_az_command(fetch_urn_command)) - #Raise exception when not finding SUSE image + # Raise exception when not finding SUSE image if not urns: raise SuseNotAvailableError() logger.debug('Fetched urns: \n%s', urns) - #Returning the first URN as it is the latest image with no special use like HPC or SAP - logger.debug('Return the first URN : %s' , urns[0]) + # Returning the first URN as it is the latest image with no special use like HPC or SAP + logger.debug('Return the first URN : %s', urns[0]) return urns[0] + def _select_distro_linux(distro): if distro == 'rhel6': os_image_urn = 'RedHat:RHEL:6.10:latest' @@ -464,18 +470,18 @@ def _select_distro_linux(distro): os_image_urn = 'Canonical:UbuntuServer:18.04-LTS:latest' elif distro == 'ubuntu20': os_image_urn = "Canonical:0001-com-ubuntu-server-focal:20_04-lts:latest" - elif distro == 'centos6' : - os_image_urn = 'OpenLogic:CentOS:6.10:latest' - elif distro == 'centos7' : - os_image_urn = 'OpenLogic:CentOS:7_9:latest' - elif distro == 'centos8' : - os_image_urn = 'OpenLogic:CentOS:8_4:latest' - elif distro == 'oracle6' : - os_image_urn = 'Oracle:Oracle-Linux:6.10:latest' - elif distro == 'oracle7' : - os_image_urn = 'Oracle:Oracle-Linux:ol79:latest' - elif distro == 'oracle8' : - os_image_urn = 'Oracle:Oracle-Linux:ol82:latest' + elif distro == 'centos6': + os_image_urn = 'OpenLogic:CentOS:6.10:latest' + elif distro == 'centos7': + os_image_urn = 'OpenLogic:CentOS:7_9:latest' + elif distro == 'centos8': + os_image_urn = 'OpenLogic:CentOS:8_4:latest' + elif distro == 'oracle6': + os_image_urn = 'Oracle:Oracle-Linux:6.10:latest' + elif distro == 'oracle7': + os_image_urn = 'Oracle:Oracle-Linux:ol79:latest' + elif distro == 'oracle8': + os_image_urn = 'Oracle:Oracle-Linux:ol82:latest' elif distro == 'sles12': os_image_urn = _suse_image_selector('sles-12') elif distro == 'sles15': @@ -489,9 +495,10 @@ def _select_distro_linux(distro): os_image_urn = "UbuntuLTS" return os_image_urn + def _select_distro_linux_gen2(distro): # base on the document : https://docs.microsoft.com/en-us/azure/virtual-machines/generation-2#generation-2-vm-images-in-azure-marketplace - # RHEL/Centos/Oracle 6 are not supported for Gen 2 + # RHEL/Centos/Oracle 6 are not supported for Gen 2 if distro == 'rhel6': os_image_urn = 'RedHat:rhel-raw:7-raw-gen2:latest' elif distro == 'rhel7': @@ -502,18 +509,18 @@ def _select_distro_linux_gen2(distro): os_image_urn = 'Canonical:UbuntuServer:18_04-lts-gen2:latest' elif distro == 'ubuntu20': os_image_urn = "Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest" - elif distro == 'centos6' : - os_image_urn = 'OpenLogic:CentOS:7_9-gen2:latest' - elif distro == 'centos7' : - os_image_urn = 'OpenLogic:CentOS:7_9-gen2:latest' - elif distro == 'centos8' : - os_image_urn = 'OpenLogic:CentOS:8_4-gen2:latest' - elif distro == 'oracle6' : - os_image_urn = 'Oracle:Oracle-Linux:ol79-gen2:latest' - elif distro == 'oracle7' : - os_image_urn = 'Oracle:Oracle-Linux:ol79-gen2:latest' - elif distro == 'oracle8' : - os_image_urn = 'Oracle:Oracle-Linux:ol82-gen2:latest' + elif distro == 'centos6': + os_image_urn = 'OpenLogic:CentOS:7_9-gen2:latest' + elif distro == 'centos7': + os_image_urn = 'OpenLogic:CentOS:7_9-gen2:latest' + elif distro == 'centos8': + os_image_urn = 'OpenLogic:CentOS:8_4-gen2:latest' + elif distro == 'oracle6': + os_image_urn = 'Oracle:Oracle-Linux:ol79-gen2:latest' + elif distro == 'oracle7': + os_image_urn = 'Oracle:Oracle-Linux:ol79-gen2:latest' + elif distro == 'oracle8': + os_image_urn = 'Oracle:Oracle-Linux:ol82-gen2:latest' elif distro == 'sles12': os_image_urn = _suse_image_selector_gen2('sles-12') elif distro == 'sles15': From 14318ff1a10c34ab2b648af22b78b78c0a700ab5 Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Wed, 23 Mar 2022 14:06:04 +0000 Subject: [PATCH 09/13] updated the help text --- src/vm-repair/azext_vm_repair/_help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm-repair/azext_vm_repair/_help.py b/src/vm-repair/azext_vm_repair/_help.py index 7e0b9332462..efb295ea301 100644 --- a/src/vm-repair/azext_vm_repair/_help.py +++ b/src/vm-repair/azext_vm_repair/_help.py @@ -22,7 +22,7 @@ - name: Create a repair VM and set the VM authentication text: > az vm repair create -g MyResourceGroup -n myVM --repair-username username --repair-password password!234 --verbose - - name: Create a repair VM of a specific distro , a specific URN could also be provided + - name: Create a repair VM of a specific distro or a specific URN could also be provided text: > az vm repair create -g MyResourceGroup -n myVM --distro 'rhel7|suse12|ubuntu20|centos6|oracle8' """ From 8c29cbba6c1ad5c451c56ba33c193531990fe504 Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Wed, 23 Mar 2022 14:57:32 +0000 Subject: [PATCH 10/13] updated the image selector function and the telementry key --- src/vm-repair/azext_vm_repair/repair_utils.py | 86 ++++++++----------- src/vm-repair/azext_vm_repair/telemetry.py | 2 +- 2 files changed, 35 insertions(+), 53 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/repair_utils.py b/src/vm-repair/azext_vm_repair/repair_utils.py index b7f93f52428..7e88c8d094a 100644 --- a/src/vm-repair/azext_vm_repair/repair_utils.py +++ b/src/vm-repair/azext_vm_repair/repair_utils.py @@ -460,32 +460,23 @@ def _suse_image_selector_gen2(distro): def _select_distro_linux(distro): - if distro == 'rhel6': - os_image_urn = 'RedHat:RHEL:6.10:latest' - elif distro == 'rhel7': - os_image_urn = 'RedHat:rhel-raw:7-raw:latest' - elif distro == 'rhel8': - os_image_urn = 'RedHat:rhel-raw:8-raw:latest' - elif distro == 'ubuntu18': - os_image_urn = 'Canonical:UbuntuServer:18.04-LTS:latest' - elif distro == 'ubuntu20': - os_image_urn = "Canonical:0001-com-ubuntu-server-focal:20_04-lts:latest" - elif distro == 'centos6': - os_image_urn = 'OpenLogic:CentOS:6.10:latest' - elif distro == 'centos7': - os_image_urn = 'OpenLogic:CentOS:7_9:latest' - elif distro == 'centos8': - os_image_urn = 'OpenLogic:CentOS:8_4:latest' - elif distro == 'oracle6': - os_image_urn = 'Oracle:Oracle-Linux:6.10:latest' - elif distro == 'oracle7': - os_image_urn = 'Oracle:Oracle-Linux:ol79:latest' - elif distro == 'oracle8': - os_image_urn = 'Oracle:Oracle-Linux:ol82:latest' - elif distro == 'sles12': - os_image_urn = _suse_image_selector('sles-12') - elif distro == 'sles15': - os_image_urn = _suse_image_selector('sles-15') + image_lookup = { + 'rhel6':'RedHat:RHEL:6.10:latest', + 'rhel7':'RedHat:rhel-raw:7-raw:latest', + 'rhel8':'RedHat:rhel-raw:8-raw:latest', + 'ubuntu18':'Canonical:UbuntuServer:18.04-LTS:latest', + 'ubuntu20':'Canonical:0001-com-ubuntu-server-focal:20_04-lts:latest', + 'centos6':'OpenLogic:CentOS:6.10:latest', + 'centos7':'OpenLogic:CentOS:7_9:latest', + 'centos8':'OpenLogic:CentOS:8_4:latest', + 'oracle6':'Oracle:Oracle-Linux:6.10:latest', + 'oracle7':'Oracle:Oracle-Linux:ol79:latest', + 'oracle8':'Oracle:Oracle-Linux:ol82:latest', + 'sles12':_suse_image_selector('sles-12'), + 'sles15':_suse_image_selector('sles-15') + } + if distro in image_lookup: + os_image_urn = image_lookup[distro] else: if distro.count(":") == 3: logger.info('A custom URN was provided , will be used as distro for the recovery VM') @@ -499,32 +490,23 @@ def _select_distro_linux(distro): def _select_distro_linux_gen2(distro): # base on the document : https://docs.microsoft.com/en-us/azure/virtual-machines/generation-2#generation-2-vm-images-in-azure-marketplace # RHEL/Centos/Oracle 6 are not supported for Gen 2 - if distro == 'rhel6': - os_image_urn = 'RedHat:rhel-raw:7-raw-gen2:latest' - elif distro == 'rhel7': - os_image_urn = 'RedHat:rhel-raw:7-raw-gen2:latest' - elif distro == 'rhel8': - os_image_urn = 'RedHat:rhel-raw:8-raw-gen2:latest' - elif distro == 'ubuntu18': - os_image_urn = 'Canonical:UbuntuServer:18_04-lts-gen2:latest' - elif distro == 'ubuntu20': - os_image_urn = "Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest" - elif distro == 'centos6': - os_image_urn = 'OpenLogic:CentOS:7_9-gen2:latest' - elif distro == 'centos7': - os_image_urn = 'OpenLogic:CentOS:7_9-gen2:latest' - elif distro == 'centos8': - os_image_urn = 'OpenLogic:CentOS:8_4-gen2:latest' - elif distro == 'oracle6': - os_image_urn = 'Oracle:Oracle-Linux:ol79-gen2:latest' - elif distro == 'oracle7': - os_image_urn = 'Oracle:Oracle-Linux:ol79-gen2:latest' - elif distro == 'oracle8': - os_image_urn = 'Oracle:Oracle-Linux:ol82-gen2:latest' - elif distro == 'sles12': - os_image_urn = _suse_image_selector_gen2('sles-12') - elif distro == 'sles15': - os_image_urn = _suse_image_selector_gen2('sles-15') + image_lookup = { + 'rhel6':'RedHat:rhel-raw:7-raw-gen2:latest', + 'rhel7':'RedHat:rhel-raw:7-raw-gen2:latest', + 'rhel8':'RedHat:rhel-raw:8-raw-gen2:latest', + 'ubuntu18':'Canonical:UbuntuServer:18_04-lts-gen2:latest', + 'ubuntu20':'Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest', + 'centos6':'OpenLogic:CentOS:7_9-gen2:latest', + 'centos7':'OpenLogic:CentOS:7_9-gen2:latest', + 'centos8':'OpenLogic:CentOS:8_4-gen2:latest', + 'oracle6':'Oracle:Oracle-Linux:ol79-gen2:latest', + 'oracle7':'Oracle:Oracle-Linux:ol79-gen2:latest', + 'oracle8':'Oracle:Oracle-Linux:ol82-gen2:latest', + 'sles12':_suse_image_selector_gen2('sles-12'), + 'sles15':_suse_image_selector_gen2('sles-15') + } + if distro in image_lookup: + os_image_urn = image_lookup[distro] else: if distro.count(":") == 3: logger.info('A custom URN was provided , will be used as distro for the recovery VM') diff --git a/src/vm-repair/azext_vm_repair/telemetry.py b/src/vm-repair/azext_vm_repair/telemetry.py index b10586c5844..81f4da45158 100644 --- a/src/vm-repair/azext_vm_repair/telemetry.py +++ b/src/vm-repair/azext_vm_repair/telemetry.py @@ -12,7 +12,7 @@ TEST_KEY = 'a6bdff92-33b5-426f-9123-33875d0ae98b' PROD_KEY = '3e7130f2-759b-41d4-afb8-f1405d1d7ed9' -tc = TelemetryClient(TEST_KEY) +tc = TelemetryClient(PROD_KEY) tc.context.application.ver = _get_current_vmrepair_version() From 0ab3fe1e941a5fb9ba9b37eaa7c9b6e7b2e86820 Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Fri, 1 Apr 2022 06:56:58 +0000 Subject: [PATCH 11/13] updating the styling errors --- src/vm-repair/azext_vm_repair/repair_utils.py | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/src/vm-repair/azext_vm_repair/repair_utils.py b/src/vm-repair/azext_vm_repair/repair_utils.py index 7e88c8d094a..68bcd03a706 100644 --- a/src/vm-repair/azext_vm_repair/repair_utils.py +++ b/src/vm-repair/azext_vm_repair/repair_utils.py @@ -3,7 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -from logging import Logger, log +# from logging import Logger # , log import subprocess import shlex import os @@ -17,8 +17,7 @@ from .encryption_types import Encryption -from .exceptions import (AzCommandError, WindowsOsNotAvailableError, - RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV, SuseNotAvailableError) +from .exceptions import (AzCommandError, WindowsOsNotAvailableError, RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV, SuseNotAvailableError) # pylint: disable=line-too-long, deprecated-method REPAIR_MAP_URL = 'https://raw.githubusercontent.com/Azure/repair-script-library/master/map.json' @@ -461,19 +460,19 @@ def _suse_image_selector_gen2(distro): def _select_distro_linux(distro): image_lookup = { - 'rhel6':'RedHat:RHEL:6.10:latest', - 'rhel7':'RedHat:rhel-raw:7-raw:latest', - 'rhel8':'RedHat:rhel-raw:8-raw:latest', - 'ubuntu18':'Canonical:UbuntuServer:18.04-LTS:latest', - 'ubuntu20':'Canonical:0001-com-ubuntu-server-focal:20_04-lts:latest', - 'centos6':'OpenLogic:CentOS:6.10:latest', - 'centos7':'OpenLogic:CentOS:7_9:latest', - 'centos8':'OpenLogic:CentOS:8_4:latest', - 'oracle6':'Oracle:Oracle-Linux:6.10:latest', - 'oracle7':'Oracle:Oracle-Linux:ol79:latest', - 'oracle8':'Oracle:Oracle-Linux:ol82:latest', - 'sles12':_suse_image_selector('sles-12'), - 'sles15':_suse_image_selector('sles-15') + 'rhel6': 'RedHat:RHEL:6.10:latest', + 'rhel7': 'RedHat:rhel-raw:7-raw:latest', + 'rhel8': 'RedHat:rhel-raw:8-raw:latest', + 'ubuntu18': 'Canonical:UbuntuServer:18.04-LTS:latest', + 'ubuntu20': 'Canonical:0001-com-ubuntu-server-focal:20_04-lts:latest', + 'centos6': 'OpenLogic:CentOS:6.10:latest', + 'centos7': 'OpenLogic:CentOS:7_9:latest', + 'centos8': 'OpenLogic:CentOS:8_4:latest', + 'oracle6': 'Oracle:Oracle-Linux:6.10:latest', + 'oracle7': 'Oracle:Oracle-Linux:ol79:latest', + 'oracle8': 'Oracle:Oracle-Linux:ol82:latest', + 'sles12': _suse_image_selector('sles-12'), + 'sles15': _suse_image_selector('sles-15') } if distro in image_lookup: os_image_urn = image_lookup[distro] @@ -491,20 +490,20 @@ def _select_distro_linux_gen2(distro): # base on the document : https://docs.microsoft.com/en-us/azure/virtual-machines/generation-2#generation-2-vm-images-in-azure-marketplace # RHEL/Centos/Oracle 6 are not supported for Gen 2 image_lookup = { - 'rhel6':'RedHat:rhel-raw:7-raw-gen2:latest', - 'rhel7':'RedHat:rhel-raw:7-raw-gen2:latest', - 'rhel8':'RedHat:rhel-raw:8-raw-gen2:latest', - 'ubuntu18':'Canonical:UbuntuServer:18_04-lts-gen2:latest', - 'ubuntu20':'Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest', - 'centos6':'OpenLogic:CentOS:7_9-gen2:latest', - 'centos7':'OpenLogic:CentOS:7_9-gen2:latest', - 'centos8':'OpenLogic:CentOS:8_4-gen2:latest', - 'oracle6':'Oracle:Oracle-Linux:ol79-gen2:latest', - 'oracle7':'Oracle:Oracle-Linux:ol79-gen2:latest', - 'oracle8':'Oracle:Oracle-Linux:ol82-gen2:latest', - 'sles12':_suse_image_selector_gen2('sles-12'), - 'sles15':_suse_image_selector_gen2('sles-15') - } + 'rhel6': 'RedHat:rhel-raw:7-raw-gen2:latest', + 'rhel7': 'RedHat:rhel-raw:7-raw-gen2:latest', + 'rhel8': 'RedHat:rhel-raw:8-raw-gen2:latest', + 'ubuntu18': 'Canonical:UbuntuServer:18_04-lts-gen2:latest', + 'ubuntu20': 'Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest', + 'centos6': 'OpenLogic:CentOS:7_9-gen2:latest', + 'centos7': 'OpenLogic:CentOS:7_9-gen2:latest', + 'centos8': 'OpenLogic:CentOS:8_4-gen2:latest', + 'oracle6': 'Oracle:Oracle-Linux:ol79-gen2:latest', + 'oracle7': 'Oracle:Oracle-Linux:ol79-gen2:latest', + 'oracle8': 'Oracle:Oracle-Linux:ol82-gen2:latest', + 'sles12': _suse_image_selector_gen2('sles-12'), + 'sles15': _suse_image_selector_gen2('sles-15') + } if distro in image_lookup: os_image_urn = image_lookup[distro] else: From c5647bee5034ffeff7d22f44045a62dcef789bb2 Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Tue, 19 Apr 2022 07:29:16 +0000 Subject: [PATCH 12/13] Updated the history, version and test units --- src/vm-repair/HISTORY.rst | 4 + src/vm-repair/azext_vm_repair/_help.py | 2 +- .../tests/latest/test_repair_commands.py | 133 ++++++++++++++++++ src/vm-repair/setup.py | 2 +- 4 files changed, 139 insertions(+), 2 deletions(-) diff --git a/src/vm-repair/HISTORY.rst b/src/vm-repair/HISTORY.rst index 146f55a678c..13e54f8c116 100644 --- a/src/vm-repair/HISTORY.rst +++ b/src/vm-repair/HISTORY.rst @@ -2,6 +2,10 @@ Release History =============== +0.4.2 +++++++ +Adding a new distro option for creating the recovery VM, adding the detect for gen2 Linux machine and create a gen2 recovery VM + 0.4.1 ++++++ Fixing bug in preview parameter diff --git a/src/vm-repair/azext_vm_repair/_help.py b/src/vm-repair/azext_vm_repair/_help.py index efb295ea301..67cd5dbb11d 100644 --- a/src/vm-repair/azext_vm_repair/_help.py +++ b/src/vm-repair/azext_vm_repair/_help.py @@ -24,7 +24,7 @@ az vm repair create -g MyResourceGroup -n myVM --repair-username username --repair-password password!234 --verbose - name: Create a repair VM of a specific distro or a specific URN could also be provided text: > - az vm repair create -g MyResourceGroup -n myVM --distro 'rhel7|suse12|ubuntu20|centos6|oracle8' + az vm repair create -g MyResourceGroup -n myVM --distro 'rhel7|sles12|ubuntu20|centos6|oracle8|sles15' """ helps['vm repair restore'] = """ diff --git a/src/vm-repair/azext_vm_repair/tests/latest/test_repair_commands.py b/src/vm-repair/azext_vm_repair/tests/latest/test_repair_commands.py index 406ffcda440..77b6699d99a 100644 --- a/src/vm-repair/azext_vm_repair/tests/latest/test_repair_commands.py +++ b/src/vm-repair/azext_vm_repair/tests/latest/test_repair_commands.py @@ -555,3 +555,136 @@ def test_vmrepair_WinManagedCreateRestore(self, resource_group): vms = self.cmd('vm list -g {rg} -o json').get_output_in_json() source_vm = vms[0] assert source_vm['storageProfile']['osDisk']['name'] == result['copied_disk_name'] + +class LinuxSinglepassKekEncryptedManagedDiskWithRHEL8DistroCreateRestoreTest(LiveScenarioTest): + + @ResourceGroupPreparer(location='westus2') + def test_vmrepair_LinuxSinglepassKekEncryptedManagedDiskCreateRestore(self, resource_group): + self.kwargs.update({ + 'vm': 'vm1', + 'kv': self.create_random_name(prefix='cli', length=8), + 'key': 'key1' + }) + + # Create test VM + self.cmd('vm create -g {rg} -n {vm} --image UbuntuLTS --admin-username azureadmin --admin-password !Passw0rd2018 --size Standard_D2s_v3') + vms = self.cmd('vm list -g {rg} -o json').get_output_in_json() + # Something wrong with vm create command if it fails here + assert len(vms) == 1 + + # Create key vault + self.cmd('keyvault create -n {kv} -g {rg} --enabled-for-disk-encryption True') + + # Check keyvault + keyvault = self.cmd('keyvault list -g {rg} -o json').get_output_in_json() + assert len(keyvault) == 1 + + # Create key + self.cmd('keyvault key create --vault-name {kv} --name {key} --protection software') + + # Check key + key = self.cmd('keyvault key list --vault-name {kv} -o json').get_output_in_json() + assert len(key) == 1 + + # Enable encryption + self.cmd('vm encryption enable -g {rg} -n {vm} --disk-encryption-keyvault {kv} --key-encryption-key {key}') + # Add buffer time for encryption settings to be set + time.sleep(300) + + # Test create + result = self.cmd('vm repair create -g {rg} -n {vm} --repair-username azureadmin --repair-password !Passw0rd2018 --distro rhel8 --unlock-encrypted-vm -o json').get_output_in_json() + assert result['status'] == STATUS_SUCCESS, result['error_message'] + + # Check repair VM + repair_vms = self.cmd('vm list -g {} -o json'.format(result['repair_resource_group'])).get_output_in_json() + assert len(repair_vms) == 1 + repair_vm = repair_vms[0] + # Check attached data disk + assert repair_vm['storageProfile']['dataDisks'][0]['name'] == result['copied_disk_name'] + + # Call Restore + self.cmd('vm repair restore -g {rg} -n {vm} --yes') + + # Check swapped OS disk + vms = self.cmd('vm list -g {rg} -o json').get_output_in_json() + source_vm = vms[0] + assert source_vm['storageProfile']['osDisk']['name'] == result['copied_disk_name'] + +class LinuxSinglepassNoKekEncryptedManagedDiskWithSLES15CreateRestoreTest(LiveScenarioTest): + + @ResourceGroupPreparer(location='westus2') + def test_vmrepair_LinuxSinglepassNoKekEncryptedManagedDiskCreateRestoreTest(self, resource_group): + self.kwargs.update({ + 'vm': 'vm1', + 'kv': self.create_random_name(prefix='cli', length=8), + }) + + # Create test VM + self.cmd('vm create -g {rg} -n {vm} --image UbuntuLTS --admin-username azureadmin --admin-password !Passw0rd2018 --size Standard_D2s_v3') + vms = self.cmd('vm list -g {rg} -o json').get_output_in_json() + # Something wrong with vm create command if it fails here + assert len(vms) == 1 + + # Create key vault + self.cmd('keyvault create -n {kv} -g {rg} --enabled-for-disk-encryption True') + + # Check keyvault + keyvault = self.cmd('keyvault list -g {rg} -o json').get_output_in_json() + assert len(keyvault) == 1 + + # Enable encryption + self.cmd('vm encryption enable -g {rg} -n {vm} --disk-encryption-keyvault {kv}') + # Add buffer time for encryption settings to be set + time.sleep(300) + + # Test create + result = self.cmd('vm repair create -g {rg} -n {vm} --repair-username azureadmin --repair-password !Passw0rd2018 --distro sles15 --unlock-encrypted-vm -o json').get_output_in_json() + assert result['status'] == STATUS_SUCCESS, result['error_message'] + + # Check repair VM + repair_vms = self.cmd('vm list -g {} -o json'.format(result['repair_resource_group'])).get_output_in_json() + assert len(repair_vms) == 1 + repair_vm = repair_vms[0] + # Check attached data disk + assert repair_vm['storageProfile']['dataDisks'][0]['name'] == result['copied_disk_name'] + + # Call Restore + self.cmd('vm repair restore -g {rg} -n {vm} --yes') + + # Check swapped OS disk + vms = self.cmd('vm list -g {rg} -o json').get_output_in_json() + source_vm = vms[0] + assert source_vm['storageProfile']['osDisk']['name'] == result['copied_disk_name'] + +class LinuxManagedDiskCreateRestoreTestwithOracle8andpublicip(LiveScenarioTest): + + @ResourceGroupPreparer(location='westus2') + def test_vmrepair_LinuxManagedCreateRestore(self, resource_group): + self.kwargs.update({ + 'vm': 'vm1' + }) + + # Create test VM + self.cmd('vm create -g {rg} -n {vm} --image UbuntuLTS --admin-username azureadmin --admin-password !Passw0rd2018') + vms = self.cmd('vm list -g {rg} -o json').get_output_in_json() + # Something wrong with vm create command if it fails here + assert len(vms) == 1 + + # Test create + result = self.cmd('vm repair create -g {rg} -n {vm} --repair-username azureadmin --repair-password !Passw0rd2018 --distro oracle8 --associate-public-ip -o json').get_output_in_json() + assert result['status'] == STATUS_SUCCESS, result['error_message'] + + # Check repair VM + repair_vms = self.cmd('vm list -g {} -o json'.format(result['repair_resource_group'])).get_output_in_json() + assert len(repair_vms) == 1 + repair_vm = repair_vms[0] + # Check attached data disk + assert repair_vm['storageProfile']['dataDisks'][0]['name'] == result['copied_disk_name'] + + # Call Restore + self.cmd('vm repair restore -g {rg} -n {vm} --yes') + + # Check swapped OS disk + vms = self.cmd('vm list -g {rg} -o json').get_output_in_json() + source_vm = vms[0] + assert source_vm['storageProfile']['osDisk']['name'] == result['copied_disk_name'] diff --git a/src/vm-repair/setup.py b/src/vm-repair/setup.py index 3f516a87aa3..b634d98340c 100644 --- a/src/vm-repair/setup.py +++ b/src/vm-repair/setup.py @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "0.4.1" +VERSION = "0.4.2" CLASSIFIERS = [ 'Development Status :: 4 - Beta', From dfd7755f73ee65d6d8155695dc89782b8df7baa3 Mon Sep 17 00:00:00 2001 From: Ibrahim Abedalghafer Date: Tue, 19 Apr 2022 07:36:41 +0000 Subject: [PATCH 13/13] updated the history and setup file --- src/vm-repair/HISTORY.rst | 4 ++++ src/vm-repair/setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vm-repair/HISTORY.rst b/src/vm-repair/HISTORY.rst index 722cba76e07..baf2df59ae1 100644 --- a/src/vm-repair/HISTORY.rst +++ b/src/vm-repair/HISTORY.rst @@ -2,6 +2,10 @@ Release History =============== +0.4.3 +++++++ +Adding a new distro option for creating the recovery VM, adding the detect for gen2 Linux machine and create a gen2 recovery VM + 0.4.2 ++++++ Linux only: Fixing duplicated UUID issue. Data disk gets attached only after VM got created. diff --git a/src/vm-repair/setup.py b/src/vm-repair/setup.py index b634d98340c..7c0988d40eb 100644 --- a/src/vm-repair/setup.py +++ b/src/vm-repair/setup.py @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "0.4.2" +VERSION = "0.4.3" CLASSIFIERS = [ 'Development Status :: 4 - Beta',