testing/vcttesting/hgmo_mach_commands.py (204 lines of code) (raw):

# 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/. from __future__ import print_function, unicode_literals import argparse import os import subprocess import stat import sys from mach.decorators import ( CommandArgument, CommandProvider, Command, ) @CommandProvider class HgmoCommands(object): def __init__(self, context): from vcttesting.docker import Docker, params_from_env from vcttesting.hgmo import HgCluster docker_url, tls = params_from_env(os.environ) docker = Docker(docker_url, tls=tls) if not docker.is_alive(): print("Docker not available") sys.exit(1) self.c = HgCluster(docker) @Command("start", category="hgmo", description="Start a hg.mozilla.org cluster") @CommandArgument( "--master-ssh-port", type=int, help="Port number on which SSH server should listen", ) @CommandArgument( "--show-output", action="store_true", help="Display output of shutdown process" ) def start(self, master_ssh_port=None, show_output=False): s = self.c.start(master_ssh_port=master_ssh_port, show_output=show_output) print("SSH Hostname: %s" % s["master_ssh_hostname"]) print("SSH Port: %s" % s["master_ssh_port"]) print("LDAP URI: %s" % s["ldap_uri"]) print("Web URL 0: %s" % s["hgweb_0_url"]) print("Web URL 1: %s" % s["hgweb_1_url"]) print("Pulse: %s:%d" % (s["pulse_hostname"], s["pulse_hostport"])) @Command("build", category="hgmo", description="Build hgmo test images") @CommandArgument("--image", type=str, help="Name of image to build") def build(self, image=None): from vcttesting.hgmo import HgCluster HgCluster.build(image=image) @Command( "shellinit", category="hgmo", description="Print shell commands to export variables", ) def shellinit(self): cluster_state = self.c.get_state() print("export SSH_CID=%s" % cluster_state["master_id"]) print("export PULSE_HOST=%s" % cluster_state["pulse_hostname"]) print("export PULSE_PORT=%s" % cluster_state["pulse_hostport"]) print("export SSH_SERVER=%s" % cluster_state["master_ssh_hostname"]) print("export SSH_PORT=%d" % cluster_state["master_ssh_port"]) # Don't export the full value because spaces. print( "export SSH_HOST_RSA_KEY=%s" % cluster_state["master_host_rsa_key"].split()[1] ) print( "export SSH_HOST_ED25519_KEY=%s" % cluster_state["master_host_ed25519_key"].split()[1] ) print("export HGWEB_0_URL=%s" % cluster_state["hgweb_0_url"]) print("export HGWEB_1_URL=%s" % cluster_state["hgweb_1_url"]) print("export HGWEB_0_CID=%s" % cluster_state["hgweb_0_cid"]) print("export HGWEB_1_CID=%s" % cluster_state["hgweb_1_cid"]) print("export KAFKA_0_HOSTPORT=%s" % cluster_state["kafka_0_hostport"]) print("export KAFKA_1_HOSTPORT=%s" % cluster_state["kafka_1_hostport"]) print("export KAFKA_2_HOSTPORT=%s" % cluster_state["kafka_2_hostport"]) @Command( "clean", category="hgmo", description="Clean up all references to this cluster" ) @CommandArgument( "--show-output", action="store_true", help="Display output of shutdown process" ) def clean(self, show_output=False): self.c.clean(show_output=show_output) @Command( "create-ldap-user", category="hgmo", description="Create a new user in LDAP" ) @CommandArgument("email", help="Email address associated with user") @CommandArgument("username", help="System account name") @CommandArgument("uid", type=int, help="Numeric user ID to associate with user") @CommandArgument("fullname", help="Full name of the user") @CommandArgument("--key-file", help="Use or create an SSH key") @CommandArgument( "--scm-level", type=int, choices=(1, 2, 3, 4), help="Add the user to the specified SCM level groups", ) @CommandArgument( "--no-hg-access", action="store_true", help="Do not grant Mercurial access to user", ) @CommandArgument("--hg-disabled", action="store_true", help="Set hgAccess to FALSE") @CommandArgument( "--group", action="append", dest="groups", help="Additional group to add the user to. (can be specified multiple times", ) def create_ldap_user( self, email, username, uid, fullname, key_file=None, scm_level=None, no_hg_access=False, hg_disabled=False, groups=[], ): self.c.ldap.create_user( email, username, uid, fullname, key_filename=key_file, scm_level=scm_level, hg_access=not no_hg_access, hg_enabled=not hg_disabled, groups=groups, ) @Command( "add-ssh-key", category="hgmo", description="Add an SSH public key to a user" ) @CommandArgument("email", help="Email address of user to modify") @CommandArgument("key", help="SSH public key string") def add_ssh_key(self, email, key): if key == "-": key = sys.stdin.read().strip() self.c.ldap.add_ssh_key(email, key.encode("utf-8")) @Command( "add-user-to-group", category="hgmo", description="Add a user to an LDAP group" ) @CommandArgument("email", help="Email address of user to modify") @CommandArgument("group", help="Name of LDAP group to add user to") def add_user_to_group(self, email, group): self.c.ldap.add_user_to_group(email, group) @Command( "create-repo", category="hgmo", description="Create a repository in the cluster" ) @CommandArgument("name", help="Name of repository to create") @CommandArgument("group", default="scm_level_1", help="LDAP group that owns repo") def create_repo(self, name, group): out = self.c.create_repo(name, group=group) if out: sys.stdout.write(out) @Command( "aggregate-code-coverage", category="hgmo", description="Aggregate code coverage results to a directory", ) @CommandArgument("destdir", help="Directory where to save code coverage files") def aggregate_code_coverage(self, destdir): self.c.aggregate_code_coverage(destdir) @Command( "exec", category="hgmo", description="Execute a command in a Docker container" ) @CommandArgument( "--detach", action="store_true", help="Do not wait for process to finish" ) @CommandArgument("name", help="Name of container to execute inside") @CommandArgument("command", help="Command to execute", nargs=argparse.REMAINDER) def execute(self, name, command, detach=False): state = self.c.get_state() if name == "hgssh": cid = state["master_id"] elif name == "pulse": cid = state["pulse_id"] elif name.startswith("hgweb"): i = int(name[5:]) cid = state["hgweb_%d_cid" % i] else: print('invalid name. must be "hgssh" or "hgwebN"') return 1 cmd = ["docker", "exec"] if "TESTTMP" not in os.environ: cmd.append("-it") if detach: cmd.append("-d") cmd.append(cid) cmd.extend(command) return subprocess.call(cmd) @Command( "download-mirror-ssh-keys", category="hgmo", description="Downloads SSH keys used by mirrors", ) @CommandArgument("out_dir", help="Directory in which to write the keys") def download_mirror_ssh_keys(self, out_dir): state = self.c.get_state() priv, pub = self.c.get_mirror_ssh_keys(master_id=state["master_id"])[0:2] with open(os.path.join(out_dir, "mirror"), "w") as fh: fh.write(priv) os.chmod(os.path.join(out_dir, "mirror"), stat.S_IRUSR | stat.S_IWUSR) with open(os.path.join(out_dir, "mirror.pub"), "w") as fh: fh.write(pub) print("SSH keys written to %s" % out_dir)