diff options
author | Daniel Silverstone <daniel.silverstone@codethink.co.uk> | 2014-03-10 16:35:58 +0000 |
---|---|---|
committer | Daniel Silverstone <daniel.silverstone@codethink.co.uk> | 2014-03-11 14:13:08 +0000 |
commit | 115c62b1d3e0b98020ec4493ce1d9de512a4995a (patch) | |
tree | 2a378e12c2ce83d03d393cc11734c7c8f3b258b0 | |
parent | c101d7d310b908ad88a61efb499b8ee14f94fdb5 (diff) | |
download | gitano-115c62b1d3e0b98020ec4493ce1d9de512a4995a.tar.gz |
Support for rsync in Trovesbaserock/danielsilverstone/S10634-rsync-support
In order to support ingesting of binary artifacts, we are proposing the use of
`git-fat` which is a content filter which uses rsync to store the binary
artifacts. That requires an access controlled binary artifact repository, so
we take advantage of Gitano's ACLs and associate an optional rsync repository
with every git repository on the server. By placing it inside the git
repository, all of gitano's destroy and graveyard behaviour automatically works
with the new rsync content.
Signed-off-by: Daniel Silverstone <daniel.silverstone@codethink.co.uk>
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | plugins/rsync.lua | 105 |
2 files changed, 107 insertions, 1 deletions
@@ -61,7 +61,8 @@ SKEL_FILES := gitano-admin/rules/selfchecks.lace \ MAN1S := gitano-setup.1 -PLUGINS := + +PLUGINS := rsync.lua MOD_DIRS := gitano MOD_FILES := $(patsubst %,%.lua,$(subst .,/,$(MODS))) diff --git a/plugins/rsync.lua b/plugins/rsync.lua new file mode 100644 index 0000000..4c07233 --- /dev/null +++ b/plugins/rsync.lua @@ -0,0 +1,105 @@ +-- rsync Plugin +-- +-- This plugin is part of Trove. Trove is Codethink's Baserock central server +-- and uses Gitano as the Git service. This plugin adds support to Trove for +-- supporting 'rsync' as a command in Gitano. This means that every repository +-- has an rsync tree attached to it which can be used by remote ends sshing +-- into the Trove. +-- +-- Copyright 2014 Daniel Silverstone <daniel.silverstone@codethink.co.uk> + +local gitano = require "gitano" + +local sp = require "luxio.subprocess" + +local rsync_short_help = "An rsync endpoint within Gitano" +local rsync_helptext = [[ +Users are not expected to use this command directly, but instead to +instruct their local rsync to use a remote of user@gitanohost:reponame +when pushing or pulling rsync content. +]] + +local function rsync_detect_repo(config, cmdline) + local repo, msg + local repopath = cmdline[#cmdline] + + if #cmdline < 4 then + -- Validate will fail with a nice error, give up now + return nil, cmdline + end + + if repopath:match("^/") then + repopath = repopath:sub(2) + end + + local origpath = repopath + + -- Basically, while there's still something to the repopath + -- and we've not yet found a repo, strip an element and try again... + while not repo and repopath ~= ""do + repo, msg = gitano.repository.find(config, repopath) + if not repo then + repopath = repopath:match("^(.*)/[^/]*$") or "" + end + end + + if not repo then + gitano.log.error("Unable to find a repository for " .. cmdline[#cmdline]) + return nil, nil + end + + if repo.is_nascent then + gitano.log.error("Repository " .. repo.name .. " is nascent") + gitano.log.error("Cannot use rsync command with nascent repositories") + return nil, nil + end + + -- Okay, so repopath represented a repository, let's convert the path + -- into something which we can work with... + cmdline[#cmdline] = repo:fs_path() .. "/rsync" .. origpath:sub(#repopath+1) + if origpath:match("/$") and not (cmdline[#cmdline]):match("/$") then + cmdline[#cmdline] = cmdline[#cmdline] .. "/" + end + + gitano.util.mkdir_p(repo:fs_path() .. "/rsync") + + -- And give back the repo for ruleset running and the cmdline for the rsync + + gitano.log.error(cmdline[#cmdline]) + + return repo, cmdline +end + +local function rsync_validate(config, repo, cmdline) + if #cmdline < 4 then + gitano.log.error("usage: rsync --server <rsync arguments> . <server-side-path>") + return false + end + if cmdline[2] ~= "--server" then + gitano.log.error("Second cmdline element must always be --server") + return false + end + return true +end + +local function rsync_prep(config, repo, cmdline, context) + if cmdline[3] == "--sender" then + context.operation = "read" + else + context.operation = "write" + end + return config.repo:run_lace(context) +end + +local function rsync_run(config, repo, cmdline, env) + local cmdcopy = {env=env} + for i = 1, #cmdline do cmdcopy[i] = cmdline[i] end + local proc = sp.spawn(cmdcopy) + return proc:wait() +end + +assert(gitano.command.register("rsync", + rsync_short_help, rsync_helptext, + rsync_validate, rsync_prep, rsync_run, + true, false, false, + rsync_detect_repo)) |