-- @@SHEBANG -- -*- lua -*- -- gitano-test-tool -- -- Git (with) Augmented network operations -- testing tool -- -- Copyright 2012 Daniel Silverstone -- -- -- @@GITANO_LUA_PATH local gitano = require "gitano" local gall = require "gall" local luxio = require "luxio" local sio = require "luxio.simple" local sp = require "luxio.subprocess" -- @@GITANO_BIN_PATH -- @@GITANO_SHARE_PATH local argv = {...} local basedir = (luxio.getenv "DATADIR") .. "/" local function user_home(username) return basedir .. "user-home-" .. username end local function ssh_base(username) return user_home(username) .. "/.ssh" end local function ssh_key_file(username, keyname) return ssh_base(username) .. "/" .. keyname end local function unix_assert(ret, errno) if ret ~= 0 then error(luxio.strerror(errno)) end end local function run_program(t) local proc = sp.spawn_simple(t) local how, why = proc:wait() if how == -1 then unix_assert(how, why) end if not (how == "exit" and why == 0) then io.stderr:write(how .. ":" .. tostring(why).."\n") os.exit(1) end end local function esc_quote_all(t) local tt = {} for i = 1, #t do tt[i] = ("%q"):format(t[i]) end return table.concat(tt, " ") end local function load_auth(fname) local fh = io.open(fname, "r") local line = fh:read("*l") local ret = {} while line do line = line:gsub("^ *", "") line = line:gsub(" *$", "") line = line:gsub("^#.*", "") if line ~= "" then local repopath, user, keyset, key = line:match('^[^\\]+\\"([^"]+)\\" \\"([^"]+)\\" \\"([^"]+)\\""[^ ]+ (.+)$') assert(repopath, line) ret[#ret+1] = { repopath = repopath, user = user, keyset = keyset, key = key } ret[key] = ret[#ret] end line = fh:read("*l") end fh:close() return ret end local function generate_exturl(user, key, repo) local authkeys = load_auth(ssh_key_file("testinstance", "authorized_keys")) local pubkey = (sio.open(ssh_key_file(user, key) .. ".pub", "r")):read("*l") local authline = assert(authkeys[pubkey]) local extfmt = "ext::env HOME=%s SSH_CLIENT=%s SSH_ORIGINAL_COMMAND=%s %s %s %s %s" local function esc(s) return ((s:gsub("%%", "%%%%")):gsub(" ", "%% ")) end return (extfmt):format(esc(user_home("testinstance")), esc("10.0.0.1 1234"), "%S% " .. esc(repo), esc(gitano.config.lib_bin_path() .. "/gitano-auth"), esc(authline.repopath), esc(authline.user), esc(authline.keyset)) end function cmd_createunixuser(username) assert(sio.mkdir(user_home(username), "0755")) assert(sio.mkdir(ssh_base(username), "0755")) end function cmd_createsshkey(username, keyname, optionaltype) optionaltype = optionaltype or "rsa" run_program { "ssh-keygen", "-q", "-t", optionaltype, "-C", username .. "-" .. optionaltype .. "@" .. keyname, "-f", ssh_key_file(username, keyname), "-N", "" } end function cmd_setupstandard(owning_user, master_key) local clodname = basedir .. "setup.clod" local fh = io.open(clodname, "w") fh:write('setup.batch "true"\n') fh:write(('paths.pubkey %q\n'):format(ssh_key_file(owning_user, master_key) .. ".pub")) fh:write('site.name "Gitano Test Instance"\n') fh:write('log.prefix "gitano-test"\n') fh:write(('admin.keyname %q\n'):format(master_key)) fh:close() run_program { "gitano-setup", clodname, exe = gitano.config.lib_bin_path() .. "/gitano-setup", env = { HOME = user_home(owning_user) } } end function cmd_cloneviassh(user, key, repo, localname) local exturl = generate_exturl(user, key, repo) run_program { "git", "clone", exturl, user_home(user) .. "/" .. localname, } end function cmd_cloneexists(user, localname) run_program { "git", "fsck", user_home(user) .. "/" .. localname } end function cmd_pubkeyfilename(user, key) print(ssh_key_file(user, key) .. ".pub") end function cmd_runcommand(user, key, ...) local authkeys = load_auth(ssh_key_file("testinstance", "authorized_keys")) local pubkey = (sio.open(ssh_key_file(user, key) .. ".pub", "r")):read("*l") local authline = assert(authkeys[pubkey]) local cmdline = { gitano.config.lib_bin_path() .. "/gitano-auth", authline.repopath, authline.user, authline.keyset, env = {HOME = user_home("testinstance"), SSH_CLIENT="10.0.0.1 1234"} } cmdline.env.SSH_ORIGINAL_COMMAND = esc_quote_all({...}) run_program(cmdline) end function cmd_clonelocation(user, localname) print(user_home(user) .. "/" .. localname) end function cmd_findtoken() local input = sio.stdin:read("*a") local token = input:match("("..("[0-9a-f]"):rep(40)..")") assert(token, "Cannot find a token") print(token) end local cmd = table.remove(argv, 1) if _G['cmd_' .. cmd] then _G['cmd_' .. cmd](unpack(argv)) else error("Unknown command: " .. cmd) end