Compare commits
6 Commits
556b9d6b75
...
master
Author | SHA1 | Date | |
---|---|---|---|
911ffe1c92 | |||
f43ac055c2 | |||
2e16523810 | |||
d7052998c8 | |||
488dedb74e | |||
9340dbe720 |
239
otherworld
239
otherworld
@@ -93,6 +93,9 @@ def docker_commit (container, image_name):
|
|||||||
def docker_rm (container):
|
def docker_rm (container):
|
||||||
call(["docker", "rm", "-f", container])
|
call(["docker", "rm", "-f", container])
|
||||||
|
|
||||||
|
def docker_restart (container):
|
||||||
|
call(["docker", "restart", container])
|
||||||
|
|
||||||
def docker_rmi (container):
|
def docker_rmi (container):
|
||||||
call(["docker", "rmi", "-f", container])
|
call(["docker", "rmi", "-f", container])
|
||||||
|
|
||||||
@@ -132,6 +135,67 @@ def expand_user_volumes (volumes):
|
|||||||
|
|
||||||
return mappings
|
return mappings
|
||||||
|
|
||||||
|
def parse_command_line (command, config=None):
|
||||||
|
if config is None:
|
||||||
|
config = {
|
||||||
|
"actions": [],
|
||||||
|
"user_volumes": [],
|
||||||
|
"command_env": {}
|
||||||
|
}
|
||||||
|
|
||||||
|
while len(command) > 0:
|
||||||
|
arg = command[0]
|
||||||
|
if arg == "--quiet":
|
||||||
|
command = command[1:]
|
||||||
|
config['quiet'] = True
|
||||||
|
elif arg == "--notty":
|
||||||
|
command = command[1:]
|
||||||
|
config['tty'] = False
|
||||||
|
elif arg == "--rm":
|
||||||
|
config['actions'].append("rm")
|
||||||
|
command = command[1:]
|
||||||
|
elif arg == "--restart":
|
||||||
|
config['actions'].append("restart")
|
||||||
|
command = command[1:]
|
||||||
|
elif arg == "--rmi":
|
||||||
|
config['actions'].append("rmi")
|
||||||
|
command = command[1:]
|
||||||
|
elif arg == "--commit":
|
||||||
|
config['actions'].append("commit")
|
||||||
|
command = command[1:]
|
||||||
|
elif arg == "--sudo":
|
||||||
|
config['command_user'] = "root"
|
||||||
|
command = command[1:]
|
||||||
|
elif arg.startswith("--container="):
|
||||||
|
config['container_name'] = arg[len("--container="):]
|
||||||
|
command = command[1:]
|
||||||
|
elif arg.startswith("--image="):
|
||||||
|
config['image_name'] = arg[len("--image="):]
|
||||||
|
command = command[1:]
|
||||||
|
elif arg.startswith("--build="):
|
||||||
|
config['build_path'] = arg[len("--build="):]
|
||||||
|
command = command[1:]
|
||||||
|
elif arg.startswith("--volume="):
|
||||||
|
config['user_volumes'].append(arg[len("--volume="):])
|
||||||
|
command = command[1:]
|
||||||
|
elif arg.startswith("--env="):
|
||||||
|
env_pair = arg[len("--env="):]
|
||||||
|
(key, value) = env_pair.split("=", 1)
|
||||||
|
config['command_env'][key] = value
|
||||||
|
command = command[1:]
|
||||||
|
elif arg == "--cd":
|
||||||
|
config['command_workdir'] = os.getcwd()
|
||||||
|
command = command[1:]
|
||||||
|
elif arg.startswith("--cd="):
|
||||||
|
config['command_workdir'] = arg[len("--cd="):]
|
||||||
|
command = command[1:]
|
||||||
|
elif arg == "--pull":
|
||||||
|
command = command[1:]
|
||||||
|
config['pull'] = True
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
return (config, command)
|
||||||
|
|
||||||
def find_config_files (config_names):
|
def find_config_files (config_names):
|
||||||
config_files = []
|
config_files = []
|
||||||
directory = os.path.abspath(os.getcwd())
|
directory = os.path.abspath(os.getcwd())
|
||||||
@@ -159,91 +223,69 @@ def load_config_files (namespace, config_files):
|
|||||||
exec(config_code.read(), {}, namespace)
|
exec(config_code.read(), {}, namespace)
|
||||||
return dict([item for item in namespace.items() if item[0] in config_keys])
|
return dict([item for item in namespace.items() if item[0] in config_keys])
|
||||||
|
|
||||||
user = os.environ["USER"]
|
def init_command_as_list (command):
|
||||||
uid = int(check_output(["id", "-u"]).strip())
|
if isinstance(command, str):
|
||||||
image_name = os.environ.get("OW_IMAGE", None)
|
command = ["sh", "-c", command]
|
||||||
container_name = os.environ.get("OW_CONTAINER", f"{CONTAINER_NAME}_{user}")
|
return command
|
||||||
build_path = None
|
|
||||||
|
|
||||||
command = sys.argv[1:]
|
# parse options and command from command line
|
||||||
command_user = user
|
(command_line_options, command) = parse_command_line(sys.argv[1:])
|
||||||
user_volumes = USER_VOLUMES
|
actions = command_line_options['actions']
|
||||||
pull = False
|
|
||||||
|
|
||||||
actions = []
|
quiet = command_line_options.get("quiet", False)
|
||||||
|
def log (message, *args, **kwargs):
|
||||||
|
if quiet:
|
||||||
|
return
|
||||||
|
print(">> {}".format(message.format(*args, **kwargs)))
|
||||||
|
|
||||||
command_env = {}
|
|
||||||
command_workdir = None
|
|
||||||
|
|
||||||
quiet = False
|
|
||||||
tty = sys.stdout.isatty()
|
tty = sys.stdout.isatty()
|
||||||
|
|
||||||
# load config from files
|
# default config
|
||||||
config = load_config_files({
|
user = os.environ["USER"]
|
||||||
|
config = {
|
||||||
"command": command,
|
"command": command,
|
||||||
"user": user,
|
"user": user,
|
||||||
"uid": uid,
|
"uid": int(check_output(["id", "-u"]).strip()),
|
||||||
"command_user": command_user,
|
"command_user": user,
|
||||||
"image_name": image_name,
|
"image_name": os.environ.get("OW_IMAGE", None),
|
||||||
"container_name": container_name,
|
"container_name": command_line_options.get("container_name", os.environ.get("OW_CONTAINER", f"{CONTAINER_NAME}_{user}")),
|
||||||
"build_path": build_path,
|
"build_path": None,
|
||||||
"command_workdir": command_workdir,
|
"command_workdir": None,
|
||||||
"user_volumes": user_volumes,
|
"user_volumes": USER_VOLUMES,
|
||||||
"pull": pull,
|
"pull": False,
|
||||||
"command_env": command_env,
|
"command_env": {},
|
||||||
"cwd": os.getcwd(),
|
"cwd": os.getcwd(),
|
||||||
"tty": tty
|
"tty": sys.stdout.isatty(),
|
||||||
}, find_config_files([OTHERWORLD_CONFIG, "{}{}".format(container_name, OTHERWORLD_CONFIG)]))
|
"log": log,
|
||||||
locals().update(config)
|
"root_init_command": [],
|
||||||
|
"root_init_commmands": [],
|
||||||
|
"user_init_command": [],
|
||||||
|
"user_init_commands": [],
|
||||||
|
"docker_create_options": []
|
||||||
|
}
|
||||||
|
|
||||||
while len(command) > 0:
|
# load config from files
|
||||||
arg = command[0]
|
config_files = find_config_files([
|
||||||
if arg == "--quiet":
|
OTHERWORLD_CONFIG,
|
||||||
command = command[1:]
|
"{}{}".format(config['container_name'], OTHERWORLD_CONFIG)
|
||||||
quiet = True
|
])
|
||||||
elif arg == "--notty":
|
|
||||||
command = command[1:]
|
for config_file in config_files:
|
||||||
tty = False
|
log("Loading config file {}", config_file)
|
||||||
elif arg == "--rm":
|
|
||||||
actions.append("rm")
|
config = load_config_files(config, config_files)
|
||||||
command = command[1:]
|
|
||||||
elif arg == "--rmi":
|
# apply config from command line
|
||||||
actions.append("rmi")
|
for key, value in command_line_options.items():
|
||||||
command = command[1:]
|
if key == "user_volumes":
|
||||||
elif arg == "--commit":
|
config['user_volumes'] = config['user_volumes'] + value
|
||||||
actions.append("commit")
|
elif key == "command_env":
|
||||||
command = command[1:]
|
config['command_env'].update(value)
|
||||||
elif arg == "--sudo":
|
|
||||||
command_user = "root"
|
|
||||||
command = command[1:]
|
|
||||||
elif arg.startswith("--container="):
|
|
||||||
container_name = arg[len("--container="):]
|
|
||||||
command = command[1:]
|
|
||||||
elif arg.startswith("--image="):
|
|
||||||
image_name = arg[len("--image="):]
|
|
||||||
command = command[1:]
|
|
||||||
elif arg.startswith("--build="):
|
|
||||||
build_path = arg[len("--build="):]
|
|
||||||
command = command[1:]
|
|
||||||
elif arg.startswith("--volume="):
|
|
||||||
user_volumes.append(arg[len("--volume="):])
|
|
||||||
command = command[1:]
|
|
||||||
elif arg.startswith("--env="):
|
|
||||||
env_pair = arg[len("--env="):]
|
|
||||||
(key, value) = env_pair.split("=", 1)
|
|
||||||
command_env[key] = value
|
|
||||||
command = command[1:]
|
|
||||||
elif arg == "--cd":
|
|
||||||
command_workdir = os.getcwd()
|
|
||||||
command = command[1:]
|
|
||||||
elif arg.startswith("--cd="):
|
|
||||||
command_workdir = arg[len("--cd="):]
|
|
||||||
command = command[1:]
|
|
||||||
elif arg == "--pull":
|
|
||||||
command = command[1:]
|
|
||||||
pull = True
|
|
||||||
else:
|
else:
|
||||||
break
|
config[key] = value
|
||||||
|
|
||||||
|
# update local variables (FIXME: rewrite to avoid doing this)
|
||||||
|
locals().update(config)
|
||||||
|
|
||||||
if command_workdir:
|
if command_workdir:
|
||||||
user_volumes.append(command_workdir)
|
user_volumes.append(command_workdir)
|
||||||
@@ -252,19 +294,20 @@ if command_workdir:
|
|||||||
if actions:
|
if actions:
|
||||||
if "commit" in actions:
|
if "commit" in actions:
|
||||||
target_image_name = get_generated_image_name(container_name)
|
target_image_name = get_generated_image_name(container_name)
|
||||||
if not quiet:
|
log("Committing container: {} to image: {}", container_name, target_image_name)
|
||||||
print(f">> Committing container: {container_name} to image: {target_image_name}")
|
|
||||||
docker_commit(container_name, target_image_name)
|
docker_commit(container_name, target_image_name)
|
||||||
|
|
||||||
|
if "restart" in actions:
|
||||||
|
log("Restarting container: {}", container_name)
|
||||||
|
docker_restart(container_name)
|
||||||
|
|
||||||
if "rm" in actions:
|
if "rm" in actions:
|
||||||
if not quiet:
|
log("Removing container: {}", container_name)
|
||||||
print(f">> Removing container: {container_name}")
|
|
||||||
docker_rm(container_name)
|
docker_rm(container_name)
|
||||||
|
|
||||||
if "rmi" in actions:
|
if "rmi" in actions:
|
||||||
target_image_name = get_generated_image_name(container_name)
|
target_image_name = get_generated_image_name(container_name)
|
||||||
if not quiet:
|
log("Removing image: {}", target_image_name)
|
||||||
print(f">> Removing image: {target_image_name}")
|
|
||||||
docker_rmi(target_image_name)
|
docker_rmi(target_image_name)
|
||||||
|
|
||||||
if not command:
|
if not command:
|
||||||
@@ -285,39 +328,45 @@ except Exception:
|
|||||||
image_name = get_generated_image_name(container_name)
|
image_name = get_generated_image_name(container_name)
|
||||||
try:
|
try:
|
||||||
docker_inspect(image_name)
|
docker_inspect(image_name)
|
||||||
if not quiet:
|
log("Using default otherworld image {}", image_name)
|
||||||
print(f">> Using default otherworld image {image_name}")
|
|
||||||
except Exception:
|
except Exception:
|
||||||
if not quiet:
|
log("Default otherworld image {} not found, falling back to {}", image_name, DEFAULT_IMAGE_NAME)
|
||||||
print(f">> Default otherworld image {image_name} not found, falling back to {DEFAULT_IMAGE_NAME}")
|
|
||||||
image_name = DEFAULT_IMAGE_NAME
|
image_name = DEFAULT_IMAGE_NAME
|
||||||
|
|
||||||
if pull:
|
if pull:
|
||||||
docker_pull(image_name)
|
docker_pull(image_name)
|
||||||
|
|
||||||
if not quiet:
|
log("Creating container: {} (using image: {})", container_name, image_name)
|
||||||
print(f">> Creating container: {container_name} (using image: {image_name})")
|
|
||||||
docker_create(
|
docker_create(
|
||||||
image_name,
|
image_name,
|
||||||
container_name,
|
container_name,
|
||||||
DOCKER_CREATE_OPTIONS + create_x11_mapping() + expand_user_volumes(user_volumes),
|
DOCKER_CREATE_OPTIONS + config.get("docker_create_options", []) + create_x11_mapping() + expand_user_volumes(user_volumes),
|
||||||
BACKGROUND_COMMAND, { OTHERWORLD_LABEL: user }
|
BACKGROUND_COMMAND, { OTHERWORLD_LABEL: user }
|
||||||
)
|
)
|
||||||
container = docker_inspect(container_name)[0]
|
container = docker_inspect(container_name)[0]
|
||||||
|
|
||||||
if not container["State"]["Running"]:
|
if not container["State"]["Running"]:
|
||||||
if not quiet:
|
log("Starting container: {}", container_name)
|
||||||
print(f">> Starting container: {container_name}")
|
|
||||||
docker_start(container_name)
|
docker_start(container_name)
|
||||||
container = docker_inspect(container_name)[0]
|
container = docker_inspect(container_name)[0]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
docker_get_user(container_name, user)
|
docker_get_user(container_name, user)
|
||||||
except Exception:
|
except Exception:
|
||||||
if not quiet:
|
log("Creating container user: {}", user)
|
||||||
print(f">> Creating container user: {user}")
|
|
||||||
docker_create_user(container_name, user, uid)
|
docker_create_user(container_name, user, uid)
|
||||||
|
|
||||||
if not quiet:
|
if config['root_init_command']:
|
||||||
print(f">> Welcome to {container_name} (IP {container['NetworkSettings']['IPAddress']})")
|
config['root_init_commands'].append(config['root_init_command'])
|
||||||
|
|
||||||
|
for command in config['root_init_commands']:
|
||||||
|
docker_exec(container_name, init_command_as_list(command), "root", command_env, tty, "/home/{}".format(command_user))
|
||||||
|
|
||||||
|
if config['user_init_command']:
|
||||||
|
config['user_init_commands'].append(config['user_init_command'])
|
||||||
|
|
||||||
|
for command in config['user_init_commands']:
|
||||||
|
docker_exec(container_name, init_command_as_list(command), command_user, command_env, tty, "/home/{}".format(command_user))
|
||||||
|
|
||||||
|
log("Welcome to {} (IP {})", container_name, container['NetworkSettings']['IPAddress'])
|
||||||
docker_exec(container_name, command, command_user, command_env, tty, command_workdir)
|
docker_exec(container_name, command, command_user, command_env, tty, command_workdir)
|
||||||
|
Reference in New Issue
Block a user