|
1 |
| -## |
| 1 | +## @author Dmitry Kolesnikov, <[email protected]> |
| 2 | +## @copyright (c) 2012 - 2014 Dmitry Kolesnikov. All Rights Reserved |
2 | 3 | ##
|
3 |
| -## targets: |
4 |
| -## make all [APP=...] |
5 |
| -## make rel [APP=...] [config=vars.config] |
6 |
| -## make pkg [APP=...] [config=vars.config] |
7 |
| -## make run |
8 |
| -## make test |
| 4 | +## @description |
| 5 | +## Makefile to build and release Erlang applications using standard development tools |
9 | 6 | ##
|
10 |
| -.PHONY: test rel deps all pkg |
| 7 | +## @version 0.11.5 |
11 | 8 |
|
12 |
| -## application name |
13 |
| -ROOT = `pwd` |
| 9 | +##################################################################### |
| 10 | +## |
| 11 | +## application config |
| 12 | +## |
| 13 | +##################################################################### |
14 | 14 | PREFIX ?= /usr/local
|
15 |
| -APP ?= $(notdir $(CURDIR)) |
16 |
| -ARCH = $(shell uname -m) |
17 |
| -PLAT = $(shell uname -s) |
18 |
| -TAG = ${ARCH}.${PLAT} |
19 |
| -TEST?= priv/${APP}.benchmark |
20 |
| -S3 = |
| 15 | +APP ?= $(notdir $(CURDIR)) |
| 16 | +ARCH ?= $(shell uname -m) |
| 17 | +PLAT ?= $(shell uname -s) |
| 18 | +VSN ?= $(shell test -z "`git status --porcelain`" && git describe --tags --long | sed -e 's/-g[0-9a-f]*//' | sed -e 's/-0//' || echo "`git describe --abbrev=0 --tags`-SNAPSHOT") |
| 19 | +REL = ${APP}-${VSN} |
| 20 | +PKG ?= ${REL}+${ARCH}.${PLAT} |
| 21 | +TEST ?= ${APP} |
| 22 | +S3 ?= |
| 23 | +VMI ?= fogfish/erlang |
| 24 | +NET ?= lo0 |
| 25 | +URL ?= undefined |
| 26 | +LATEST ?= latest |
21 | 27 |
|
22 | 28 | ## root path to benchmark framework
|
23 | 29 | BB = ../basho_bench
|
24 | 30 | SSHENV = /tmp/ssh-agent.conf
|
25 |
| - |
26 |
| -## erlang flags |
| 31 | +COOKIE?= nocookie |
| 32 | + |
| 33 | +## erlang runtime flags use by `make run` |
| 34 | +ROOT = $(shell pwd) |
| 35 | +ADDR = $(shell ifconfig ${NET} | sed -En 's/^${NET}:.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' && echo "127.0.0.1") |
27 | 36 | EFLAGS = \
|
28 |
| - -name ${APP}@127.0.0.1 \ |
29 |
| - -setcookie nocookie \ |
30 |
| - -pa ./ebin \ |
31 |
| - -pa deps/*/ebin \ |
32 |
| - -pa apps/*/ebin \ |
| 37 | + -name ${APP}@${ADDR} \ |
| 38 | + -setcookie ${COOKIE} \ |
| 39 | + -pa ${ROOT}/_build/default/lib/*/ebin \ |
| 40 | + -pa ${ROOT}/rel \ |
33 | 41 | -kernel inet_dist_listen_min 32100 \
|
34 | 42 | -kernel inet_dist_listen_max 32199 \
|
35 | 43 | +P 1000000 \
|
36 | 44 | +K true +A 160 -sbt ts
|
37 | 45 |
|
38 |
| -## application release |
39 |
| -ifeq ($(wildcard rel/reltool.config),) |
40 |
| - REL = |
41 |
| - VSN = |
42 |
| - TAR = |
43 |
| - PKG = |
44 |
| -else |
45 |
| - REL = $(shell cat rel/reltool.config | sed -n 's/{target_dir,.*\"\(.*\)\"}./\1/p') |
46 |
| - VSN = $(shell echo ${REL} | sed -n 's/.*-\(.*\)/\1/p') |
47 |
| -ifeq (${VSN},) |
48 |
| - VSN = $(shell cat rel/reltool.config | sed -n 's/.*{rel,.*\".*\",.*\"\(.*\)\".*/\1/p') |
49 |
| -endif |
50 |
| -ifeq (${config},) |
51 |
| - RFLAGS = |
52 |
| - VARIANT = |
53 |
| -else |
54 |
| - VARIANT = $(addprefix ., $(notdir $(basename ${config}))) |
55 |
| - RFLAGS = target_dir=${REL}${VARIANT} overlay_vars=${ROOT}/${config} |
56 |
| -endif |
57 |
| - TAR = ${REL}${VARIANT}.${TAG}.tgz |
58 |
| - PKG = ${REL}${VARIANT}.${TAG}.bundle |
59 |
| -endif |
60 |
| - |
61 | 46 | ## self-extracting bundle wrapper
|
62 |
| -BUNDLE_INIT = PREFIX=${PREFIX}\nREL=${PREFIX}/${REL}${VARIANT}\nAPP=${APP}\nVSN=${VSN}\nLINE=\`grep -a -n 'BUNDLE:\x24' \x240\`\ntail -n +\x24(( \x24{LINE\x25\x25:*} + 1)) \x240 | gzip -vdc - | tar -C ${PREFIX} -xvf - > /dev/null\n |
| 47 | +BUNDLE_INIT = PREFIX=${PREFIX}\nREL=${PREFIX}/${REL}\nAPP=${APP}\nVSN=${VSN}\nLINE=`grep -a -n "BUNDLE:$$" $$0`\nmkdir -p $${REL}\ntail -n +$$(( $${LINE%%%%:*} + 1)) $$0 | gzip -vdc - | tar -C $${REL} -xvf - > /dev/null\n |
63 | 48 | BUNDLE_FREE = exit\nBUNDLE:\n
|
64 |
| -
|
| 49 | +BUILDER = FROM ${VMI}\nRUN mkdir ${APP}\nCOPY . ${APP}/\nRUN cd ${APP} && make && make rel\n |
| 50 | +CTRUN = \ |
| 51 | + -module(test). \ |
| 52 | + -export([run/1]). \ |
| 53 | + run(Spec) -> \ |
| 54 | + {ok, Test} = file:consult(Spec), \ |
| 55 | + case lists:keyfind(node, 1, Test) of \ |
| 56 | + false -> ct:run_test([{spec, Spec}]); \ |
| 57 | + true -> ct_master:run(Spec) \ |
| 58 | + end, \ |
| 59 | + erlang:halt(). |
| 60 | + |
| 61 | +##################################################################### |
65 | 62 | ##
|
66 | 63 | ## build
|
67 | 64 | ##
|
68 |
| -all: rebar deps compile |
| 65 | +##################################################################### |
| 66 | +all: rebar3 compile |
69 | 67 |
|
70 | 68 | compile:
|
71 |
| - @./rebar compile |
72 |
| -
|
73 |
| -deps: |
74 |
| - @./rebar get-deps |
| 69 | + @./rebar3 compile |
75 | 70 |
|
76 | 71 | clean:
|
77 |
| - @./rebar clean ; \ |
78 |
| - rm -rf test.*-temp-data ; \ |
79 |
| - rm -rf tests ; \ |
80 |
| - rm -rf log ; \ |
81 |
| - rm -f *.${TAG}.tgz ; \ |
82 |
| - rm -f *.${TAG}.bundle |
83 |
| -
|
| 72 | + @./rebar3 clean ;\ |
| 73 | + rm -Rf _build/default/rel ;\ |
| 74 | + rm -rf test.*-temp-data ;\ |
| 75 | + rm -rf tests ;\ |
| 76 | + rm -rf log ;\ |
| 77 | + rm -f relx.config ;\ |
| 78 | + rm -f *.tar.gz ;\ |
| 79 | + rm -f *.bundle |
84 | 80 |
|
85 | 81 | distclean: clean
|
86 |
| - @./rebar delete-deps |
| 82 | + @./rebar3 unlock ;\ |
| 83 | + rm -Rf _build ;\ |
| 84 | + rm -Rf rebar3 |
| 85 | + |
| 86 | +## |
| 87 | +## execute unit test |
| 88 | +unit: all |
| 89 | + @./rebar3 skip_deps=true eunit |
| 90 | + |
| 91 | +## |
| 92 | +## execute common test and terminate node |
| 93 | +test: _build/test.beam |
| 94 | + @mkdir -p /tmp/test/${APP} ;\ |
| 95 | + erl ${EFLAGS} -pa _build/ -pa test/ -run test run test/${TEST}.config |
87 | 96 |
|
88 |
| -test: all |
89 |
| - @./rebar skip_deps=true eunit |
| 97 | +_build/test.beam: _build/test.erl |
| 98 | + erlc -o _build $< |
90 | 99 |
|
91 |
| -docs: |
92 |
| - @./rebar skip_deps=true doc |
| 100 | +_build/test.erl: |
| 101 | + echo "${CTRUN}" > $@ |
93 | 102 |
|
| 103 | + |
| 104 | +##################################################################### |
94 | 105 | ##
|
95 |
| -## release |
| 106 | +## release |
96 | 107 | ##
|
97 |
| -ifneq (${REL},) |
98 |
| -rel: |
99 |
| - @./rebar generate ${RFLAGS}; \ |
100 |
| - cd rel ; tar -zcf ../${TAR} ${REL}${VARIANT}/; cd - |
| 108 | +##################################################################### |
| 109 | +rel: ${PKG}.tar.gz |
| 110 | + |
| 111 | +## assemble VM release |
| 112 | +ifeq (${PLAT},$(shell uname -s)) |
| 113 | +${PKG}.tar.gz: relx.config |
| 114 | + @./rebar3 tar -n ${APP} -v ${VSN} ;\ |
| 115 | + cp _build/default/rel/${APP}/${APP}-${VSN}.tar.gz $@ ;\ |
| 116 | + echo "==> tarball: $@" |
| 117 | + |
| 118 | +relx.config: rel/relx.config.src |
| 119 | + @cat $< | sed 's/release/release, {${APP}, "${VSN}"}/' > $@ |
| 120 | +else |
| 121 | +${PKG}.tar.gz: _build/dockermake |
| 122 | + @docker build --file=$< --force-rm=true --tag=build/${APP}:latest . ;\ |
| 123 | + I=`docker create build/${APP}:latest` ;\ |
| 124 | + docker cp $$I:/${APP}/$@ $@ ;\ |
| 125 | + docker rm -f $$I ;\ |
| 126 | + docker rmi build/${APP}:latest ;\ |
| 127 | + test -f $@ && echo "==> tarball: $@" |
| 128 | + |
| 129 | +_build/dockermake: |
| 130 | + @echo "${BUILDER}" > $@ |
| 131 | +endif |
101 | 132 |
|
102 |
| -pkg: rel/deploy.sh rel |
103 |
| - @printf "${BUNDLE_INIT}" > ${PKG} ; \ |
104 |
| - cat rel/deploy.sh >> ${PKG} ; \ |
105 |
| - printf "${BUNDLE_FREE}" >> ${PKG} ; \ |
106 |
| - cat ${TAR} >> ${PKG} ; \ |
107 |
| - chmod ugo+x ${PKG} |
| 133 | +## build docker image |
| 134 | +docker: rel/Dockerfile |
| 135 | + docker build \ |
| 136 | + --build-arg APP=${APP} \ |
| 137 | + --build-arg VSN=${VSN} \ |
| 138 | + -t ${URL}/${APP}:${VSN} -f $< . |
| 139 | + docker tag -f ${URL}/${APP}:${VSN} ${URL}/${APP}:${LATEST} |
108 | 140 |
|
109 |
| -${PKG}: pkg |
110 | 141 |
|
111 |
| -s3: ${PKG} |
112 |
| - aws s3 cp ${PKG} ${S3}/${APP}-latest${VARIANT}.${TAG}.bundle |
113 | 142 |
|
114 |
| -endif |
| 143 | +##################################################################### |
| 144 | +## |
| 145 | +## package / bundle |
| 146 | +## |
| 147 | +##################################################################### |
| 148 | +pkg: ${PKG}.tar.gz ${PKG}.bundle |
| 149 | + |
| 150 | +${PKG}.bundle: rel/deploy.sh |
| 151 | + @printf '${BUNDLE_INIT}' > $@ ;\ |
| 152 | + cat $< >> $@ ;\ |
| 153 | + printf '${BUNDLE_FREE}' >> $@ ;\ |
| 154 | + cat ${PKG}.tar.gz >> $@ ;\ |
| 155 | + chmod ugo+x $@ ;\ |
| 156 | + echo "==> bundle: $@" |
| 157 | + |
| 158 | +## copy 'package' to s3 |
| 159 | +s3: ${PKG}.bundle |
| 160 | + aws s3 cp $< ${S3}/$< |
115 | 161 |
|
| 162 | +s3-latest: ${PKG}.bundle |
| 163 | + aws s3 cp $< ${S3}/${APP}-latest${VARIANT}.bundle |
| 164 | + |
| 165 | +##################################################################### |
116 | 166 | ##
|
117 | 167 | ## deploy
|
118 | 168 | ##
|
| 169 | +##################################################################### |
119 | 170 | ifneq (${host},)
|
120 | 171 | ${SSHENV}:
|
| 172 | + @echo "==> ssh: config keys" ;\ |
121 | 173 | ssh-agent -s > ${SSHENV}
|
122 | 174 |
|
123 |
| -node: ${SSHENV} |
| 175 | +node: ${PKG}.bundle ${SSHENV} |
| 176 | + @echo "==> deploy: ${host}" ;\ |
124 | 177 | . ${SSHENV} ;\
|
125 | 178 | k=`basename ${pass}` ;\
|
126 | 179 | l=`ssh-add -l | grep $$k` ;\
|
127 | 180 | if [ -z "$$l" ] ; then \
|
128 | 181 | ssh-add ${pass} ;\
|
129 | 182 | fi ;\
|
130 |
| - rsync -cav --rsh=ssh --progress ${PKG} ${host}:${PKG} ;\ |
131 |
| - ssh -t ${host} "sudo sh ./${PKG}" |
132 |
| -
|
| 183 | + rsync -cav --rsh=ssh --progress $< ${host}:$< ;\ |
| 184 | + ssh -t ${host} "sudo sh ./$<" |
133 | 185 | endif
|
134 | 186 |
|
| 187 | +##################################################################### |
135 | 188 | ##
|
136 | 189 | ## debug
|
137 | 190 | ##
|
| 191 | +##################################################################### |
138 | 192 | run:
|
139 | 193 | @erl ${EFLAGS}
|
140 | 194 |
|
141 | 195 | benchmark:
|
142 |
| - $(BB)/basho_bench -N [email protected] -C nocookie ${TEST} |
143 |
| - $(BB)/priv/summary.r -i tests/current |
| 196 | + @echo "==> benchmark: ${TEST}" ;\ |
| 197 | + $(BB)/basho_bench -N [email protected] -C nocookie priv/ ${TEST}.benchmark ;\ |
| 198 | + $(BB)/priv/summary.r -i tests/current ;\ |
144 | 199 | open tests/current/summary.png
|
145 | 200 |
|
146 |
| -ifneq (${REL},) |
147 |
| -start: |
148 |
| - @./rel/${REL}${VARIANT}/bin/${APP} start |
149 |
| -
|
150 |
| -stop: |
151 |
| - @./rel/${REL}${VARIANT}/bin/${APP} stop |
152 |
| -
|
153 |
| -console: |
154 |
| - @./rel/${REL}${VARIANT}/bin/${APP} console |
155 |
| -
|
156 |
| -attach: |
157 |
| - @./rel/${REL}${VARIANT}/bin/${APP} attach |
158 |
| -endif |
| 201 | +console: ${PKG}.tar.gz |
| 202 | + @_build/default/rel/${APP}/bin/${APP} console |
159 | 203 |
|
| 204 | +##################################################################### |
160 | 205 | ##
|
161 | 206 | ## dependencies
|
162 | 207 | ##
|
163 |
| -rebar: |
164 |
| - @curl -O https://raw.githubusercontent.com/wiki/basho/rebar/rebar ; \ |
165 |
| - chmod ugo+x rebar |
| 208 | +##################################################################### |
| 209 | +rebar3: |
| 210 | + @curl -L -O https://s3.amazonaws.com/rebar3/rebar3 ; \ |
| 211 | + chmod ugo+x $@ |
| 212 | + |
| 213 | +.PHONY: test rel deps all pkg |
166 | 214 |
|
0 commit comments