summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSol Jerome <sol.jerome@gmail.com>2011-04-13 09:24:40 -0500
committerSol Jerome <sol.jerome@gmail.com>2011-04-13 09:24:40 -0500
commit41edd7fddc7cb53d0fe3880c7707eb0f58879e59 (patch)
treecf66192a9fd4edb9dcd9bf80d142693d1eff2220
parent545dda76d34a06ae25efa2eb3d0c8c0bd70127d0 (diff)
downloadbcfg2-41edd7fddc7cb53d0fe3880c7707eb0f58879e59.tar.gz
bcfg2-41edd7fddc7cb53d0fe3880c7707eb0f58879e59.tar.bz2
bcfg2-41edd7fddc7cb53d0fe3880c7707eb0f58879e59.zip
VCS: Initial commit (#754)
Preliminary support for version control checkouts onto the client. This client tool is still fairly picky and has some known problems (incorrect git index file, for one). All the abstraction libraries left quite a bit to be desired. Also, none were packaged in popular distributions. Signed-off-by: Sol Jerome <sol.jerome@gmail.com>
-rw-r--r--doc/client/tools/vcs.txt15
-rw-r--r--doc/server/configurationentries.txt4
-rw-r--r--src/lib/Client/Tools/VCS.py137
3 files changed, 156 insertions, 0 deletions
diff --git a/doc/client/tools/vcs.txt b/doc/client/tools/vcs.txt
new file mode 100644
index 000000000..fb9c33684
--- /dev/null
+++ b/doc/client/tools/vcs.txt
@@ -0,0 +1,15 @@
+.. -*- mode: rst -*-
+
+.. _client-tools-vcs:
+
+===============
+VCS Client Tool
+===============
+
+.. warning: This tool is currently under development.
+
+.. note: Currently, the only supported VCS is git.
+
+The VCS tool allows you to checkout particular revisions from a VCS
+repository on the client to a specified path. The tool requires the
+appropriate python libraries for the VCS used to be installed.
diff --git a/doc/server/configurationentries.txt b/doc/server/configurationentries.txt
index 6e6ab79f7..4ade2d414 100644
--- a/doc/server/configurationentries.txt
+++ b/doc/server/configurationentries.txt
@@ -95,6 +95,10 @@ necessary for the Path type specified.
| | entries | POSIX entities | group, perms |
| | | | |
+-------------+----------------------+-----------------+--------------------------+
+| vcs | New | Create version | vcstype (git), |
+| | | control | sourceurl, revision |
+| | | checkout | |
++-------------+----------------------+-----------------+--------------------------+
Keep in mind that permissions for files served up by Cfg/TGenshi/TCheetah
are still handled via the traditional :ref:`server-info` mechanisms.
diff --git a/src/lib/Client/Tools/VCS.py b/src/lib/Client/Tools/VCS.py
new file mode 100644
index 000000000..fa7748574
--- /dev/null
+++ b/src/lib/Client/Tools/VCS.py
@@ -0,0 +1,137 @@
+"""VCS support."""
+
+# TODO:
+# * git_write_index
+# * add svn support
+# * integrate properly with reports
+missing = []
+
+import os
+import sys
+# python-dulwich git imports
+try:
+ import dulwich
+ import dulwich.index
+ from dulwich.errors import NotGitRepository
+except:
+ missing.append('git')
+# subversion import
+try:
+ import pysvn
+except:
+ missing.append('svn')
+
+import Bcfg2.Client.Tools
+
+
+class VCS(Bcfg2.Client.Tools.Tool):
+ """VCS support."""
+ name = 'VCS'
+ __handles__ = [('Path', 'vcs')]
+ __req__ = {'Path': ['name',
+ 'type',
+ 'vcstype',
+ 'sourceurl',
+ 'revision']}
+
+ def __init__(self, logger, cfg, setup):
+ Bcfg2.Client.Tools.Tool.__init__(self, logger, cfg, setup)
+ self.cfg = cfg
+
+ def git_write_index(self, entry):
+ """Write the git index"""
+ pass
+
+ def Verifygit(self, entry, _):
+ """Verify git repositories"""
+ try:
+ repo = dulwich.repo.Repo(entry.get('name'))
+ except NotGitRepository:
+ self.logger.info("Repository %s does not exist" %
+ entry.get('name'))
+ return False
+ cur_rev = repo.head()
+
+ if cur_rev != entry.get('revision'):
+ self.logger.info("At revision %s need to go to revision %s" %
+ (cur_rev, entry.get('revision')))
+ return False
+
+ return True
+
+ def Installgit(self, entry):
+ """Checkout contents from a git repository"""
+ destname = entry.get('name')
+ destr = dulwich.repo.Repo.init(destname, mkdir=True)
+ cl, host_path = dulwich.client.get_transport_and_path(entry.get('sourceurl'))
+ remote_refs = cl.fetch(host_path,
+ destr,
+ determine_wants=destr.object_store.determine_wants_all,
+ progress=sys.stdout.write)
+ destr.refs['refs/heads/master'] = entry.get('revision')
+ dtree = destr[entry.get('revision')].tree
+ obj_store = destr.object_store
+ for fname, mode, sha in obj_store.iter_tree_contents(dtree):
+ fullpath = os.path.join(destname, fname)
+ try:
+ f = open(os.path.join(destname, fname), 'wb')
+ except IOError:
+ dir = os.path.split(fullpath)[0]
+ os.makedirs(dir)
+ f = open(os.path.join(destname, fname), 'wb')
+ f.write(destr[sha].data)
+ f.close()
+ os.chmod(os.path.join(destname, fname), mode)
+ return True
+ # FIXME: figure out how to write the git index properly
+ #iname = "%s/.git/index" % entry.get('name')
+ #f = open(iname, 'w+')
+ #entries = obj_store[sha].iteritems()
+ #try:
+ # dulwich.index.write_index(f, entries)
+ #finally:
+ # f.close()
+
+ def Verifysvn(self, entry, _):
+ """Verify svn repositories"""
+ client = pysvn.Client()
+ try:
+ cur_rev = str(client.info(entry.get('name')).revision.number)
+ except:
+ self.logger.info("Repository %s does not exist" % entry.get('name'))
+ return False
+
+ if cur_rev != entry.get('revision'):
+ self.logger.info("At revision %s need to go to revision %s" %
+ (cur_rev, entry.get('revision')))
+ return False
+
+ return True
+
+ def Installsvn(self, entry):
+ """Checkout contents from a svn repository"""
+ try:
+ client = pysvn.Client.update(entry.get('name'), recurse=True)
+ except:
+ self.logger.error("Failed to update repository", exc_info=1)
+ return False
+
+ return True
+
+ def VerifyPath(self, entry, _):
+ vcs = entry.get('vcstype')
+ if vcs in missing:
+ self.logger.error("Missing %s python libraries. Cannot verify" %
+ vcs)
+ return False
+ ret = getattr(self, 'Verify%s' % vcs)
+ return ret(entry, _)
+
+ def InstallPath(self, entry):
+ vcs = entry.get('vcstype')
+ if vcs in missing:
+ self.logger.error("Missing %s python libraries. "
+ "Unable to install" % vcs)
+ return False
+ ret = getattr(self, 'Install%s' % vcs)
+ return ret(entry)