1414from azure .cli .command_modules .vm .custom import get_vm , _is_linux_os
1515from azure .cli .command_modules .storage .storage_url_helpers import StorageResourceIdentifier
1616from msrestazure .tools import parse_resource_id
17- from .exceptions import SkuDoesNotSupportHyperV
17+ from .exceptions import AzCommandError , SkuNotAvailableError , UnmanagedDiskCopyError , WindowsOsNotAvailableError , RunScriptNotFoundForIdError , SkuDoesNotSupportHyperV , ScriptReturnsError , SupportingResourceNotFoundError , CommandCanceledByUserError
1818
1919from .command_helper_class import command_helper
2020from .repair_utils import (
4545 _check_n_start_vm ,
4646 _check_existing_rg
4747)
48- from .exceptions import AzCommandError , SkuNotAvailableError , UnmanagedDiskCopyError , WindowsOsNotAvailableError , RunScriptNotFoundForIdError , SkuDoesNotSupportHyperV , ScriptReturnsError , SupportingResourceNotFoundError , CommandCanceledByUserError
48+ from .exceptions import AzCommandError , RunScriptNotFoundForIdError , SupportingResourceNotFoundError , CommandCanceledByUserError
4949logger = get_logger (__name__ )
5050
5151
5252def 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 ):
53+
54+ # log all the parameters
55+ logger .debug ('vm repair create command parameters: vm_name: %s, resource_group_name: %s, repair_password: %s, repair_username: %s, repair_vm_name: %s, copy_disk_name: %s, repair_group_name: %s, unlock_encrypted_vm: %s, enable_nested: %s, associate_public_ip: %s, distro: %s, yes: %s' , vm_name , resource_group_name , repair_password , repair_username , repair_vm_name , copy_disk_name , repair_group_name , unlock_encrypted_vm , enable_nested , associate_public_ip , distro , yes )
56+
5357 # Init command helper object
5458 command = command_helper (logger , cmd , 'vm repair create' )
5559 # Main command calling block
@@ -101,7 +105,8 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern
101105 create_repair_vm_command += ' --zone {zone}' .format (zone = zone )
102106
103107 # Create new resource group
104- if not _check_existing_rg (repair_group_name ):
108+ existing_rg = _check_existing_rg (repair_group_name )
109+ if not existing_rg :
105110 create_resource_group_command = 'az group create -l {loc} -n {group_name}' \
106111 .format (loc = source_vm .location , group_name = repair_group_name )
107112 logger .info ('Creating resource group for repair VM and its resources...' )
@@ -272,7 +277,7 @@ def create(cmd, vm_name, resource_group_name, repair_password=None, repair_usern
272277 if not command .is_status_success ():
273278 command .set_status_error ()
274279 return_dict = command .init_return_dict ()
275- if _check_existing_rg ( repair_group_name ) :
280+ if existing_rg :
276281 _clean_up_resources (repair_group_name , confirm = True )
277282 else :
278283 _clean_up_resources (repair_group_name , confirm = False )
@@ -305,9 +310,11 @@ def restore(cmd, vm_name, resource_group_name, disk_name=None, repair_vm_id=None
305310 # Fetch source and repair VM data
306311 source_vm = get_vm (cmd , resource_group_name , vm_name )
307312 is_managed = _uses_managed_disk (source_vm )
308- repair_vm_id = parse_resource_id (repair_vm_id )
309- repair_vm_name = repair_vm_id ['name' ]
310- repair_resource_group = repair_vm_id ['resource_group' ]
313+ if repair_vm_id :
314+ logger .info ('Repair VM ID: %s' , repair_vm_id )
315+ repair_vm_id = parse_resource_id (repair_vm_id )
316+ repair_vm_name = repair_vm_id ['name' ]
317+ repair_resource_group = repair_vm_id ['resource_group' ]
311318 source_disk = None
312319
313320 # MANAGED DISK
@@ -379,6 +386,10 @@ def restore(cmd, vm_name, resource_group_name, disk_name=None, repair_vm_id=None
379386
380387def run (cmd , vm_name , resource_group_name , run_id = None , repair_vm_id = None , custom_script_file = None , parameters = None , run_on_repair = False , preview = None ):
381388
389+ # log method parameters
390+ logger .debug ('vm repair run parameters: vm_name: %s, resource_group_name: %s, run_id: %s, repair_vm_id: %s, custom_script_file: %s, parameters: %s, run_on_repair: %s, preview: %s' ,
391+ vm_name , resource_group_name , run_id , repair_vm_id , custom_script_file , parameters , run_on_repair , preview )
392+
382393 # Init command helper object
383394 command = command_helper (logger , cmd , 'vm repair run' )
384395 LINUX_RUN_SCRIPT_NAME = 'linux-run-driver.sh'
@@ -397,9 +408,13 @@ def run(cmd, vm_name, resource_group_name, run_id=None, repair_vm_id=None, custo
397408 script_name = WINDOWS_RUN_SCRIPT_NAME
398409
399410 # If run_on_repair is False, then repair_vm is the source_vm (scripts run directly on source vm)
400- repair_vm_id = parse_resource_id (repair_vm_id )
401- repair_vm_name = repair_vm_id ['name' ]
402- repair_resource_group = repair_vm_id ['resource_group' ]
411+ if run_on_repair :
412+ repair_vm_id = parse_resource_id (repair_vm_id )
413+ repair_vm_name = repair_vm_id ['name' ]
414+ repair_resource_group = repair_vm_id ['resource_group' ]
415+ else :
416+ repair_vm_name = vm_name
417+ repair_resource_group = resource_group_name
403418
404419 run_command_params = []
405420 additional_scripts = []
@@ -650,3 +665,70 @@ def reset_nic(cmd, vm_name, resource_group_name, yes=False):
650665 return_dict = command .init_return_dict ()
651666
652667 return return_dict
668+
669+
670+ def repair_and_restore (cmd , vm_name , resource_group_name , repair_password = None , repair_username = None , repair_vm_name = None , copy_disk_name = None , repair_group_name = None ):
671+ from datetime import datetime
672+ import secrets
673+ import string
674+
675+ # Init command helper object
676+ command = command_helper (logger , cmd , 'vm repair repair-and-restore' )
677+
678+ password_length = 30
679+ password_characters = string .ascii_lowercase + string .digits + string .ascii_uppercase
680+ repair_password = '' .join (secrets .choice (password_characters ) for i in range (password_length ))
681+
682+ username_length = 20
683+ username_characters = string .ascii_lowercase + string .digits
684+ repair_username = '' .join (secrets .choice (username_characters ) for i in range (username_length ))
685+
686+ timestamp = datetime .utcnow ().strftime ('%Y%m%d%H%M%S' )
687+ repair_vm_name = ('repair-' + vm_name )[:14 ] + '_'
688+ copy_disk_name = vm_name + '-DiskCopy-' + timestamp
689+ repair_group_name = 'repair-' + vm_name + '-' + timestamp
690+ existing_rg = _check_existing_rg (repair_group_name )
691+
692+ create_out = create (cmd , vm_name , resource_group_name , repair_password , repair_username , repair_vm_name = repair_vm_name , copy_disk_name = copy_disk_name , repair_group_name = repair_group_name , associate_public_ip = False , yes = True )
693+
694+ # log create_out
695+ logger .info ('create_out: %s' , create_out )
696+
697+ repair_vm_name = create_out ['repair_vm_name' ]
698+ copy_disk_name = create_out ['copied_disk_name' ]
699+ repair_group_name = create_out ['repair_resource_group' ]
700+
701+ logger .info ('Running fstab run command' )
702+
703+ try :
704+ run_out = run (cmd , repair_vm_name , repair_group_name , run_id = 'linux-alar2' , parameters = ["fstab" ])
705+
706+ except Exception :
707+ command .set_status_error ()
708+ command .error_stack_trace = traceback .format_exc ()
709+ command .error_message = "Command failed when running fstab script."
710+ command .message = "Command failed when running fstab script."
711+ if existing_rg :
712+ _clean_up_resources (repair_group_name , confirm = True )
713+ else :
714+ _clean_up_resources (repair_group_name , confirm = False )
715+ return
716+
717+ # log run_out
718+ logger .info ('run_out: %s' , run_out )
719+
720+ if run_out ['script_status' ] == 'ERROR' :
721+ logger .error ('fstab script returned an error.' )
722+ if existing_rg :
723+ _clean_up_resources (repair_group_name , confirm = True )
724+ else :
725+ _clean_up_resources (repair_group_name , confirm = False )
726+ return
727+
728+ logger .info ('Running restore command' )
729+ show_vm_id = 'az vm show -g {g} -n {n} --query id -o tsv' \
730+ .format (g = repair_group_name , n = repair_vm_name )
731+
732+ repair_vm_id = _call_az_command (show_vm_id )
733+
734+ restore (cmd , vm_name , resource_group_name , copy_disk_name , repair_vm_id , yes = True )
0 commit comments