Support creation of both lighttpd and nginx configuration files
authorMagnus Hagander <magnus@hagander.net>
Sun, 27 Dec 2020 13:22:44 +0000 (14:22 +0100)
committerMagnus Hagander <magnus@hagander.net>
Sun, 27 Dec 2020 13:22:44 +0000 (14:22 +0100)
We only support reloading one webserver, as it's not really expected to
run more than one, but concurrently supporting generating both file
formats will make migration a lot easier.

gitdump.py
pggit.settings.sample

index 5b86d115af48e9bad7e6cf4a21b375c913b90ec3..92d3a2fb826c169ec485437e4226c4160030e4bf 100644 (file)
@@ -16,10 +16,22 @@ import shutil
 import psycopg2
 import configparser
 import urllib.parse
-import filecmp
 from util.LockFile import LockFile
 
 
+def replace_file_from_string(fn, s):
+    if os.path.isfile(fn):
+        with open(fn) as f:
+            old = f.read()
+        if old == s:
+            # No changes
+            return False
+
+    with open("{}.tmp".format(fn), "w") as f:
+        f.write(s)
+    os.rename("{}.tmp".format(fn), fn)
+
+
 class AuthorizedKeysDumper(object):
     def __init__(self, db, conf):
         self.db = db
@@ -58,8 +70,8 @@ SELECT name,anonymous,web,description,initialclone,tabwidth,
          THEN 1 ELSE 0 END
 FROM repositories AS r WHERE approved ORDER BY name""")
         f = open("%s.tmp" % self.conf.get("paths", "gitweblist"), "w")
-        accessfile = open("%s.tmp" % self.conf.get("paths", "lighttpdconf"), "w")
-        accessfile.write("alias.url += (\n")
+
+        webrepos = []
 
         for name, anon, web, description, initialclone, tabwidth, owner, remoterepo in curs:
             allrepos[name] = 1
@@ -132,8 +144,7 @@ FROM repositories AS r WHERE approved ORDER BY name""")
                     open(anonfile, "w").close()
                 # When anonymous access is allowed, create an entry so
                 # we can access it with http git.
-                accessfile.write(' "/git/%s.git/" => "%s/",' % (name, repopath))
-                accessfile.write("\n")
+                webrepos.append((name, repopath))
             else:
                 if os.path.isfile(anonfile):
                     os.remove(anonfile)
@@ -142,20 +153,30 @@ FROM repositories AS r WHERE approved ORDER BY name""")
         os.chmod("%s.tmp" % self.conf.get("paths", "gitweblist"), 0o644)
         os.rename("%s.tmp" % self.conf.get("paths", "gitweblist"), self.conf.get("paths", "gitweblist"))
 
-        accessfile.write(")\n")
-        accessfile.close()
-        # Only rewrite the access file if it is actually different. And if
-        # it is, we need to also reload lighttpd at this point.
-        if os.path.isfile(self.conf.get("paths", "lighttpdconf")) and filecmp.cmp(
-            self.conf.get("paths", "lighttpdconf"),
-                "%s.tmp" % self.conf.get("paths", "lighttpdconf")):
-            # No changes, so just get rid of the temp file
-            os.remove("%s.tmp" % self.conf.get("paths", "lighttpdconf"))
-        else:
-            # File changed, so we need to overwrite the old one *and*
-            # reload lighttpd so the changes take effect.
-            os.rename("%s.tmp" % self.conf.get("paths", "lighttpdconf"),
-                      self.conf.get("paths", "lighttpdconf"))
+        if webrepos:
+            changed = False
+            if self.conf.has_option("paths", "lighttpdconf"):
+                if replace_file_from_string(
+                        self.conf.get("paths", "lighttpdconf"),
+                        "alias.url += (\n{}\n)\n".format("\n".join([' "/git/{}.git/" => "{}/",'.format(name, path) for name, path in webrepos])),
+                ):
+                    changed = True
+
+            if self.conf.has_option("paths", "nginxconf"):
+                if replace_file_from_string(
+                        self.conf.get("paths", "nginxconf"),
+                        """if ($args ~ "git-receive-pack") {{
+    return 403;
+}}
+
+if ($uri !~ "^/git/({})\.git") {{
+    return 404;
+}}
+""".format("|".join([name for name, path in webrepos])),
+                ):
+                    changed = True
+
+        if changed and self.conf.has_option("webserver", "reloadcommand"):
             os.system(self.conf.get("webserver", "reloadcommand"))
 
         # Now remove any repositories that have been deleted
index d5c484b4c4c1abaf3cb1ef65130731ca2489a625..66ac1012a62581f828b4586f3e131605949b2ba6 100644 (file)
@@ -16,6 +16,7 @@ pggit=/opt/pgsql/pggit/pggit.py
 gitweblist=/opt/pgsql/pggit/__temp__gitweb.list
 logfile=/home/gitlab/pggit.log
 lighttpdconf=/home/gitlab/lighttpd/pggit.conf
+nginxconf=/home/gitlab/nginx/pggit.conf
 
 [webserver]
 reloadcommand=sudo /usr/sbin/service lighttpd reload