Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Vm-repair] Vm repair bug fixes #5451

Merged
merged 31 commits into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b7ee3d9
Adding code for unlock and added encryptformatall
Jul 7, 2020
a767bd7
removing temp files
Jul 7, 2020
14f0244
Changes to logging and logic
Jul 17, 2020
bd7d445
Merge pull request #1 from jofrance/alpha
jofrance Jul 18, 2020
07e7ace
Fixing code for data disk detection on RedHat
Aug 15, 2020
ad946b2
Merge pull request #2 from jofrance/alpha
jofrance Aug 17, 2020
9342e13
add NF for finding the data disk with awk
Aug 25, 2020
f455fe2
Adding error traps to allow stderr to be printed
Aug 31, 2020
fe9ae58
Merge pull request #3 from jofrance/alpha
jofrance Aug 31, 2020
f8ff6ab
Merge remote-tracking branch 'upstream/master'
Sep 16, 2020
5b9b43f
Merge branch 'master' of https://github.com/Azure/azure-cli-extensions
Sep 16, 2020
2497ff0
add utils again
Sep 16, 2020
4c97088
adding logic for detecting BEK volume and mounting it
Oct 9, 2020
d9bf8be
Adding suppression of errors to stdout
Nov 12, 2020
082b3a1
Merge pull request #5 from jofrance/Beta
jofrance Nov 12, 2020
7ad8931
Merge branch 'master' of https://github.com/Azure/azure-cli-extensions
jofrance Nov 13, 2020
40ab793
Merge branch 'master' of https://github.com/Azure/azure-cli-extensions
jofrance Jan 19, 2021
88577d9
Merge branch 'master' of https://github.com/Azure/azure-cli-extensions
jofrance Jan 19, 2021
6186a6b
Merge branch 'Azure:main' into master
jofrance Aug 17, 2022
a791bfd
fixing script to unlock on ADE
jofrance Aug 17, 2022
b8797d1
updating unlock script
jofrance Aug 17, 2022
289b1f9
updating unlock script
jofrance Aug 17, 2022
c596310
Merge branch 'Azure:main' into master
jofrance Aug 18, 2022
f29dffa
change format query tag validation to lower case
jofrance Aug 18, 2022
8a1fc63
Merge branch 'master' of github.com:jofrance/azure-cli-extensions
jofrance Aug 18, 2022
8e49f5e
add second validation for tag casing
jofrance Aug 19, 2022
477673d
fixes
haagha Oct 14, 2022
c52cd79
Merge remote-tracking branch 'jofrance/master' into vmrepairfixes
haagha Oct 14, 2022
da3e88e
adding help
haagha Oct 14, 2022
2f9776a
fixing static analysis
haagha Oct 18, 2022
13b2bc2
history and bump version
haagha Oct 24, 2022
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
1 change: 1 addition & 0 deletions src/vm-repair/azext_vm_repair/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def load_arguments(self, _):
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 (rhel7|rhel8|suse12|ubuntu20|centos7|oracle7)')
c.argument('yes', help='Option to skip associate_public_ip prompt and confirm yes to it in no Tty mode')
haagha marked this conversation as resolved.
Show resolved Hide resolved

with self.argument_context('vm repair restore') as c:
c.argument('repair_vm_id', help='Repair VM resource id.')
Expand Down
4 changes: 2 additions & 2 deletions src/vm-repair/azext_vm_repair/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def validate_create(cmd, namespace):
# Validate vm password
validate_vm_password(namespace.repair_password, is_linux)
# Prompt input for public ip usage
if not namespace.associate_public_ip:
if (not namespace.associate_public_ip) and (not namespace.yes):
_prompt_public_ip(namespace)


Expand Down Expand Up @@ -313,7 +313,7 @@ def fetch_repair_vm(namespace):
# Find repair VM
tag = _get_repair_resource_tag(namespace.resource_group_name, namespace.vm_name)
try:
find_repair_command = 'az resource list --tag {tag} --query "[?type==\'microsoft.compute/virtualmachines\']" -o json' \
find_repair_command = 'az resource list --tag {tag} --query "[?type==\'microsoft.compute/virtualmachines\' || type==\'Microsoft.Compute/virtualMachines\']" -o json' \
.format(tag=tag)
logger.info('Searching for repair-vm within subscription...')
output = _call_az_command(find_repair_command)
Expand Down
48 changes: 25 additions & 23 deletions src/vm-repair/azext_vm_repair/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from azure.cli.command_modules.vm.custom import get_vm, _is_linux_os
from azure.cli.command_modules.storage.storage_url_helpers import StorageResourceIdentifier
from msrestazure.tools import parse_resource_id
from .exceptions import SkuDoesNotSupportHyperV

from .command_helper_class import command_helper
from .repair_utils import (
Expand All @@ -39,13 +40,15 @@
_select_distro_linux_gen2,
_set_repair_map_url,
_is_gen2,
_unlock_encrypted_vm_run,
_create_repair_vm,
_check_n_start_vm
)
from .exceptions import AzCommandError, SkuNotAvailableError, UnmanagedDiskCopyError, WindowsOsNotAvailableError, RunScriptNotFoundForIdError, SkuDoesNotSupportHyperV, ScriptReturnsError, SupportingResourceNotFoundError, CommandCanceledByUserError
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, 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, distro='ubuntu', yes=False):
# Init command helper object
command = command_helper(logger, cmd, 'vm repair create')
# Main command calling block
Expand All @@ -64,13 +67,12 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern
created_resources = []

# Fetch OS image urn and set OS type for disk create
if is_linux:
if is_linux and _uses_managed_disk(source_vm):
# os_image_urn = "UbuntuLTS"
os_type = 'Linux'
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)
else:
os_image_urn = _select_distro_linux(distro)
Expand Down Expand Up @@ -125,31 +127,31 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern
# Copy OS Disk
logger.info('Copying OS disk of source VM...')
copy_disk_id = _call_az_command(copy_disk_command).strip('\n')
# For Linux the disk gets not attached at VM creation time. To prevent an incorrect boot state it is required to attach the disk after the VM got created.
if not is_linux:
# Add copied OS Disk to VM creat command so that the VM is created with the disk attached
create_repair_vm_command += ' --attach-data-disks {id}'.format(id=copy_disk_id)
# Validate create vm create command to validate parameters before runnning copy disk command
validate_create_vm_command = create_repair_vm_command + ' --validate'
logger.info('Validating VM template before continuing...')
_call_az_command(validate_create_vm_command, secure_params=[repair_password, repair_username])
# Create repair VM
logger.info('Creating repair VM...')
_call_az_command(create_repair_vm_command, secure_params=[repair_password, repair_username])

if is_linux:
# Attach copied managed disk to new vm
# Create VM according to the two conditions: is_linux, unlock_encrypted_vm
# Only in the case of a Linux VM without encryption the data-disk gets attached after VM creation.
# This is required to prevent an incorrect boot due to an UUID mismatch
if not is_linux:
# windows
_create_repair_vm(copy_disk_id, create_repair_vm_command, repair_password, repair_username)

if not is_linux and unlock_encrypted_vm:
# windows with encryption
_create_repair_vm(copy_disk_id, create_repair_vm_command, repair_password, repair_username)
_unlock_encrypted_vm_run(repair_vm_name, repair_group_name, is_linux)

if is_linux and unlock_encrypted_vm:
# linux with encryption
_create_repair_vm(copy_disk_id, create_repair_vm_command, repair_password, repair_username)
_unlock_encrypted_vm_run(repair_vm_name, repair_group_name, is_linux)

if is_linux and (not unlock_encrypted_vm):
# linux without encryption
_create_repair_vm(copy_disk_id, create_repair_vm_command, repair_password, repair_username, fix_uuid=True)
logger.info('Attaching copied disk to repair VM as data disk...')
attach_disk_command = "az vm disk attach -g {g} --name {disk_id} --vm-name {vm_name} ".format(g=repair_group_name, disk_id=copy_disk_id, vm_name=repair_vm_name)
_call_az_command(attach_disk_command)

# Handle encrypted VM cases
if unlock_encrypted_vm:
stdout, stderr = _unlock_singlepass_encrypted_disk(repair_vm_name, repair_group_name, is_linux)
logger.debug('Unlock script STDOUT:\n%s', stdout)
if stderr:
logger.warning('Encryption unlock script error was generated:\n%s', stderr)

# UNMANAGED DISK
else:
logger.info('Source VM uses unmanaged disks. Creating repair VM with unmanaged disks.\n')
Expand Down
18 changes: 17 additions & 1 deletion src/vm-repair/azext_vm_repair/repair_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def _check_linux_hyperV_gen(source_vm):
.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')
logger.info('Checking if source VM is 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))
Expand Down Expand Up @@ -682,3 +682,19 @@ def _get_function_param_dict(frame):
if param in values:
values[param] = '********'
return values


def _unlock_encrypted_vm_run(repair_vm_name, repair_group_name, is_linux):
stdout, stderr = _unlock_singlepass_encrypted_disk(repair_vm_name, repair_group_name, is_linux)
logger.debug('Unlock script STDOUT:\n%s', stdout)
if stderr:
logger.warning('Encryption unlock script error was generated:\n%s', stderr)


def _create_repair_vm(copy_disk_id, create_repair_vm_command, repair_password, repair_username, fix_uuid=False):
if not fix_uuid:
create_repair_vm_command += ' --attach-data-disks {id}'.format(id=copy_disk_id)
logger.info('Validating VM template before continuing...')
_call_az_command(create_repair_vm_command + ' --validate', secure_params=[repair_password, repair_username])
logger.info('Creating repair VM...')
_call_az_command(create_repair_vm_command, secure_params=[repair_password, repair_username])
Loading