1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
-- @@SHEBANG
-- -*- lua -*-
-- gitano-test-tool
--
-- Git (with) Augmented network operations -- testing tool
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
--
-- @@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
|