def sftp_upload(hostname, username, private_key_path, local_path, remote_path, **kwargs): """ uploads to sftp server :param hostname: :param username: :param private_key_path: :param local_path: :param remote_path: :param kwargs: :return: """ assert running_on_linux sftp_options = ['-o StrictHostKeyChecking=no' ] # todo: dynamic options creation kwargs.setdefault('dump_file', ir_log_dir + '/sftp_upload.txt') kwargs.setdefault('dump_file_rotate', True) # create batch_file batch_command = 'put {local} {remote}'.format(local=local_path, remote=remote_path) batch_file_path = write_to_tmp_file(batch_command) cmd = 'sftp -b {batch_file} -i {identity_file} {options} {username}@{hostname}'.format( hostname=hostname, username=username, batch_file=batch_file_path, identity_file=private_key_path, options=' '.join(sftp_options), ) ret = iexec(cmd, **kwargs) return ret
def sftp_download(hostname, username, password, remote_path, local_path, **kwargs): """ downloads from sftp server :param hostname: :param username: :param password: :param remote_path: :param local_path: :param kwargs: :return: """ assert running_on_linux sftp_options = ['-o StrictHostKeyChecking=no' ] # todo: dynamic options creation kwargs.setdefault('dump_file', ir_log_dir + '/sftp_download.txt') kwargs.setdefault('dump_file_rotate', True) check_makedir(os.path.dirname(local_path)) cmd = 'sshpass -p {password} sftp {options} {username}@{hostname}:{remote_path} {local_path}'.format( hostname=hostname, username=username, password=password, remote_path=remote_path, local_path=local_path, options=' '.join(sftp_options), ) ret = iexec(cmd, **kwargs) return ret
def query_windows_service(name, **kwargs): """query a service on windows""" kwargs.setdefault('to_console', False) ret = iexec('sc query {}'.format(name), **kwargs) return dict( mo.groups() for mo in [SERVICE_QUERY_KEY_VALUE_RE.search(line.strip()) for line in ret.out] if mo)
def remove_docker_image(image_id, force=False, **kwargs): kwargs.setdefault('to_console', False) kwargs.setdefault('trace_file', docker_trace_log) cmd = 'docker rmi' if force: cmd = '{} --force'.format(cmd) cmd = '{} {}'.format(cmd, image_id) return iexec(cmd, **kwargs)
def get_processes(name, log_id=None, **kwargs): kwargs.setdefault('to_console', False) kwargs.setdefault('show_log', False) kwargs.setdefault('trace_file', ir_artifact_dir + '/get_processes.trace.out') if running_on_windows: if kwargs.pop('partial', False): name += '*' collect_ret = iexec( 'tasklist /FI "IMAGENAME eq {}" /FO CSV'.format(name), **kwargs) procs = [row['Image Name'] for row in DictReader(collect_ret.out)] else: collect_ret = iexec('pgrep {} -l'.format(name), **kwargs) procs = [line.split()[-1] for line in collect_ret.out if line] write_file(ir_artifact_dir + '/get_procs.out', collect_ret.append_output(log_id), mode='a') return procs
def chmod(fpath, mode='0777', **kwargs): """use chmod on path""" assert running_on_linux kwargs.setdefault('to_console', False) kwargs.setdefault('log_as_trace', True) if os.path.isdir(fpath): cmd = 'chmod {m} -R {p}' else: cmd = 'chmod {m} {p}' return iexec(cmd.format(m=mode, p=fpath), **kwargs)
def remove_docker_container(container_id, force=False, volumes=True, **kwargs): kwargs.setdefault('to_console', False) kwargs.setdefault('trace_file', docker_trace_log) cmd = 'docker rm' if force: cmd = '{} --force'.format(cmd) if volumes: cmd = '{} --volumes'.format(cmd) cmd = '{} {}'.format(cmd, container_id) return iexec(cmd, **kwargs)
def copy_from_docker(container_id, src, dst, **kwargs): kwargs.setdefault('to_console', False) kwargs.setdefault('trace_file', docker_trace_log) log.debug('copying from docker: id={} src={} dst={}'.format(container_id, src, dst)) if os.path.isdir(dst): dir_to_make = dst else: dir_to_make = os.path.dirname(dst) check_makedir(dir_to_make) cmd = 'docker cp {container_id}:{src} {dst}'.format(container_id=container_id, src=src, dst=dst) return iexec(cmd, **kwargs)
def get_container_id_from_composition_service(composition_file, service_name, **kwargs): log.trace('getting container id from composition service: composition={} service={}'.format( composition_file, service_name )) cmd = 'docker-compose -f {composition_file} ps -q {service_name}'.format( composition_file=composition_file, service_name=service_name) ret = iexec(cmd, **kwargs) container_id = ret.out_string.strip() # todo: better detection of container id if not container_id: raise RuntimeError('Could not fetch container_id for composition service: composition={} service={}'.format( composition_file, service_name )) log.trace('found container id for composition service: container_id={} composition={} service={}'.format( container_id, composition_file, service_name)) return container_id
def toggle_service(name, action, **kwargs): """ Toggle a service :param name: service name :param action: start or stop or restart :param kwargs: any kwargs to pass to iexec :return: ExecResult object """ assert action in ['stop', 'start', 'restart'], 'Unknown action: {}'.format(action) kwargs.setdefault('to_console', False) kwargs.setdefault('trace_file', ir_log_dir + '/toggle_service.trace.txt') if running_on_windows: if action == 'restart': cmd = 'net stop {n} & net start {n}'.format(n=name) else: cmd = 'net {} {}'.format(action, name) else: cmd = 'service {} {}'.format(name, action) return iexec(cmd, **kwargs)
def kill_process(kill_all=False, pid=None, name=None, cmd_part=None, mode='psutil', children_only=False, myself=False, partial=False, signum='9', safe_kill=None, wait_time_after_kill=60, **kwargs): """ Kills a process by PID, Name, or Partial name. Can kill first matched process or all matched processes :param myself: :param children_only: :param wait_time_after_kill: :param safe_kill: :param signum: :param partial: :param pid: PID of the process to kill :param name: Name of the process to kill :param cmd_part: Partial command used to run the process to kill (cmd_part only works with psutil mode) :param kill_all: Specify as True to kill all processes, otherwise just first :param mode: Specify psutil or cmdline :return: True if process(s) were killed, False otherwise. """ # kwargs pkn = int(signum) # pkill num (signum) assert pkn in [9, 15] if myself: if pid: log.warn('killing process with "myself" flag overrides pid') pid = os.getpid() if children_only: if mode == 'cmdline': log.warn( 'killing process with "children only" flag overrides mode') mode = 'psutil' # verify params if not any([pid, name, cmd_part]): raise ValueError( 'Must supply at least one of [pid, name, cmd_part] as kwargs.') # make a param object for logs? sid = ' '.join([ '{}={}'.format(k, v) for k, v in { 'pid': pid, 'name': name, 'cmd_part': cmd_part }.items() if v ]) if mode not in ['psutil', 'cmdline']: log.warn( 'kill_process, invalid mode, (ignoring, using default): mode={}'. format(mode)) mode = 'psutil' # return value proc_was_killed = False if mode == 'psutil': # todo: simplify this horrible code try: import psutil except ImportError: psutil = None log.warn( 'Could not import psutil for kill_process, trying cmdline') mode = 'cmdline' else: log.trace( 'Iterating processes with psutil: kwrgs={}'.format(kwargs)) for proc in psutil.process_iter(): try: log.trace( 'examining process: pid={} name={} cmd_part={}'.format( int(proc.pid), proc.name(), proc.cmdline())) if ((pid and int(proc.pid) == int(pid)) or (name and proc.name() == name) or (cmd_part and cmd_part in subprocess.list2cmdline(proc.cmdline())) or (partial and name and name.lower() in proc.name().lower())): if safe_kill is not None and not safe_kill(proc.pid): continue try: log.trace( 'getting children of process: proc={}'.format( proc)) childrens = proc.children(recursive=True) log.trace( 'Killing procs: pid={} name={} ppid={} status={} cmdline={} children_only={} ' 'childrens={}'.format(proc.pid, proc.name, proc.ppid, proc.status, proc.cmdline, children_only, childrens)) for child in childrens: log.trace( 'examining child: child={} pid={} name={} cmd_part={}' .format(child, int(proc.pid), proc.name(), proc.cmdline())) if pkn == 9: child.kill() else: child.terminate() if not children_only: if pkn == 9: proc.kill() else: proc.terminate() except psutil.NoSuchProcess as nsp: log.trace( 'no such process error-in: msg={} kwargs={}'. format(nsp.msg, kwargs)) try: if not children_only: proc.wait(wait_time_after_kill) except psutil.TimeoutExpired as te: log.error( 'timeout waiting for proc to be killed: sid={} exc={}' .format(sid, te)) raise else: proc_was_killed = True if not kill_all: break except psutil.AccessDenied: continue except psutil.NoSuchProcess as nsp: log.trace( 'no such process error-out: msg={} kwargs={}'.format( nsp.msg, kwargs)) continue # process was not killed if not proc_was_killed: if name or pid: # fallback to cmdline (name or pid are mandatory for this mode) log.warn( 'failed to kill proc with psutil, falling back to cmdline: {}' .format(sid)) mode = 'cmdline' else: log.error('failed to kill proc with psutil: {}'.format(sid)) if mode == 'cmdline': if name: if partial: name += '*' cmd = 'taskkill /IM "{}" /F /T'.format( name) if running_on_windows else 'pkill -{} "{}"'.format( pkn, name) elif pid and ((safe_kill is None) or safe_kill(pid)): cmd = 'taskkill /PID "{}" /F /T'.format( pid) if running_on_windows else 'kill -{} "{}"'.format( pkn, pid) else: raise RuntimeError('This is impossible!') ret = iexec(cmd) if ret.rc == 0 or ret.rc == 1 and ret.contains('No such process'): proc_was_killed = True write_file(ir_artifact_dir + '/kill_proc.out', mode='a', contents='KWARGS={}\nRET={}\n\n'.format(kwargs, ret)) return proc_was_killed
def rm_rf(*paths, **kwargs): """Use rm -rf on the paths""" assert running_on_linux log.info('Cleaning paths with rm -rf: paths={}'.format(list(paths))) # note: perhaps add protection against certain paths? ('/') return iexec('rm -rf {}'.format(' '.join(paths)), **kwargs)
def docker_exec(container_id, cmd, **kwargs): log.debug('performing docker exec: id={} cmd={}'.format(container_id, cmd)) return iexec('docker exec {id} {cmd}'.format(id=container_id, cmd=cmd), **kwargs)
def copy_to_docker(container_id, src, dst, **kwargs): kwargs.setdefault('to_console', False) kwargs.setdefault('trace_file', docker_trace_log) log.debug('copying to docker: id={} src={} dst={}'.format(container_id, src, dst)) cmd = 'docker cp {src} {container_id}:{dst}'.format(container_id=container_id, src=src, dst=dst) return iexec(cmd, **kwargs)