-
Notifications
You must be signed in to change notification settings - Fork 1
/
mkd
executable file
·362 lines (338 loc) · 13.4 KB
/
mkd
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
356
357
358
359
360
361
362
#!/usr/bin/env bash
# vim:ts=4:sw=4:expandtab
############################################################
# NAME
# mkd - a toy for make and deploy targets.
#
# SYNOPSIS
# mkd
# mkd [ options ] [ targets ] ...
#
# debug=on mkd ...
#
# OPTIONS
# -C DIRECTORY Change to DIRECTORY before doing anything.
# -f FILE Read FILE as a makefile.
# -h Print this message and exit.
# -j [N] Allow N jobs at once; infinite jobs with no arg.
# -l [N] Don't start multiple jobs unless load is below N.
#
# -m MODULENAME Use MODULENAME as module-name for each target.
# -d DEPLOYPATH Use DEPLOYPATH as deploy-path for each target.
#
# -x Don't use mkx makefile.
# -z Don't use make-flags config.
#
# AUTHORS
# neiku project <[email protected]>
#
# SEE ALSO
# mkxrc_targets
# mkxrc_modules
# mkxrc_configs
# mkxrc_targetregs
#
# VERSION
# 2015/11/21: 支持命令行或者makefile中OUTPUT定义的target
# 支持-f选项指定自定义makefile
# 支持-C选项指定自定义make目录
# 2015/11/22: 支持绝对/相对目录递归mkd
# 2015/11/25: 支持部署路径跟着target配置走,独立于module
# 支持可配置登录方式(目前只支持rsa)
# 支持自定义make前/后执行命令(pre/post-make)
# 支持deploy前/后执行命令(pre/post-deploy)
# 2015/11/26: 支持忽略未配置target
# 2015/11/28: 支持使用mkm查找target(project/global/system级别)
# 支持使用mkm查找module(project/global/system级别)
# 支持使用mkm查找config(project/global/system级别)
# 2015/12/03: 支持本地部署模块(local module)
# 2015/12/05: 支持基于密码登录的远程部署模块(passwd module)
# 2015/12/06: 支持非make编译的target(例如配置文件)
# 2015/12/11: 支持使用mk工具编译target
# 2015/12/23: 支持模式匹配target
# 2015/12/26: 支持忽略pre/post-deploy命令错误信息
# 2016/01/29: 支持透传make -j选项(并行编译)
# 2016/02/16: 支持自定义默认target变量名(key => output-name)
# (默认使用OUTPUT做为默认target变量名)
# 2016/02/17: 支持自定义选项(make选项集的子集 + mkx扩展)
# 支持-x临时不使用mkx makefile(透传mk)
# 支持-z临时不使用make-flags配置(透传mk)
# 2016/04/14: 支持命令行指定module-name(-m)、deploy-path(-d)
# (方便临时切换部署环境)
# 2016/05/01: 支持透传-m/-d选项给mkrun
# 支持自定义module(module type = custom)
# (custom-deployer 配置自定义部署工具)
# 2016/06/18: 支持MKX_CUSTOM_TARGETPATH一直为绝对路径
# 支持su module(module type = su)
# 2017/01/16: 支持跨平台
# - 通过env程序+PATH变量动态查询bash,控制权
# 、准确性都得到保障
#
############################################################
# target(*) <-----> module(1) <-----> deploy destination(1)
# help
function help()
{
echo "Usage: mkd [ options ] [ targets ] ..."
echo "Options:"
echo " -C DIRECTORY Change to DIRECTORY before doing anything."
echo " -f FILE Read FILE as a makefile."
echo " -j [N] Allow N jobs at once; infinite jobs with no arg."
echo " -h Print this message and exit."
echo " -l [N] Don't start multiple jobs unless load is below N."
echo ""
echo " -m MODULENAME Use MODULENAME as module-name for each target."
echo " -d DEPLOYPATH Use DEPLOYPATH as deploy-path for each target."
echo ""
echo " -x Don't use mkx makefile."
echo " -z Don't use make-flags config."
echo ""
echo "Report bugs to <[email protected]>"
}
# mkd -C {cmdline_makedir} -f {cmdline_makefile} {cmdline_options} {cmdline_targets}
cmdline_makedir="`pwd`"
cmdline_makefile=""
cmdline_options=""
cmdline_options_x=""
cmdline_options_z=""
cmdline_targets=""
cmdline_modulename=""
cmdline_deploypath=""
cmdline_forwards=""
# parse cmdline
cmdline="$@"
mklog debug "origin-args:[$@]"
temp=$(getopt -o "C:f:hj::l::m:d:xz" --long "" -n "mkd" -- "$@")
if [ $? != 0 ] ; then
echo "`help`" >&2
exit 1
fi
eval set -- "$temp"
mklog debug "parsed-args:[$temp]"
while true
do
case "$1" in
-C) cmdline_makedir="$2" ; shift 2 ;;
-f) cmdline_makefile="$2" ; shift 2 ;;
-h) echo "`help`" >&2; exit 0;;
-j) cmdline_options="$cmdline_options -j$2"; shift 2;;
-l) cmdline_options="$cmdline_options -l$2"; shift 2;;
-m) cmdline_modulename="$2"; shift 2;;
-d) cmdline_deploypath="$2"; shift 2;;
-x) cmdline_options_x="-x"; shift 1;;
-z) cmdline_options_z="-z"; shift 1;;
--) shift ; break ;;
*) echo "parse options error!" >&2 ; exit 1 ;;
esac
done
cmdline_targets="$@"
mklog debug "cmdline_makedir:[$cmdline_makedir], cmdline_makefile:[$cmdline_makefile]," \
"cmdline_options:[$cmdline_options], cmdline_targets:[$cmdline_targets]," \
"cmdline_options_x:[$cmdline_options_x], cmdline_options_z:[$cmdline_options_z]," \
"cmdline_modulename:[$cmdline_modulename], cmdline_deploypath:[$cmdline_deploypath]"
# cmdline forwards
if [ -n "$cmdline_modulename" ] ; then
cmdline_forwards="$cmdline_forwards -m$cmdline_modulename"
fi
if [ -n "$cmdline_deploypath" ] ; then
cmdline_forwards="$cmdline_forwards -d$cmdline_deploypath"
fi
mklog debug "cmdline_forwards:[$cmdline_forwards]"
# (using $makefile to make and) deploy $targets from $makedir
targets="$cmdline_targets"
makedir="$cmdline_makedir"
makefile="$cmdline_makefile"
# wrapper
succ_exit() { [ -n "$makedir" ] && echo "mkd: Leaving directory '$makedir'"; exit 0; }
fail_exit() { [ -n "$makedir" ] && echo "mkd: Leaving directory '$makedir'"; exit 1; }
# go into make directory if need
if [ -n "$makedir" ] ; then
if [ ! -d "$makedir" ] ; then
mklog error "check directory fail, directory:[$makedir]"
exit 1
fi
echo "mkd: Entering directory '$makedir'"
cd "$makedir" || fail_exit
# keep makedir always abs path
makedir="`pwd`"
fi
# get makefile from cmdline(by user) or make(auto load)
if [ -z "$makefile" ] ; then
makefile="`make $cmdline_options $cmdline_targets -n -p 2>/dev/null \
| grep '^MAKEFILE_LIST' \
| head -n1 \
| awk '{printf $3}'`"
if [ -z "$makefile" -a -z "$targets" ] ; then
mklog error "none-make targets not found, cmdline:[$cmdline]," \
"makefile:[$makefile], targets:[$targets]"
fail_exit
fi
fi
mklog debug "makefile:[$makefile], targets:[$targets]"
if [ -n "$makefile" ] ; then
# check makefile
if [ ! -f "$makefile" ] ; then
mklog error "check makefile fail, makefile:[$makefile]"
fail_exit
fi
# maybe mkd for sub directorys
submakedirs="`make -f $makefile -n -p 2>/dev/null | grep '^DIRS =' | tail -n1 | cut -c8-`"
mklog debug "submakedirs=$submakedirs"
if [ -n "$submakedirs" ] ; then
for subdir in $submakedirs
do
if [ "${subdir:0:1}" = "/" ] ; then
mkd -C $subdir $cmdline_options
else
mkd -C $makedir/$subdir $cmdline_options
fi
done
mklog debug "mkd for directorys end"
succ_exit
fi
# get targets from cmdline
if [ -z "$targets" ] ; then
# default targets from $output var in makefile
output="`mkm get config output-name OUTPUT`"
length="$((${#output} + 4))"
targets="`make -f $makefile -n -p 2>/dev/null | grep "^$output =" | cut -c$length-`"
if [ -z "$targets" ] ; then
mklog error "need-make targets not found, cmdline:[$cmdline]," \
"output-name:[$output], length:[$length]"
fail_exit
fi
fi
mklog debug "targets(need make):[$targets]"
# make targets from cmdline(by user) or make(auto load)
mk -f $makefile $cmdline_options $cmdline_options_x $cmdline_options_z $targets
if [ $? -ne 0 ] ; then
fail_exit
fi
fi
# deploy targets
for target in $targets
do
# .so target is specail
if expr match "$target" ".*\.so$" >/dev/null 2>&1 ; then
if ! expr match "$target" "^lib" >/dev/null 2>&1 ; then
target="lib$target"
fi
fi
# .a target is specail
if expr match "$target" ".*\.a$" >/dev/null 2>&1 ; then
if ! expr match "$target" "^lib" >/dev/null 2>&1 ; then
target="lib$target"
fi
fi
# find target's module
# or use user-defined module-name/deploy-path in cmdline
modulename="$cmdline_modulename";
deploypath="$cmdline_deploypath";
if [ -z "$modulename" -o -z "$deploypath" ] ; then
# find modulename or deploypath by target
eval `mkm find target $target \
| awk '{printf "modulename=%s; deploypath=%s;" \
, $1, $2}'`
if [ -z "$modulename" -o -z "$deploypath" ] ; then
eval `mkm find targetreg $target \
| awk '{printf "modulename=%s; deploypath=%s;" \
, $1, $2}'`
if [ -z "$modulename" -o -z "$deploypath" ] ; then
mklog error "module not found, target:[$target]"
continue
fi
mklog debug "module found in targetreg, target:[$target]"
fi
# use user-defined module name (from cmdline)
if [ -n "$cmdline_modulename" ] ; then
modulename="$cmdline_modulename"
fi
# use user-defined deploy path (from cmdline)
if [ -n "$cmdline_deploypath" ] ; then
deploypath="$cmdline_deploypath"
fi
fi
# find module's info
mtype=""; username=""; rsapkey=""; hostname=""; hostport="";
eval `mkm find module $modulename \
| awk '{printf "mtype=%s; username=%s; rsapkey=%s; hostname=%s; hostport=%s;" \
, $2, $3, $4, $5, $6}'`
mklog debug "target:[$target], module:[$modulename], mtype:[$mtype]," \
"username:[$username], rsa-private:[$rsapkey]," \
"hostname:[$hostname], hostport:[$hostport]," \
"deploypath:[$deploypath], makedir:[$makedir]"
if [ "$mtype" != "rsa" \
-a "$mtype" != "local" \
-a "$mtype" != "passwd" \
-a "$mtype" != "custom" \
-a "$mtype" != "su" ] ; then
mklog error "module type unsupported, type:[$mtype]," \
"supported type:[rsa, local, passwd, custom, su], target:[$target]"
continue
fi
# do deploy
mkrun $cmdline_forwards pre-deploy $target 2>/dev/null
case "$mtype" in
rsa)
if [ -z "$username" -o -z "$rsapkey" \
-o -z "$hostname" -o -z "$hostport" -o -z "$deploypath" ]
then
mklog error "rsa module not ok, target:[$target], module:[$modulename]"
continue
fi
scp -C -i $rsapkey -P $hostport "$makedir/$target" $username@$hostname:$deploypath/
;;
local)
cp -v "$makedir/$target" $deploypath/
;;
passwd)
if [ -z "$username" -o -z "$rsapkey" \
-o -z "$hostname" -o -z "$hostport" -o -z "$deploypath" ]
then
mklog error "passwd module not ok, target:[$target], module:[$modulename]"
continue
fi
mkscpto "$makedir/$target" $username $rsapkey $hostname $hostport $deploypath/
;;
custom)
# custom deployer
customdeployer="`mkm get config custom-deployer`"
if [ -z "$customdeployer" ] ; then
mklog error "custom deployer not found, target:[$target], module:[$modulename]"
continue
fi
mklog debug "custom-deployer:[$customdeployer]"
# run deployer
export MKX_CUSTOM_TARGETPATH="$makedir/$target" \
MKX_CUSTOM_TARGETNAME="$target" \
MKX_CUSTOM_DEPLOYPATH="$deploypath/" \
MKX_CUSTOM_CONFIG1="$modulename" \
MKX_CUSTOM_CONFIG2="$mtype" \
MKX_CUSTOM_CONFIG3="$username" \
MKX_CUSTOM_CONFIG4="$rsapkey" \
MKX_CUSTOM_CONFIG5="$hostname" \
MKX_CUSTOM_CONFIG6="$hostport"
eval "$customdeployer"
unset MKX_CUSTOM_TARGETPATH \
MKX_CUSTOM_TARGETNAME \
MKX_CUSTOM_DEPLOYPATH \
MKX_CUSTOM_CONFIG1 \
MKX_CUSTOM_CONFIG2 \
MKX_CUSTOM_CONFIG3 \
MKX_CUSTOM_CONFIG4 \
MKX_CUSTOM_CONFIG5 \
MKX_CUSTOM_CONFIG6
;;
su)
MKX_MKSU_PASSWORD="$rsapkey" mksu $username "" "cp -v '$makedir/$target' $deploypath/"
;;
*)
mklog error "module type unsupported, type:[$mtype]," \
"supported type:[rsa, local, passwd, custom, su]"
continue
;;
esac
mkrun $cmdline_forwards post-deploy $target 2>/dev/null
done
# all done
succ_exit