summaryrefslogtreecommitdiff
path: root/plugins/rsync.lua
diff options
context:
space:
mode:
authorDaniel Silverstone <daniel.silverstone@codethink.co.uk>2014-03-12 14:31:25 +0000
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2014-03-12 14:31:25 +0000
commit77266b3ec2efec51f0a3246cbad70a4f15835958 (patch)
tree141ed6836821bd96cdb6248735367d0883e2ce1d /plugins/rsync.lua
parent0434ed0c1f14bb856e11925dbf45605f10734449 (diff)
parent98d9af920fb8052b47fdf7cbf2affa5617b6f089 (diff)
downloadgitano-77266b3ec2efec51f0a3246cbad70a4f15835958.tar.gz
Merge in rsync support from upstream.
Signed-off-by: Daniel Silverstone <daniel.silverstone@codethink.co.uk>
Diffstat (limited to 'plugins/rsync.lua')
-rw-r--r--plugins/rsync.lua105
1 files changed, 105 insertions, 0 deletions
diff --git a/plugins/rsync.lua b/plugins/rsync.lua
new file mode 100644
index 0000000..310fe59
--- /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.
+--
+-- Since the functionality is generically useful however, it is supported here
+-- in Gitano upstream.
+--
+-- 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
+ 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 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, true, false,
+ rsync_detect_repo))