Beispiel #1
0
class HgmoCommands(object):
    def __init__(self, context):
        from vcttesting.docker import Docker, params_from_env
        from vcttesting.hgmo import HgCluster

        if 'DOCKER_STATE_FILE' not in os.environ:
            print('Do not where to store Docker state.')
            print('Set the DOCKER_STATE_FILE environment variable and try again.')
            sys.exit(1)

        docker_url, tls = params_from_env(os.environ)
        docker = Docker(os.environ['DOCKER_STATE_FILE'], 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')
    def start(self, master_ssh_port=None):
        s = self.c.start(master_ssh_port=master_ssh_port,
                         show_output=False)
        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('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().encode('utf-8')
        self.c.ldap.add_ssh_key(email, key)

    @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)