Преглед на файлове

Add multi_server, initial doc.

Jelmer Vernooij преди 9 години
родител
ревизия
b208126868
променени са 1 файла, в които са добавени 112 реда и са изтрити 0 реда
  1. 112 0
      dulwich/contrib/multi_server.py

+ 112 - 0
dulwich/contrib/multi_server.py

@@ -0,0 +1,112 @@
+# multi_server.py -- High Availability server
+# Copyright (C) 2015 Jelmer Vernooij <jelmer@jelmer.uk>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# or (at your option) a later version of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.
+
+"""Highly available Git server, backed by etcd.
+
+On startup, each server needs to be pointed at:
+
+ * A etcd server URL (can be a suburl)
+ * A local storage path
+
+The refs in etcd are considered canonical. Each server has a copy of the object
+store that *may* be out of date.
+
+Upon new uploads, servers contact their peers to distribute the new pack files.
+
+If an object is requested but not present, peers are contacted to see if they
+have a copy.
+"""
+
+import etcd
+
+
+from dulwich.object_store import DiskObjectStore
+from dulwich.refs import RefsContainer
+
+
+class EtcdRefsContainer(RefsContainer):
+    """A refs container backed by etcd.
+    """
+
+    def __init__(self, client, base_key):
+        """Create a new EtcdRefsContainer.
+
+        :param client: A etcd.Client object to use
+        :param base_key: Base key
+        """
+        self._client = client
+        self._base_key = base_key
+
+    def allkeys(self):
+        raise NotImplementedError
+
+    def read_loose_ref(self, name):
+        raise NotImplementedError
+
+    def get_packed_refs(self):
+        return {}
+
+    def set_symbolic_ref(self, name, other):
+        raise NotImplementedError
+
+    def set_if_equals(self, name, old_ref, new_ref):
+        # TODO(jelmer): call test_and_set
+        raise NotImplementedError
+
+    def add_if_new(self, name, ref):
+        raise NotImplementedError
+
+    def remove_if_equals(self, name, old_ref):
+        raise NotImplementedError
+
+    def get_peeled(self, name):
+        # TODO(jelmer): Implement
+        return None
+
+
+class ReplicatingObjectStore(DiskObjectStore):
+    """Object store that can replicate to peers."""
+
+    # TODO(jelmer): Base this on a pack-only data store,
+    # rather than one that also supports loose objects
+
+
+def main():
+    """Entry point for starting a TCP git server."""
+    import optparse
+    parser = optparse.OptionParser()
+    parser.add_option("-l", "--listen_address", dest="listen_address",
+                      default="localhost",
+                      help="Binding IP address.")
+    parser.add_option("-p", "--port", dest="port", type=int,
+                      default=TCP_GIT_PORT,
+                      help="Binding TCP port.")
+    options, args = parser.parse_args(argv)
+
+    log_utils.default_logging_config()
+    if len(args) > 1:
+        gitdir = args[1]
+    else:
+        gitdir = '.'
+    backend = FileSystemBackend(gitdir)
+    server = TCPGitServer(backend, options.listen_address, options.port)
+    server.serve_forever()
+
+
+if __name__ == '__main__':
+    main()