Create scratch git repos

* jeepyb/cmd/create_cgitrepos.py: Create empty git repositories
which shadow the publicized repository URLs but are in the form of
proto://host.example.org/subpath/orgname/project.git instead, where
"subpath" is configurable via a SCRATCH_SUBPATH environment
variable. If the variable is not supplied, no scratch projects will
be created and this change will be a no-op. Ownership of the
directories can be set similarly with SCRATCH_OWNER and
SCRATCH_GROUP.

This is intended to be used for arbitrary throwaway references such
as those created by openstack-infra/zuul. As such, it is not
included in the browsable cgit WebUI so as to avoid confusion. A
side effect of this is that any organization name which is the same
as the scratch subpath will cause the script to abort, ensuring
collisions between these do not occur.

Change-Id: Ie111b55dba18e2ecd8bd41394c097cbdc330db18
diff --git a/jeepyb/cmd/create_cgitrepos.py b/jeepyb/cmd/create_cgitrepos.py
index 3fc4f19..07a9eb9 100644
--- a/jeepyb/cmd/create_cgitrepos.py
+++ b/jeepyb/cmd/create_cgitrepos.py
@@ -31,6 +31,9 @@
                             '/etc/cgitrepos')
 REPO_PATH = os.environ.get('REPO_PATH',
                            '/var/lib/git')
+SCRATCH_SUBPATH = os.environ.get('SCRATCH_SUBPATH')
+SCRATCH_OWNER = os.environ.get('SCRATCH_OWNER', 'scratch')
+SCRATCH_GROUP = os.environ.get('SCRATCH_GROUP', 'scratch')
 CGIT_USER = os.environ.get('CGIT_USER', 'cgit')
 CGIT_GROUP = os.environ.get('CGIT_GROUP', 'cgit')
 
@@ -45,6 +48,20 @@
         assert name not in names
         names.add(name)
         gitorgs.setdefault(org, []).append((name, description))
+    if SCRATCH_SUBPATH:
+        assert SCRATCH_SUBPATH not in gitorgs
+        scratch_path = os.path.join('REPO_PATH', 'SCRATCH_SUBPATH')
+        for org in gitorgs:
+            scratch_dir = os.path.join(scratch_path, org)
+            if not os.path.isdir(scratch_dir):
+                os.makedirs(scratch_dir)
+            projects = gitorgs[org]
+            for (name, description) in projects:
+                scratch_repo = "%s.git" % os.path.join(scratch_dir, name)
+                subprocess.call(['git', 'init', '--bare', scratch_repo])
+                subprocess.call(['chown', '-R', '%s:%s'
+                                 % (SCRATCH_OWNER, SCRATCH_GROUP),
+                                 scratch_repo])
     for org in gitorgs:
         if not os.path.isdir('%s/%s' % (REPO_PATH, org)):
             os.makedirs('%s/%s' % (REPO_PATH, org))