#!/usr/bin/python

"""Re-generate the remctl configuration for build submissions.

This script generates the remctl ACL and configuration for each build
pocket defined in the configuration. It also updates the .k5login for
the git user that developers can push through.
"""
from __future__ import with_statement

import contextlib
import os
import tempfile

from invirt import authz
from invirt import builder
from invirt.config import structs as config


def userToPrinc(user):
    """Convert an AFS principal to a Kerberos v5 principal."""
    if '@' in user:
        (princ, realm) = user.split('@')
    else:
        princ = user
        realm = config.kerberos.realm

    return princ.replace('.', '/') + '@' + realm

def acl_path(pocket):
    return '/etc/remctl/acl/build-%s' % pocket

@contextlib.contextmanager
def atomic_write(file):
    tmp_fd, tmp_name = tempfile.mkstemp()
    tmp = os.fdopen(tmp_fd, 'r+')
    yield tmp
    tmp.close()
    os.rename(tmp_name, file)

def main():
    all_devs = set()
    build_handler = '/usr/bin/invirt-submit-build'

    for pocket in config.build.pockets:
        acl = authz.expandAdmin(getattr(config.build.pockets, pocket).acl)
        with atomic_write(acl_path(pocket)) as f:
            princs = [userToPrinc(a) for a in acl]
            print >>f, '\n'.join(princs)
            all_devs.update(set(princs))

    with atomic_write('/etc/remctl/conf.d/build') as f:
        for pocket in config.build.pockets:
            print >>f, 'build %s %s %s' % (pocket, build_handler, acl_path(pocket))

    with atomic_write('/etc/remctl/acl/repo_admin') as f:
        acl = authz.expandAdmin(config.build.repo_admin)
        print >>f, '\n'.join(userToPrinc(a) for a in acl)

    with atomic_write('/etc/remctl/conf.d/repo_admin') as f:
        print >>f, 'create repo /usr/bin/invirt-add-repo /etc/remctl/acl/repo_admin'

    with atomic_write(os.path.join(builder._REPO_DIR, '.k5login')) as f:
        print >>f, '\n'.join(all_devs)


if __name__ == '__main__':
    main()