-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtt
executable file
·355 lines (295 loc) · 7.95 KB
/
tt
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
#!/bin/bash
# variables
TT_PROJECTS=${TT_PROJECTS:-~/projects}
TT_IS_GLOBAL=$([ "$0" = "/usr/local/bin/tt" ] && echo true || echo false)
TT_SHARE=$([ $TT_IS_GLOBAL = true ] && echo /usr/local/share/tarantino || dirname $0)
TT_HOME=${TT_HOME:-~/.tt}
source $TT_SHARE/dc.sh
source $TT_SHARE/install.sh
source $TT_SHARE/parse-yaml.sh
source $TT_SHARE/workspace.sh
tt_get_services() {
dc_get_services
}
tt_get_sources() {
dc_get_sources
}
tt_get_services_with_source() {
dc_get_services_with_source
}
tt_get_available_workspaces() {
ws_ls
}
info() {
echo INFO: $*
}
main() {
local user=${SUDO_USER:-$USER}
if ! groups $user | grep &>/dev/null '\bdocker\b'; then
>&2 echo WARNING: You\'re not in the \"docker\" group. You may need to log out and back in.
>&2 echo
fi
local workspace_dir=$(get_workspace_dir)
if [[ -z "$workspace_dir" && ! -z "$1" ]]; then
case "$1" in
install) ;;
upgrade) ;;
version) ;;
workspace) ;;
*)
>&2 echo "ERROR: You don't have an active workspace. Run 'tt workspace use <workspace>' to select one."
>&2 echo
>&2 echo Available workspaces:
for dep in $(ws_ls); do
>&2 echo " $dep"
done
return 1
;;
esac
else
## load workspace plugins
if [ -d "$workspace_dir/plugins" ]; then
for plugin in $(find "$workspace_dir/plugins" -name '*.sh')
do
source $plugin
done
fi
fi
run_sub_command tt $@
}
run_sub_command() {
local prefix=$1
shift
local show_usage="${prefix}_usage"
if [ $# -eq 0 ]; then
$show_usage
return 1
fi
local cmd=$1
shift
local command="${prefix}_${cmd}"
local command_type=$(type -t $command)
if [ "$command_type" != "function" ]; then
$show_usage
return 1
fi
$command $*
}
tt_header() {
echo "tarantino - cross-service development environment"
echo
}
tt_usage() {
tt_header
echo "usage: tt <command> [args]"
echo
echo "Tarantino commands:"
echo
echo " browse <container[:port][path]> - launch a page of a named container in your browser"
echo " check [service] - check all [or named] source directories"
echo " clone [service] - clone all [or named] source directories"
echo " create [container...] - create all [or named] containers"
echo " dc - run docker-compose commands in the context of your workspace"
echo " destroy [container...] - destroy all [or named] containers"
echo " install - prepare environment for tarantino"
echo " ip <container> [-q | network_name] - retrieve ip addresses for a specific container [-q quiet or <network name>]: for only 1 unlabelled ip]"
echo " pull [service] - pull sources for all [or named] projects without changes"
echo " recreate [container...] - recreate all [or named] containers"
echo " restart - restart all containers"
echo " upgrade - upgrade to latest tarantino version"
echo " version - outputs the tt version"
echo " workspace [command] - create, remove and switch workspaces"
workspace_plugin_usage_
}
workspace_plugin_usage_() {
plugin_usage_functions=$(declare -F | grep 'plugin_usage$' | awk '{print $3}')
if [ "$plugin_usage_functions" != "" ]; then
echo
echo 'Workspace plugin commands:'
echo
for usage_function in $plugin_usage_functions; do
$usage_function
done
fi
}
tt_browse() {
local raw=$(echo $* | sed 's/ //g') # merge all args into 1 string
local container=$raw
local path=""
local port=""
local parseRegex='^([^:/?#]+)(:[0-9]+)?([\/?#].*)?'
if [[ $raw =~ $parseRegex ]]; then
container=${BASH_REMATCH[1]}
port=${BASH_REMATCH[2]}
path=${BASH_REMATCH[3]}
else
tt_usage | grep -e '^[ ]*browse'
return 1
fi
local ip=$(tt_ip $container -q)
local url=http://$ip$port$path
if [ "$ip" = "" ]; then
echo $container is not running, starting
tt_create $container
local ip=$(tt_ip $container -q)
local host=http://$ip$port
local url=$host$path
until curl $host &> /dev/null; do
sleep 0.25
echo waiting for $container web server to start: curl $host
done
fi
echo Opening browser to $url...
x-www-browser $url &> /dev/null &
}
tt_check() {
local projects=$TT_PROJECTS
local service=$(dc_get_service_and_dependencies_with_source $@)
local success=true
for service in $service; do
if [ ! -d "$projects/$service" ]; then
echo $service not found in projects directory $projects.
success=false
fi
done
if [ "$success" = "true" ]; then # return success/error code
echo All projects found in projects directory $projects.
return 0
else
return 1
fi
}
get_repo_url() {
local src=$1
## org/repo shorthand format
if [[ $src =~ ^[-A-Za-z0-9_]*\/[-A-Za-z0-9_.]*$ ]]; then
echo "[email protected]:${src}.git"
else
echo ${src}
fi
}
tt_clone() {
local projects=$TT_PROJECTS
local services=$(dc_get_service_and_dependencies $@)
eval "declare -A TT_SOURCES=($(dc_get_sources))" # sources hashtable
pushd . &> /dev/null
for service in $services; do
local src=$(get_repo_url ${TT_SOURCES[$service]})
# if source is defined but directory doesn't exist
if [ ! -z "$src" -a ! -d "$projects/$service" ]; then
echo $service not found in projects directory $projects, cloning it.
git clone $src $projects/$service || return 1;
# run npm install for any npm packages (the service, or its components)
find "$projects/$service" -name 'package.json' -not -path "**/bower_components/*" | xargs --no-run-if-empty dirname | grep -v 'node_modules' | while read module; do
cd $module
echo in $module directory running: npm install
npm install
done
fi
done
popd &> /dev/null
}
tt_pull() {
local projects=$TT_PROJECTS
local services=$(dc_get_service_and_dependencies_with_source $@)
local skipped=
local updated=
local current=
pushd .
for service in $services; do
if [ -d "$projects/$service" ]; then
cd $projects/$service
echo ---- $service ----
if [ "$(git status --porcelain | wc -c)" = "0" ]; then
current=$(git rev-parse HEAD)
git pull --rebase --ff-only
if [ $? -ne 0 ]; then
skipped="$skipped $service"
elif [ $current != "$(git rev-parse HEAD)" ]; then
updated="$updated $service"
fi
else
echo Skipping $service because the working directory is not clean.
skipped="$skipped $service"
fi
fi
done
echo
echo Updated: $updated
echo Not Clean: $skipped
popd
}
tt_create() {
if ! tt_check $@; then
echo "NOTE: You must clone service repositories before creating containers; otherwise, empty root-privilege directories would be created and that's poop."
echo 'Running "tt clone" to retrieve the missing repositories.'
tt_clone $@
fi
dc up -d $@
for service in $@; do
echo "$service ip(s):"
tt_ip $service
done
}
tt_destroy() {
if [[ $# -eq 0 ]]; then
dc kill
dc down -v # destroys networks, etc.
else
dc kill $@
dc rm -fv $@
fi
}
tt_ip() {
ip_pairs=$(docker inspect --format '{{range $i, $n := .NetworkSettings.Networks }}{{$i}}:{{$n.IPAddress}} {{end}}' "$(get_container_name "$1")")
tokens=($(echo $ip_pairs | tr ' ' "\n"))
# if in quiet mode, or there is only one network, output only the one IP
if [[ $2 == "-q" ]] || [[ ${#tokens[@]} -eq 1 ]]; then
# if the container is in host mode, output 0.0.0.0
if [[ ${tokens[0]} == "host:" ]]; then
echo "0.0.0.0"
return;
fi
echo ${tokens[0]} | cut -d ":" -f 2
return;
fi
# assume -q not provided
if [[ ! -z $2 ]]; then
for token in $tokens; do
if [[ $(echo ${token} | cut -d ":" -f 1) == $(get_network_name "$2") ]]; then
echo $token | cut -d ":" -f 2
return;
fi
done
return 1;
fi
for pair in $ip_pairs; do
echo $pair
done
}
tt_recreate() {
tt_destroy $@
info creating containers
tt_create $@
}
tt_restart() {
dc kill $@
dc start $@
}
tt_upgrade() {
local tmpdir=$(mktemp -d)
git clone [email protected]:meet-tarantino/tarantino.git $tmpdir || return 1
sudo echo "About to launch installation. Please wait for confirmation that install is complete."
sudo bash -c "cd $tmpdir; sleep 1s; make install" &
}
tt_get_workspace() {
get_workspace
}
tt_version() {
if ! $TT_IS_GLOBAL; then
echo "local"
return 0;
fi
cat "${TT_SHARE}/version.txt" 2> /dev/null
}
main $@