diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2014-03-11 17:39:54 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2014-03-11 17:39:54 +0000 |
commit | bac13b388c04a7af9c049c75534bc83c931e2611 (patch) | |
tree | db05c42c006afd373ef5bcf2f1ebc7d13abd4b58 /plugins | |
parent | 2a078069dcfd01c7bf573d53340c8264c3dc4263 (diff) | |
parent | 115c62b1d3e0b98020ec4493ce1d9de512a4995a (diff) | |
download | gitano-bac13b388c04a7af9c049c75534bc83c931e2611.tar.gz |
Merge in rsync work from Codethink
This adds support for Codethink's Trove server's rsync command
and also adds a generic plugin interface and repository detection support.
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/demo.lua | 46 | ||||
-rw-r--r-- | plugins/rsync.lua | 108 |
2 files changed, 154 insertions, 0 deletions
diff --git a/plugins/demo.lua b/plugins/demo.lua new file mode 100644 index 0000000..efac4c7 --- /dev/null +++ b/plugins/demo.lua @@ -0,0 +1,46 @@ +-- Demo Plugin +-- +-- This is a demonstration plugin which will not be installed as part of +-- Gitano. Its purpose is to show the way that a plugin can add commands +-- to Gitano if it so desires. +-- +-- Copyright 2014 Daniel Silverstone <daniel.silverstone@codethink.co.uk> + +local gitano = require "gitano" + +local demo_short_help = "Simple demo command" +local demo_helptext = [[ +This is the long help text for the demonstration plugin 'demo' command. + +Enjoy. +]] + +local function demo_validate(config, repo, cmdline) + if #cmdline ~= 2 then + gitano.log.error("usage: demo <reponame>") + return false + end + return true +end + +local function demo_prep(config, repo, cmdline, context) + context.operation = "read" + return config.repo:run_lace(context) +end + +local function demo_run(config, repo, cmdline, env) + local p = gitano.log.stdout + p(("Repo is: %s"):format(tostring(repo))) + for i, n in ipairs(cmdline) do + p(("cmdline[%d] is: %s"):format(i, tostring(n))) + end + for k, v in pairs(env) do + p(("env[%s] is: %s"):format(k, tostring(v))) + end + return "exit", 0 +end + +assert(gitano.command.register("demo", + demo_short_help, demo_helptext, + demo_validate, demo_prep, demo_run, + true, false, false)) diff --git a/plugins/rsync.lua b/plugins/rsync.lua new file mode 100644 index 0000000..da4bdb7 --- /dev/null +++ b/plugins/rsync.lua @@ -0,0 +1,108 @@ +-- 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 + + 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)) |