forked from fkie-cad/FACT_docker
-
Notifications
You must be signed in to change notification settings - Fork 1
/
start.py
executable file
·170 lines (123 loc) · 6.48 KB
/
start.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env python3
import argparse
import grp
import os
import pathlib
import subprocess
def create_docker_mount_base_dir_with_correct_permissions(docker_mount_base_dir):
docker_gid = grp.getgrnam("docker").gr_gid
pathlib.Path(docker_mount_base_dir).mkdir(mode=0o770, parents=True, exist_ok=True)
os.chown(docker_mount_base_dir, -1, docker_gid)
os.chmod(docker_mount_base_dir, 0o770)
def pass_docker_socket_args(args):
docker_gid = grp.getgrnam("docker").gr_gid
docker_socket = os.getenv("DOCKER_HOST", default="/var/run/docker.sock")
return f"""\
--group-add {docker_gid} \
--mount type=bind,source={docker_socket},destination=/var/run/docker.sock \
"""
def mount_relevant_dirs_for_docker_args(docker_mount_base_dir):
return f"""\
--mount type=bind,source={docker_mount_base_dir},destination={docker_mount_base_dir} \
"""
def build(args):
cmd = f"docker build --rm -t {args.tag} ."
subprocess.run(cmd.split())
def pytest(args):
# We use the default docker-mount-base-dir because the user has no chance to change it when running the tests
create_docker_mount_base_dir_with_correct_permissions("/tmp/fact-docker-mount-base-dir/")
cmd = f"""docker run \
{pass_docker_socket_args(args)} \
{mount_relevant_dirs_for_docker_args("/tmp/fact-docker-mount-base-dir/")} \
-it \
--rm \
{args.image}
pytest {" ".join(args.pass_to_pytest)}
"""
subprocess.run(cmd.split())
def pull(args):
cmd = f"""docker run \
{pass_docker_socket_args(args)} \
--rm \
{args.image} pull-containers
"""
subprocess.run(cmd.split())
def remove(args):
cmd = f"docker rm {args.name}"
subprocess.run(cmd.split())
def run(args):
mongodb_path_gid = os.stat(args.wt_mongodb_path).st_gid
fw_data_path_gid = os.stat(args.fw_data_path).st_gid
# Always initialize the db on the first run
pathlib.Path(f"{args.wt_mongodb_path}/REINITIALIZE_DB").touch()
create_docker_mount_base_dir_with_correct_permissions(args.docker_mount_base_dir)
# TODO the config in the container might mismatch with what we have configured here
config_cmd = f"--mount type=bind,source={args.config_file},destination=/opt/FACT_core/src/config/main.cfg,ro=true"
if args.config_file is None:
config_cmd = ""
start_cmd = "start"
if args.branch is not None:
start_cmd = f"start-branch {args.branch}"
detach_flag = ""
if args.detach is not None:
detach_flag = "--detach"
cmd = f"""docker run {detach_flag} \
{pass_docker_socket_args(args)} \
{mount_relevant_dirs_for_docker_args(args.docker_mount_base_dir)} \
--name {args.name} \
--hostname {args.name} \
--group-add {mongodb_path_gid} \
--mount type=bind,source={args.wt_mongodb_path},destination=/media/data/fact_wt_mongodb \
--group-add {fw_data_path_gid} \
--mount type=bind,source={args.fw_data_path},destination=/media/data/fact_fw_data \
-p {args.port}:5000 \
{config_cmd} \
{args.image} {start_cmd}
"""
subprocess.run(cmd.split())
def start(args):
cmd = f"docker start -ai {args.name}"
subprocess.run(cmd.split())
def stop(args):
cmd = f"docker stop {args.name}"
subprocess.run(cmd.split())
def main():
parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda _: parser.print_usage())
subparsers = parser.add_subparsers()
build_p = subparsers.add_parser("build", help="Build the FACT image.", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
build_p.set_defaults(func=build)
build_p.add_argument("--tag", default="fkiecad/fact", help="The tag that the built image should have.")
pull_p = subparsers.add_parser("pull", help="Pull or build all neccessary docker containers required to run FACT.", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
pull_p.set_defaults(func=pull)
pull_p.add_argument("--image", default="fkiecad/fact", help="The FACT image name.")
remove_p = subparsers.add_parser("remove", help="Remove the container.", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
remove_p.set_defaults(func=remove)
remove_p.add_argument("--name", default="fact", help="The FACT container name.")
run_p = subparsers.add_parser("run", help="Create and run a FACT container.", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
run_p.set_defaults(func=run)
run_p.add_argument("--name", default="fact", help="The FACT container name.")
run_p.add_argument("--image", default="fkiecad/fact", help="The FACT image name.")
run_p.add_argument("--port", default=5000, help="The port that the webserver is listening on.")
# We default to the path that is set in the default config
run_p.add_argument("--docker-mount-base-dir", default="/tmp/fact-docker-mount-base-dir", help="Has to match docker-mount-base-dir in main.cfg")
# We cant reasonably choose a default path for the following arguments
run_p.add_argument("--wt-mongodb-path", required=True, help="The path to the fact_wt_mongodb directory on the host. The group must have rwx permissions.")
run_p.add_argument("--fw-data-path", required=True, help="Path to fact_fw_data directory on the host. The group must have rwx permissions.")
run_p.add_argument("--config-file", help="The file that contains the main.cfg FACT configuration. If ommited use the config in the container.")
run_p.add_argument("--branch", help="The branch of FACT to start")
run_p.add_argument("--detach", help="Indicates if FACT should start in second plane or not.")
start_p = subparsers.add_parser("start", help="Start container", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
start_p.set_defaults(func=start)
start_p.add_argument("--name", default="fact", help="The FACT container name")
stop_p = subparsers.add_parser("stop", help="Stop a running container", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
stop_p.set_defaults(func=stop)
stop_p.add_argument("--name", default="fact", help="The FACT container name")
pytest_p = subparsers.add_parser("pytest", help="Run pytest on FACT in the container. Additional arguments will be passed to pytest.", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
pytest_p.set_defaults(func=pytest)
pytest_p.add_argument("--image", default="fkiecad/fact", help="The FACT image name.")
pytest_p.add_argument("pass_to_pytest", nargs=argparse.REMAINDER, help=argparse.SUPPRESS)
args = parser.parse_args()
args.func(args)
if __name__ == "__main__":
main()