From 1b141c8359c690756b0f9612fd6ccfc7ca5e9f99 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 10 Mar 2014 12:41:07 +0000 Subject: Plugin support in Gitano This patch adds support for Gitano to load plugins from a colon separated set of paths. While colon separation is not the best mechanism, it is in common use. We explicitly do not add any escaping rules such as :: -> : in order to remain compatible with things like PATH processing. Signed-off-by: Daniel Silverstone --- Makefile | 2 +- lib/gitano.lua | 4 +++- lib/gitano/plugins.lua | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 lib/gitano/plugins.lua diff --git a/Makefile b/Makefile index 7fa7d11..775f5cc 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ MODS := gitano \ gitano.actions gitano.config gitano.lace gitano.log \ gitano.markdown gitano.repository gitano.supple \ gitano.command gitano.admincommand gitano.usercommand \ - gitano.repocommand gitano.copycommand gitano.auth + gitano.repocommand gitano.copycommand gitano.auth gitano.plugins SKEL_FILES := gitano-admin/rules/selfchecks.lace \ gitano-admin/rules/aschecks.lace \ diff --git a/lib/gitano.lua b/lib/gitano.lua index b57bd71..31e62d5 100644 --- a/lib/gitano.lua +++ b/lib/gitano.lua @@ -15,6 +15,7 @@ local lace = require 'gitano.lace' local markdown = require 'gitano.markdown' local supple = require 'gitano.supple' local auth = require 'gitano.auth' +local plugins = require 'gitano.plugins' return { util = util, @@ -26,5 +27,6 @@ return { lace = lace, markdown = markdown, supple = supple, - auth = auth + auth = auth, + plugins = plugins, } diff --git a/lib/gitano/plugins.lua b/lib/gitano/plugins.lua new file mode 100644 index 0000000..bdc6d1e --- /dev/null +++ b/lib/gitano/plugins.lua @@ -0,0 +1,63 @@ +-- gitano.plugins +-- +-- Plugin loading support for Gitano +-- +-- Copyright 2014 Daniel Silverstone + +local util = require "gitano.util" +local log = require "gitano.log" + +local luxio = require "luxio" +local sio = require "luxio.simple" + +local gfind = string.gfind + +local plugin_name_pattern = "^(.+)%.lua$" + +local function find_plugins(path) + local ret = {} + for _, entry in ipairs(path) do + local dirp, err = sio.opendir(entry) + if not dirp then + log.warning(("Unable to scan plugin directory '%s': %s") + :format(entry, err)) + else + for filename, fileinfo in dirp:iterate() do + local plugin_name = filename:match(plugin_name_pattern) + if plugin_name and fileinfo.d_type == luxio.DT_REG then + if not ret[plugin_name] then + ret[plugin_name] = entry + ret[#ret + 1] = plugin_name + end + end + end + end + end + table.sort(ret) + return ret +end + +local function load_plugins(path) + local to_load = find_plugins(path) + for _, plugin_name in ipairs(to_load) do + local filepath = util.path_join(to_load[plugin_name], + plugin_name .. ".lua") + local chunk, err = loadfile(filepath) + if not chunk then + log.warning(("Failure loading plugin '%s' from '%s': %s") + :format(plugin_name, to_load[plugin_name], + err)) + else + local ok, err = pcall(chunk) + if not ok then + log.warning(("Failure running plugin '%s' from '%s': %s") + :format(plugin_name, to_load[plugin_name], + err)) + end + end + end +end + +return { + load_plugins = load_plugins, +} -- cgit v1.2.1 From ab1c0b22b57fc96782d9dd3498b36be04ac6f328 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 10 Mar 2014 12:41:44 +0000 Subject: Add support for a GITANO_PLUGIN_PATH in install-lua-bin The binary installer `install-lua-bin` needs to update all of the files ending in `.in` to be ready for installation. This patch ensures that we support a tag for loading plugins which the various `.in` files can then use to ensure they load plugins at an appropriate point. Signed-off-by: Daniel Silverstone --- Makefile | 8 ++++++-- utils/install-lua-bin | 14 +++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 775f5cc..359b817 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ LUA_VER := 5.1 LUA := /usr/bin/lua$(LUA_VER) PREFIX ?= /usr/local INST_ROOT := $(PREFIX) +SYSCONF_DIR ?= /etc # Internal stuff LUA_MOD_PATH := $(INST_ROOT)/share/lua/$(LUA_VER) @@ -19,6 +20,7 @@ SHARE_INST_PATH := $(DESTDIR)$(SHARE_PATH) SKEL_INST_PATH := $(SHARE_INST_PATH)/skel MAN_PATH := $(INST_ROOT)/share/man MAN_INST_PATH := $(DESTDIR)$(MAN_PATH) +PLUGIN_PATH := $(SYSCONF_DIR)/gitano/plugins:$(INST_ROOT)/lib/gitano/plugins LIB_BINS := gitano-auth gitano-post-receive-hook gitano-update-hook \ gitano-update-ssh gitano-pre-receive-hook gitano-smart-http.cgi \ @@ -59,6 +61,8 @@ SKEL_FILES := gitano-admin/rules/selfchecks.lace \ MAN1S := gitano-setup.1 +PLUGINS := + MOD_DIRS := gitano MOD_FILES := $(patsubst %,%.lua,$(subst .,/,$(MODS))) SRC_MOD_FILES := $(patsubst %,lib/%,$(MOD_FILES)) @@ -77,14 +81,14 @@ GEN_BIN := utils/install-lua-bin RUN_GEN_BIN := $(LUA) $(GEN_BIN) $(LUA) define GEN_LOCAL_BIN -$(RUN_GEN_BIN) $(shell pwd) $(shell pwd)/bin $(shell pwd)/lib $1 $2 +$(RUN_GEN_BIN) $(shell pwd) $(shell pwd)/bin $(shell pwd)/lib $(shell pwd)/plugins $1 $2 chmod 755 $2 endef define GEN_INSTALL_BIN -$(RUN_GEN_BIN) $(SHARE_PATH) $(LIB_BIN_PATH) $(LUA_MOD_PATH) $1 $2 +$(RUN_GEN_BIN) $(SHARE_PATH) $(LIB_BIN_PATH) $(LUA_MOD_PATH) $(PLUGIN_PATH) $1 $2 chmod 755 $2 endef diff --git a/utils/install-lua-bin b/utils/install-lua-bin index 4d7322c..3353a34 100644 --- a/utils/install-lua-bin +++ b/utils/install-lua-bin @@ -1,6 +1,6 @@ -- Run this explicitly through -*- Lua -*- -local lua_bin, inst_share_path, inst_bin_path, inst_mod_path, input_name, output_name = ... +local lua_bin, inst_share_path, inst_bin_path, inst_mod_path, inst_plugin_path, input_name, output_name = ... local input_fh = assert(io.open(input_name, "r")) local output_fh = assert(io.open(output_name, "w")) @@ -20,6 +20,16 @@ for path_elem in package.path:gmatch("([^;]+)") do end end +do + -- transform the plugin path from colon separated to a table + -- for interpolation + local path = {} + for entry in string.gfind(inst_plugin_path, "([^:]+)") do + path[#path+1] = ("%q"):format(entry) + end + inst_plugin_path = ("{%s}"):format(table.concat(path, ", ")) +end + while line do local token = line:match("^%-%- @@(.+)$") if token then @@ -38,6 +48,8 @@ while line do output_fh:write(("gitano.config.lib_bin_path(%q)\n"):format(inst_bin_path)) elseif token == "GITANO_SHARE_PATH" then output_fh:write(("gitano.config.share_path(%q)\n"):format(inst_share_path)) + elseif token == "GITANO_PLUGIN_PATH" then + output_fh:write(("gitano.plugins.load_plugins %s\n"):format(inst_plugin_path)) else output_fh:write("-- Unknown token: " .. token .. "\n") end -- cgit v1.2.1 From 4109f02a707146e9cbefdb484173725c45f022a6 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 10 Mar 2014 12:42:00 +0000 Subject: Add plugin support to all `.in` files Each `.in` file needs to load plugins in order to ensure that all requisite functionality is available at all points during the lifetime of a Gitano operation. This is a largely mechanical delta. Signed-off-by: Daniel Silverstone --- bin/gitano-auth.in | 1 + bin/gitano-command.cgi.in | 1 + bin/gitano-post-receive-hook.in | 1 + bin/gitano-pre-receive-hook.in | 1 + bin/gitano-setup.in | 1 + bin/gitano-smart-http.cgi.in | 1 + bin/gitano-update-hook.in | 1 + bin/gitano-update-ssh.in | 1 + 8 files changed, 8 insertions(+) diff --git a/bin/gitano-auth.in b/bin/gitano-auth.in index 8a91ae3..55712f4 100644 --- a/bin/gitano-auth.in +++ b/bin/gitano-auth.in @@ -18,6 +18,7 @@ local sp = require "luxio.subprocess" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH +-- @@GITANO_PLUGIN_PATH local repo_root, username, keytag = ... diff --git a/bin/gitano-command.cgi.in b/bin/gitano-command.cgi.in index bc280b2..ba16538 100755 --- a/bin/gitano-command.cgi.in +++ b/bin/gitano-command.cgi.in @@ -17,6 +17,7 @@ local sio = require "luxio.simple" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH +-- @@GITANO_PLUGIN_PATH local stdout = sio.stdout diff --git a/bin/gitano-post-receive-hook.in b/bin/gitano-post-receive-hook.in index f495d89..3dccfee 100644 --- a/bin/gitano-post-receive-hook.in +++ b/bin/gitano-post-receive-hook.in @@ -18,6 +18,7 @@ local sp = require "luxio.subprocess" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH +-- @@GITANO_PLUGIN_PATH local start_log_level = gitano.log.get_level() -- Clamp level at info until we have checked if the caller diff --git a/bin/gitano-pre-receive-hook.in b/bin/gitano-pre-receive-hook.in index c25418b..182554b 100644 --- a/bin/gitano-pre-receive-hook.in +++ b/bin/gitano-pre-receive-hook.in @@ -18,6 +18,7 @@ local sp = require "luxio.subprocess" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH +-- @@GITANO_PLUGIN_PATH local start_log_level = gitano.log.get_level() -- Clamp level at info until we have checked if the caller diff --git a/bin/gitano-setup.in b/bin/gitano-setup.in index 61a3246..f31c8f0 100644 --- a/bin/gitano-setup.in +++ b/bin/gitano-setup.in @@ -18,6 +18,7 @@ local clod = require "clod" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH +-- @@GITANO_PLUGIN_PATH local possible_answers = {...} diff --git a/bin/gitano-smart-http.cgi.in b/bin/gitano-smart-http.cgi.in index 8fb0240..017c4e7 100755 --- a/bin/gitano-smart-http.cgi.in +++ b/bin/gitano-smart-http.cgi.in @@ -18,6 +18,7 @@ local sio = require "luxio.simple" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH +-- @@GITANO_PLUGIN_PATH local stdout = sio.stdout diff --git a/bin/gitano-update-hook.in b/bin/gitano-update-hook.in index e338ba2..34acbf9 100644 --- a/bin/gitano-update-hook.in +++ b/bin/gitano-update-hook.in @@ -18,6 +18,7 @@ local sp = require "luxio.subprocess" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH +-- @@GITANO_PLUGIN_PATH local refname, oldsha, newsha = ... diff --git a/bin/gitano-update-ssh.in b/bin/gitano-update-ssh.in index 798296f..136d6df 100644 --- a/bin/gitano-update-ssh.in +++ b/bin/gitano-update-ssh.in @@ -18,6 +18,7 @@ local sp = require "luxio.subprocess" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH +-- @@GITANO_PLUGIN_PATH local repo_root = ... -- cgit v1.2.1 From 2cfb31e938bc94c2da2cdeb33c3bc69b04bfa932 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 10 Mar 2014 12:42:26 +0000 Subject: Install plugins during `make install` Gitano *may* ship with plugins which need to be installed during the running of `make install` -- as such, support this in the Makefile. Signed-off-by: Daniel Silverstone --- Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 359b817..4a94015 100644 --- a/Makefile +++ b/Makefile @@ -123,7 +123,7 @@ bin/%: bin/%.in $(GEN_BIN) testing/%: testing/%.in $(GEN_BIN) $(call GEN_LOCAL_BIN,$<,$@) -install: install-bins install-lib-bins install-mods install-skel install-man +install: install-bins install-lib-bins install-mods install-skel install-man install-plugins install-man: mkdir -p $(MAN_INST_PATH)/man1 @@ -147,6 +147,13 @@ install-skel: install -m 644 skel/$$SKELFILE $(SKEL_INST_PATH)/$$SKELFILE; \ done +install-plugins: + mkdir -p $(DESTDIR)$(INST_ROOT)/lib/gitano/plugins + mkdir -p $(DESTDIR)$(SYSCONF_DIR)/gitano/plugins + for PLUGIN in $(PLUGINS); do \ + install -m 644 plugins/$$PLUGIN $(DESTDIR)$(INST_ROOT)/lib/gitano/plugins; \ + done + test: local $(TEST_BINS) @$(YARN) --env GTT="$$(pwd)/testing/gitano-test-tool" \ --env LUA_PATH="$(LUA_PATH)" --env LUA_CPATH="$(LUA_CPATH)" \ -- cgit v1.2.1 From 9a6a262606096b0392feab573c9a94f2ce3ee8fb Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 10 Mar 2014 12:42:31 +0000 Subject: Demonstration Plugin The demo plugin shows how to hook into every **supported** interface for plugins. Use of any API beyond that which is shown in the demo plugin is not guaranteed at this point. Later a full plugin compatibility API definition will need to be written. Signed-off-by: Daniel Silverstone --- plugins/demo.lua | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 plugins/demo.lua 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 + +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 ") + 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)) -- cgit v1.2.1 From b4e1b4a3ef063e8447bb5299c7ea40ba9296b35d Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 10 Mar 2014 14:59:48 +0000 Subject: Configurable repository detection for commands Up until now, all commands have been restricted to expecting the repository as the second argument *ONLY*. In order to better support other styles of command, this routine combines the behaviour of all places which currently look for the repository into one place. In addition, this means we can simplify several call sites. Signed-off-by: Daniel Silverstone --- lib/gitano/command.lua | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/gitano/command.lua b/lib/gitano/command.lua index e55fe33..468b34b 100644 --- a/lib/gitano/command.lua +++ b/lib/gitano/command.lua @@ -13,9 +13,27 @@ local sio = require "luxio.simple" local cmds = {} +local function default_detect_repo(config, parsed_cmdline) + local repo, msg + if #parsed_cmdline > 1 then + -- Acquire the repository object for the target repo from arg 2 + repo, msg = repository.find(config, parsed_cmdline[2]) + if not repo then + log.critical("Unable to locate repository.") + log.critical(" * " .. (tostring(msg))) + return nil, nil + end + + if repo.is_nascent then + log.info("Repository " .. repo.name .. " is nascent") + end + end + return repo, parsed_cmdline +end + local function register_cmd(cmdname, short, helptext, validate_fn, prep_fn, run_fn, - takes_repo, hidden, is_admin) + takes_repo, hidden, is_admin, detect_repo) --[[ log.ddebug("Register command", cmdname) if takes_repo then @@ -35,7 +53,8 @@ local function register_cmd(cmdname, short, helptext, hidden = hidden, admin = is_admin, short = short, - helptext = helptext + helptext = helptext, + detect_repo = detect_repo or default_detect_repo } cmds[#cmds+1] = cmdname table.sort(cmds) @@ -52,6 +71,7 @@ local function get_cmd(cmdname) prep = cmd.prep, run = cmd.run, takes_repo = cmd.takes_repo, + detect_repo = cmd.detect_repo } end -- cgit v1.2.1 From c101d7d310b908ad88a61efb499b8ee14f94fdb5 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 10 Mar 2014 14:59:59 +0000 Subject: Use new configurable repository detection Each of these callsites independently detected repositories before. Now they use the configurable repository detection which means (a) they are unified in their behaviour and (b) they can take advantage of new commands which might not have repositories represented in the same way. Signed-off-by: Daniel Silverstone --- bin/gitano-auth.in | 16 ++++------------ lib/gitano/admincommand.lua | 16 +++++----------- lib/gitano/auth.lua | 11 +++-------- 3 files changed, 12 insertions(+), 31 deletions(-) diff --git a/bin/gitano-auth.in b/bin/gitano-auth.in index 55712f4..3901166 100644 --- a/bin/gitano-auth.in +++ b/bin/gitano-auth.in @@ -105,18 +105,10 @@ if not cmd then gitano.log.fatal("Unknown command: " .. parsed_cmdline[1]) end -if cmd.takes_repo and #parsed_cmdline > 1 then - -- Acquire the repository object for the target repo - local msg - repo, msg = gitano.repository.find(config, parsed_cmdline[2]) - if not repo then - gitano.log.critical("Unable to locate repository.") - gitano.log.critical(" * " .. (tostring(msg))) - gitano.log.fatal("Cannot continue") - end - - if repo.is_nascent then - gitano.log.info("Repository " .. repo.name .. " is nascent") +if cmd.takes_repo then + repo, parsed_cmdline = cmd.detect_repo(config, parsed_cmdline) + if not repo and not parsed_cmdline then + gitano.log.fatal("Failed to acquire repository object") end end diff --git a/lib/gitano/admincommand.lua b/lib/gitano/admincommand.lua index f565e96..d0d13ce 100644 --- a/lib/gitano/admincommand.lua +++ b/lib/gitano/admincommand.lua @@ -47,18 +47,12 @@ local function builtin_as_validate(config, _, cmdline) cmdline.cmd = cmd -- If the returned command needs a repo, find it (and save it for later) local repo - if cmd.takes_repo and #cmdline > 3 then + if cmd.takes_repo then -- Acquire the repository object for the target repo - local msg - repo, msg = repository.find(config, cmdline[4]) - if not repo then - log.critical("Unable to locate repository.") - log.critical(" * " .. (tostring(msg))) - log.fatal("Cannot continue") - end - - if repo.is_nascent then - log.info("Repository " .. repo.name .. " is nascent") + repo, cmdline.copy = cmd.detect_repo(config, cmdline.copy) + if not repo and not cmdline.copy then + log.error("Unable to continue") + return false end cmdline.repo = repo end diff --git a/lib/gitano/auth.lua b/lib/gitano/auth.lua index 8cdd8ec..8f288e6 100644 --- a/lib/gitano/auth.lua +++ b/lib/gitano/auth.lua @@ -97,14 +97,9 @@ local function is_authorized(user, source, cmdline) local repo if cmd.takes_repo and #parsed_cmdline > 1 then - -- Acquire the repository object for the target repo - local msg - repo, msg = repository.find(admin_conf, parsed_cmdline[2]) - - if not repo then - log.critical("Unable to locate repository.") - log.critical(" * " .. (tostring(msg) or "No error")) - return nil + repo, parsed_cmdline = cmd.detect_repo(admin_conf, parsed_cmdline) + if not repo and not parsed_cmdline then + return nil end end -- cgit v1.2.1 From 115c62b1d3e0b98020ec4493ce1d9de512a4995a Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Mon, 10 Mar 2014 16:35:58 +0000 Subject: Support for rsync in Troves 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 --- Makefile | 3 +- plugins/rsync.lua | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 plugins/rsync.lua diff --git a/Makefile b/Makefile index 4a94015..cab0162 100644 --- a/Makefile +++ b/Makefile @@ -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 + +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 . ") + 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)) -- cgit v1.2.1 From 98d9af920fb8052b47fdf7cbf2affa5617b6f089 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Wed, 12 Mar 2014 10:09:44 +0000 Subject: RSYNC: Update rsync plugin to fix hiccoughs This removes the rsync path reporting since I'm now confident it works, also we fix a bug in the lace running so that it tests against the right repo and we hide the rsync command since it's not a normal user command. Signed-off-by: Daniel Silverstone --- plugins/rsync.lua | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/rsync.lua b/plugins/rsync.lua index da4bdb7..310fe59 100644 --- a/plugins/rsync.lua +++ b/plugins/rsync.lua @@ -67,9 +67,6 @@ local function rsync_detect_repo(config, cmdline) 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 @@ -91,7 +88,7 @@ local function rsync_prep(config, repo, cmdline, context) else context.operation = "write" end - return config.repo:run_lace(context) + return repo:run_lace(context) end local function rsync_run(config, repo, cmdline, env) @@ -104,5 +101,5 @@ end assert(gitano.command.register("rsync", rsync_short_help, rsync_helptext, rsync_validate, rsync_prep, rsync_run, - true, false, false, + true, true, false, rsync_detect_repo)) -- cgit v1.2.1