Source code for mache.sync.diags

import argparse
import subprocess
import sys

from mache.machine_info import MachineInfo
from mache.permissions import update_permissions


[docs] def sync_diags( # noqa: C901 other, direction='to', machine=None, username=None, config_filename=None ): """ Synchronize diagnostics files between supported machines Parameters ---------- other : str The other machine to sync to or from direction : {'to', 'from'}, optional The direction to sync (to or from the other machine). machine : str, optional The name of this machine. If not provided, it will be detected automatically username : str, optional The username to use on the other machine config_filename : str, optional A config file to override default config options for the machine """ if direction not in ['to', 'from']: raise ValueError('The direction must be one of "to" or "from"') machine_info = MachineInfo(machine=machine) machine = machine_info.machine lcrc_machines = ['anvil', 'chrysalis'] if direction == 'to' and machine not in lcrc_machines: raise ValueError( f'You can only sync diagnostics to another machine ' f'from an LCRC machine: {", ".join(lcrc_machines)}' ) if direction == 'from' and other not in lcrc_machines: raise ValueError( f'You can only sync diagnostics from an LCRC ' f'machine: {", ".join(lcrc_machines)}' ) machine_config = machine_info.config if config_filename is not None: machine_config.read(config_filename) other_info = MachineInfo(machine=other) other_config = other_info.config hostname = other_config.get('sync', 'hostname') if other_config.has_option('sync', 'tunnel_hostname'): tunnel = other_config.get('sync', 'tunnel_hostname') else: tunnel = None if ( machine in lcrc_machines and other in lcrc_machines and machine != other ): raise ValueError( f'You should sync {machine} with itself since files are local' ) elif username is None: if direction == 'from': raise ValueError( 'For syncing to work properly, your LCRC username is required.' ) else: raise ValueError( f'For syncing to work properly, your {other} ' f'username is required.' ) if direction == 'from': source_config = other_config dest_config = machine_config else: source_config = machine_config dest_config = other_config public_diags = source_config.get('sync', 'public_diags') private_diags = source_config.get('sync', 'private_diags') dest_diags = dest_config.get('diagnostics', 'base_path') if machine == other: prefix = '' else: if username is not None: prefix = f'{username}@{hostname}:' else: prefix = f'{hostname}:' if direction == 'from': public_diags = f'{prefix}{public_diags}' private_diags = f'{prefix}{private_diags}' else: dest_diags = f'{prefix}{dest_diags}' if not public_diags.endswith('/'): public_diags = f'{public_diags}/' if not private_diags.endswith('/'): private_diags = f'{private_diags}/' args = [ 'rsync', '--verbose', '--recursive', '--times', '--links', '--compress', '--progress', '--update', '--no-perms', '--omit-dir-times', ] if tunnel: args.append(f'--rsync-path=ssh {tunnel} rsync') public_args = args + [public_diags, dest_diags] private_args = args + [private_diags, dest_diags] print(f'running: {" ".join(public_args)}') try: subprocess.check_call(public_args) except subprocess.CalledProcessError: print( 'Warning: Some transfer operations failed for public diagnostics.' ) print('') print(f'running: {" ".join(private_args)}') try: subprocess.check_call(private_args) except subprocess.CalledProcessError: print( 'Warning: Some transfer operations failed for private diagnostics.' ) if direction == 'from': group = machine_config.get('diagnostics', 'group') print(f'Updating permissions on {dest_diags}:') update_permissions( base_paths=dest_diags, group=group, show_progress=True, group_writable=True, other_readable=True, ) print('Done.')
def main(): """ Defines the ``mache sync diags`` command """ parser = argparse.ArgumentParser( description='Synchronize diagnostics files between supported machines', usage=""" mache sync diags to <other> [<args>] or mache sync diags from <other> [<args>] To get help on an individual command, run: mache sync <command> --help """, ) parser.add_argument( 'direction', help='whether to sync "to" or "from" the other machine' ) parser.add_argument('other', help='The other machine to sync to or from') parser.add_argument( '-m', '--machine', dest='machine', help='The name of this machine. If not provided, it ' 'will be detected automatically', ) parser.add_argument( '-u', '--username', dest='username', help='The username to use on the other machine', ) parser.add_argument( '-f', '--config_file', dest='config_file', help='A config file to override default config ' 'options for the machine', ) args = parser.parse_args(sys.argv[3:]) sync_diags( args.other, args.direction, args.machine, args.username, args.config_file, )