-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathentrypoint
executable file
·216 lines (170 loc) · 6.29 KB
/
entrypoint
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
This command takes one positional argument, `command`, which specifies whether
to initialize test repos locally, or to start an hg serve comand serving the
test repos.
"""
import argparse
import json
import logging
import subprocess
import sys
import os
from pathlib import Path
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
BASE_REPO_DIR = Path("/repos")
PHABRICATOR_URI = os.environ.get("PHABRICATOR_URI", "http://phabricator.test")
DO_ARCCONFIG = os.environ.get("ARCCONFIG", "").lower() in ("y", "1", "true")
BASE_ARC_CONFIG = {
"phabricator.uri": PHABRICATOR_URI,
"history.immutable": False,
}
# Add or remove entires from this list to create more or less test repos.
REPOS = [
# At the time of writing, test-repo is used in the "dev" instance for testing.
"test-repo",
# The repos below are used by the local conduit suite (phabricator and lando-api).
# If these values are changed here, the local phabricator SQL dump and the hardcoded
# repo values in `landoapi.repos` will need to be updated.
"first-repo",
"second-repo",
"third-repo",
]
# Create a config template for the `hg serve` command.
WEBDIR_CONF = f"""[paths]
/ = {BASE_REPO_DIR}/*"""
WEBDIR_CONF_PATH = BASE_REPO_DIR / "webdir.conf"
def init(args):
"""Perform initialization on the local dev environment.
Calls `create_repo` on a pre-defined list of repos, and sets up HG's web config.
Args:
args (argparse.Namespace): Additional arguments passed to `init` from the
command line.
"""
for repo in REPOS:
logging.info(f"Creating {repo}...")
create_repo(repo, DO_ARCCONFIG)
with WEBDIR_CONF_PATH.open("w") as f:
logging.info(f"Copying webdir conf to {WEBDIR_CONF_PATH}...")
f.write(WEBDIR_CONF)
logging.info("Done.")
def start(args):
"""Run a local mercurial web server instance with sshd in the background.
Args:
args (argparse.Namespace): Additional arguments passed to `start` from the
command line: hg_serve_port, sshd_port.
"""
if not args.no_init:
init(args)
if not args.no_ssh_auth:
authorize_ssh(args)
if not args.no_sshd:
logging.info(f"Starting sshd on port {args.sshd_port}...")
subprocess.run(["/usr/sbin/sshd", "-e", "-p", args.sshd_port])
logging.info(f"Starting hg serve on port {args.hg_serve_port}...")
subprocess.run(
[
"hg",
"serve",
"--port",
args.hg_serve_port,
"--accesslog",
"/dev/stdout",
"--errorlog",
"/dev/stderr",
"--webdir-conf",
WEBDIR_CONF_PATH,
],
cwd=BASE_REPO_DIR,
)
def authorize_ssh(args):
"""Copy an authorized public key from an environment variable to the filesystem.
Args:
args (argparse.Namespace): Additional arguments passed to `authorizer_ssh` from
the command line.
"""
ENV_KEY = "SSH_PUBLIC_KEY"
ssh_path = Path("~/.ssh").expanduser()
authorized_keys_path = ssh_path / "authorized_keys"
ssh_public_key = getattr(args, "public_key", os.environ.get(ENV_KEY))
if not ssh_public_key:
logging.warning(
"Public ssh key not passed as an argument or found in envioronment "
f"({ENV_KEY})."
)
return
logging.info(f"Removing {authorized_keys_path} if it exists...")
authorized_keys_path.unlink(missing_ok=True)
with authorized_keys_path.open("w") as f:
logging.info(f"Populating {authorized_keys_path} with key...")
f.write(ssh_public_key)
logging.info("Done.")
def create_repo(name, do_arcconfig=False):
"""Initialize a repo in the base directory with the provided name.
Args:
name (str): the name of the repo to initialize
"""
if not BASE_REPO_DIR.is_dir():
BASE_REPO_DIR.mkdir()
subprocess.call(["hg", "init", BASE_REPO_DIR / name])
with (BASE_REPO_DIR / name / "README").open("w") as f:
f.write(name)
if do_arcconfig:
with (BASE_REPO_DIR / name / ".arcconfig").open("w") as f:
config = BASE_ARC_CONFIG.copy()
config["repository.callsign"] = name.upper().replace("-", "")
json.dump(config, f)
subprocess.call(
["hg", "commit", "-A", "-m", "initial commit"], cwd=BASE_REPO_DIR / name,
)
subprocess.call(["hg", "phase", "--public", "-r", "."], cwd=BASE_REPO_DIR / name)
def create_parser():
parser = argparse.ArgumentParser()
commands = parser.add_subparsers(dest="command", title="commands")
command_parsers = {
init: commands.add_parser("init", help="create test repos"),
start: commands.add_parser("start", help="run an hg serve command locally"),
authorize_ssh: commands.add_parser(
"authorize-ssh", help="authorize ssh client via an env var"
),
}
for func, sub_parser in command_parsers.items():
sub_parser.set_defaults(func=func)
command_parsers[start].add_argument(
"--hg-serve-port",
"-p",
default=os.environ.get("HG_SERVE_PORT", "8000"),
help="port to start the hg web server on",
)
command_parsers[start].add_argument(
"--sshd-port",
"-q",
default=os.environ.get("SSHD_PORT", "8022"),
help="port to start ssh daemon on",
)
command_parsers[start].add_argument(
"--no-ssh-auth",
"-r",
action="store_true",
help="do not attempt to authorize ssh public key from the environment",
)
command_parsers[start].add_argument(
"--no-sshd", "-s", action="store_true", help="do not start sshd ",
)
command_parsers[start].add_argument(
"--no-init", "-t", action="store_true", help="do not initialize repos",
)
command_parsers[authorize_ssh].add_argument(
"--public-key", "-k", help="public key to authorize",
)
return parser
if __name__ == "__main__":
parser = create_parser()
args = parser.parse_args()
if hasattr(args, "func"):
args.func(args)
else:
parser.print_help()