diff --git a/.bin/Scripts/functions/ddrescue.py b/.bin/Scripts/functions/ddrescue.py index ba65d933..2d1c2d3b 100644 --- a/.bin/Scripts/functions/ddrescue.py +++ b/.bin/Scripts/functions/ddrescue.py @@ -277,6 +277,7 @@ class RecoveryState(): if mode not in ('clone', 'image'): raise GenericError('Unsupported mode') self.get_smart_source() + self.set_working_dir() def add_block_pair(self, source, dest): """Run safety checks and append new BlockPair to internal list.""" @@ -469,9 +470,6 @@ class RecoveryState(): def self_checks(self): """Run self-checks and update state values.""" cmd = ['findmnt', '--json', '--target', os.getcwd()] - map_allowed_fstypes = RECOMMENDED_FSTYPES.copy() - map_allowed_fstypes.extend(['cifs', 'ext2', 'vfat']) - map_allowed_fstypes.sort() json_data = get_json_from_command(cmd) # Abort if json_data is empty @@ -483,12 +481,12 @@ class RecoveryState(): fstype = json_data.get( 'filesystems', [{}])[0].get( 'fstype', 'unknown') - if fstype not in map_allowed_fstypes: + if fstype not in RECOMMENDED_MAP_FSTYPES: print_error( "Map isn't being saved to a recommended filesystem ({})".format( fstype.upper())) print_info('Recommended types are: {}'.format( - ' / '.join(map_allowed_fstypes).upper())) + ' / '.join(RECOMMENDED_MAP_FSTYPES).upper())) print_standard(' ') if not ask('Proceed anyways? (Strongly discouraged)'): raise GenericAbort() @@ -525,6 +523,37 @@ class RecoveryState(): elif self.current_pass == 2: self.current_pass_str = '3 "Scraping bad areas"' + def set_working_dir(self): + """Set working dir to MAP_DIR if possible. + + NOTE: This is to help ensure the map file + is saved to non-volatile storage.""" + map_dir = '{}/{}'.format(MAP_DIR, global_vars['Date-Time']) + + # Get Ticket ID + # TODO + # map_dir = '{}/{}_{}'.format(MAP_DIR, ticket_id, ticket_name) + + # Mount backup shares + mount_backup_shares(read_write=True) + + # Get MAP_DIR filesystem type + # NOTE: If the backup share fails to mount then this will + # likely be the type of / + cmd = [ + 'findmnt', + '--noheadings', + '--target', MAP_DIR, + '--output', 'FSTYPE', + ] + result = run_program(cmd, check=False, encoding='utf-8', errors='ingnore') + map_dir_type = result.stdout.strip().lower() + + # Change working dir if map_dir_type is acceptable + if map_dir_type in RECOMMENDED_MAP_FSTYPES: + os.makedirs(map_dir, exist_ok=True) + os.chdir(map_dir) + def update_etoc(self): """Search ddrescue output for the current EToC, returns str.""" now = datetime.datetime.now(tz=self.timezone) @@ -775,7 +804,6 @@ def is_writable_filesystem(dir_obj): def menu_ddrescue(source_path, dest_path, run_mode): """ddrescue menu.""" - map_dir = '{}/{}'.format(MAP_DIR, global_vars['Date-Time']) source = None dest = None if source_path: @@ -792,17 +820,6 @@ def menu_ddrescue(source_path, dest_path, run_mode): dest = select_path(skip_device=source) dest.self_check() - # Get Ticket ID - # TODO - # map_dir = '{}/{}_{}'.format(MAP_DIR, ticket_id, ticket_name) - - # Mount backup shares - mount_backup_shares(read_write=True) - - # Move to safe working dir - os.makedirs(map_dir, exist_ok=True) - os.chdir(map_dir) - # Build BlockPairs state = RecoveryState(run_mode, source, dest) if run_mode == 'clone': diff --git a/.bin/Scripts/settings/ddrescue.py b/.bin/Scripts/settings/ddrescue.py index 8f0db99c..559fdbe4 100644 --- a/.bin/Scripts/settings/ddrescue.py +++ b/.bin/Scripts/settings/ddrescue.py @@ -7,6 +7,7 @@ from collections import OrderedDict # General MAP_DIR = '/Backups/Anaconda' RECOMMENDED_FSTYPES = ['ext3', 'ext4', 'xfs'] +RECOMMENDED_MAP_FSTYPES = ['cifs', 'ext2', 'ext3', 'ext4', 'vfat', 'xfs'] USAGE = """ {script_name} clone [source [destination]] {script_name} image [source [destination]] (e.g. {script_name} clone /dev/sda /dev/sdb)