[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/githubnemo/python-sandbox/master/create-python-sandbox [Back]  [Original]

#!/usr/bin/python3

import os
from string import Template


DEFAULT_FIREJAIL_PATH = os.path.join(os.path.expanduser('~'), '.config', 'firejail')
DEFAULT_TEMPLATE_PATH = os.path.join(
    os.path.dirname(os.path.realpath(__file__)),
    'python-env-template.profile',
)
DEFAULT_ENVS_PATH = os.path.join(os.path.expanduser('~'), 'envs')


class ProfileTemplate(Template):
    delimiter = ''


def read_template(path):
    with open(path) as f:
        return ProfileTemplate(f.read())


def write_profile(path, content):
    with open(path, 'w') as f:
        f.write(content)


def write_sandbox_dotfile(sandbox_name, working_dir):
    """This allows for shells to automatically enable the
    sandbox once they find the file.
    """
    path = os.path.join(working_dir, '.python-sandbox')
    with open(path, 'w') as f:
        f.write(sandbox_name + '\n')
    return path


def resolve_working_dir(working_dir):
    """Make sure to get an absolute path or raise an error.
    For example, if "." is supplied, it should resolve in the
    current working dir as an absolute path since `.` would
    not be valid as working dir in the template.
    """
    return os.path.abspath(working_dir)


def resolve_env_dir():
    """Make sure that the user can permanently overwrite the place
    where python environments are assumed to reside by the firejail
    profile.

    Method: Set `PYSANDBOX_ENVS_PATH` environment variable.
    """
    return os.environ.get('PYSANDBOX_ENVS_PATH', DEFAULT_ENVS_PATH)


def main(args):
    print(f'Loading template {args.template}.')

    working_dir = resolve_working_dir(args.working_dir)

    template_str = read_template(args.template)
    profile_str = template_str.substitute({
        'sandbox_name': args.sandbox_name,
        'working_dir': working_dir,
        'env_dir': resolve_env_dir(),
        'HOME': os.path.expanduser('~'),
    })

    if not os.path.exists(DEFAULT_FIREJAIL_PATH):
        os.makedirs(DEFAULT_FIREJAIL_PATH, exist_ok=True)

    profile_name = f'python-env-{args.sandbox_name}.profile'
    profile_path = os.path.join(DEFAULT_FIREJAIL_PATH, profile_name)

    if os.path.exists(profile_path) and not args.force:
        print('Profile already exists. Aborting.')
        return 1

    write_profile(profile_path, profile_str)

    sandbox_dotfile = write_sandbox_dotfile(
        args.sandbox_name,
        working_dir,
    )

    print(f"Written profile to {profile_path}.")
    print(f"Written {args.sandbox_name} to {sandbox_dotfile}.")
    print("")
    print(f"""Start your sandbox by running

    firejail --profile=python-env-{args.sandbox_name} --tab bash

""")


if __name__ == "__main__":
    import sys
    from argparse import ArgumentParser
    parser = ArgumentParser(
        description="""Create a new python sandbox profile in the firejail
configuration directory given the name of the sandbox
and it's working directory (which gets full read-write)
access. The tool automatically places a `.python-sandbox` file with the
sandbox's name in the working directory.

For venv/conda/... environments, by default ~/envs/ is allowed.
To override the default directory where environments are supposed to be
stored, set the PYSANDBOX_ENVS_PATH environment variable.
"""
    )
    parser.add_argument('sandbox_name', type=str, help="name of sandbox (needs to be FS compatible)")
    parser.add_argument('working_dir', type=str, help="Working directory of the sandbox")
    parser.add_argument('--template', type=str, default=DEFAULT_TEMPLATE_PATH, help="Path to the firejail profile template")
    parser.add_argument('-f', '--force', action='store_true', help="Force overriding the sandbox if it already exists")

    args = parser.parse_args()
    ret = main(args)
    sys.exit(ret or 0)

Web Proxy Viewer  |  New URL  |  Original Page