Add support for creating a default acl file.

If a project wants to follow the core/drivers pattern, create an
acl file for it if it doesn't have one. Additionally, allow for
the specification of an additional acl file to append to the end
of the generated acl file to allow for specialization on top of the
general case.

Change-Id: I4d5b905befdb8d742dd1aaa148cf4ec1b3355b01
Reviewed-on: https://review.openstack.org/23372
Reviewed-by: James E. Blair <corvus@inaugust.com>
Reviewed-by: Clark Boylan <clark.boylan@gmail.com>
Reviewed-by: Jeremy Stanley <fungi@yuggoth.org>
Approved: Monty Taylor <mordred@inaugust.com>
Tested-by: Jenkins
diff --git a/jeepyb/cmd/manage_projects.py b/jeepyb/cmd/manage_projects.py
index d3ec58d..25b03d0 100644
--- a/jeepyb/cmd/manage_projects.py
+++ b/jeepyb/cmd/manage_projects.py
@@ -25,6 +25,7 @@
 #   has-issues: False
 #   has-downloads: False
 #   acl-dir: /home/gerrit2/acls
+#   acl-base: /home/gerrit2/acls/project.config
 # ---
 # - project: PROJECT_NAME
 #   options:
@@ -37,6 +38,10 @@
 #   remote: https://gerrit.googlesource.com/gerrit
 #   upstream: git://github.com/bushy/beards.git
 #   acl-config: /path/to/gerrit/project.config
+#   acl-append:
+#     - /path/to/gerrit/project.config
+#   acl-parameters:
+#     super-project: OTHER_PROJECT_NAME
 
 
 import ConfigParser
@@ -90,6 +95,29 @@
     return (status, out)
 
 
+def write_acl_config(project, acl_dir, acl_base, acl_append, parameters):
+    project_parts = os.path.split(project)
+    if len(project_parts) > 1:
+        repo_base = os.path.join(acl_dir, *project_parts[:-1])
+        if not os.path.exists(repo_base):
+            os.path.makedirs(repo_base)
+        if not os.path.isdir(repo_base):
+            return 1
+        config_file = os.path.join(repo_base, "%s.config" % project_parts[-1])
+    else:
+        config_file = os.path.join(acl_dir, "%s.config" % project)
+    with open(config_file, 'w') as config:
+        if acl_base and os.path.exists(acl_base):
+            config.write(open(acl_base, 'r').read())
+        for acl_snippet in acl_append:
+            if not os.path.exists(acl_snippet):
+                acl_snippet = os.path.join(acl_dir, acl_snippet)
+            if not os.path.exists(acl_snippet):
+                continue
+            with open(acl_snippet, 'r') as append_content:
+                config.write(append_content.read() % parameters)
+
+
 def fetch_config(project, remote_url, repo_path, env={}):
     status = git_command(repo_path, "fetch %s +refs/meta/config:"
                          "refs/remotes/gerrit-meta/config" % remote_url, env)
@@ -332,6 +360,12 @@
                 acl_config = None
 
             if acl_config:
+                if not os.path.isfile(acl_config):
+                    write_acl_config(project,
+                                     ACL_DIR,
+                                     section.get('acl-base', None),
+                                     section.get('acl-append', []),
+                                     section.get('acl-parameters', {}))
                 tmpdir = tempfile.mkdtemp()
                 try:
                     repo_path = os.path.join(tmpdir, 'repo')