from subprocess import run, PIPE import os def exec_privilege_escalated_command(exec_string, *bindmounts): """Function to simulate sudo <command> by bind-mounting affected paths though docker. bindmounts is a list of `-v` style docker args e.g. `/home/user/elasticsearch-docker/tests/datadir1:/datadir1` """ bind_mount_cli_args = [] for bindarg in bindmounts: bind_mount_cli_args.append('-v') bind_mount_cli_args.append(bindarg) proc = run( ['docker', 'run', '--rm'] + bind_mount_cli_args + ['alpine', '/bin/sh', '-c', exec_string], stdout=PIPE) return proc def create_empty_dir(path, uid, gid): parent_dir = os.path.dirname(os.path.abspath(path)) base_newdir = os.path.basename(os.path.normpath(path)) proc = exec_privilege_escalated_command( 'mkdir /mount/{0} && chown {1}:{2} /mount/{0} && chmod 0770 /mount/{0}'.format(base_newdir, uid, gid), parent_dir + ":" + "/mount" ) if proc.returncode != 0: print("Unable to mkdir: {}".format(path)) return proc def delete_dir(path): parent_dir = os.path.dirname(os.path.abspath(path)) basedir_parent = os.path.basename(os.path.normpath(parent_dir)) basedir = os.path.basename(os.path.normpath(path)) proc = exec_privilege_escalated_command( 'cd /mount/{0} && rm -rf {1}'.format(basedir_parent, basedir), parent_dir + ":" + "/mount/{}".format(basedir_parent) ) if proc.returncode != 0: print("Unable to delete: {}".format(path)) return proc def recursive_chown(path, uid, gid): parent_dir = os.path.dirname(os.path.abspath(path)) basedir_parent = os.path.basename(os.path.normpath(parent_dir)) basedir = os.path.basename(os.path.normpath(path)) proc = exec_privilege_escalated_command( 'cd /mount/{0} && chown -R {1}:{2} {3} '.format(basedir_parent, uid, gid, basedir), parent_dir + ":" + "/mount/{}".format(basedir_parent) ) if proc.returncode != 0: print("Unable to delete: {}".format(path)) return proc