Project

General

Profile

Download (7.13 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/bin/sh
2
#
3
# build_snapshots.sh
4
#
5
# part of pfSense (https://www.pfsense.org)
6
# Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
# All rights reserved.
8
#
9
# Redistribution and use in source and binary forms, with or without
10
# modification, are permitted provided that the following conditions are met:
11
#
12
# 1. Redistributions of source code must retain the above copyright notice,
13
#    this list of conditions and the following disclaimer.
14
#
15
# 2. Redistributions in binary form must reproduce the above copyright
16
#    notice, this list of conditions and the following disclaimer in
17
#    the documentation and/or other materials provided with the
18
#    distribution.
19
#
20
# 3. All advertising materials mentioning features or use of this software
21
#    must display the following acknowledgment:
22
#    "This product includes software developed by the pfSense Project
23
#    for use in the pfSense® software distribution. (http://www.pfsense.org/).
24
#
25
# 4. The names "pfSense" and "pfSense Project" must not be used to
26
#    endorse or promote products derived from this software without
27
#    prior written permission. For written permission, please contact
28
#    coreteam@pfsense.org.
29
#
30
# 5. Products derived from this software may not be called "pfSense"
31
#    nor may "pfSense" appear in their names without prior written
32
#    permission of the Electric Sheep Fencing, LLC.
33
#
34
# 6. Redistributions of any form whatsoever must retain the following
35
#    acknowledgment:
36
#
37
# "This product includes software developed by the pfSense Project
38
# for use in the pfSense software distribution (http://www.pfsense.org/).
39
#
40
# THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
41
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
44
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51
# OF THE POSSIBILITY OF SUCH DAMAGE.
52

    
53
usage() {
54
	echo "Usage: $(basename $0) [-l] [-n] [-r] [-U] [-p] [-i]"
55
	echo "	-l: Build looped operations"
56
	echo "	-n: Do not build images, only core pkg repo"
57
	echo "	-p: Update poudriere repo"
58
	echo "	-r: Do not reset local changes"
59
	echo "	-U: Upload snapshots"
60
	echo "	-i: Skip rsync to final server"
61
}
62

    
63
export BUILDER_TOOLS=$(realpath $(dirname ${0}))
64
export BUILDER_ROOT=$(realpath "${BUILDER_TOOLS}/..")
65

    
66
NO_IMAGES=""
67
NO_RESET=""
68
UPLOAD=""
69
_SKIP_FINAL_RSYNC=""
70
LOOPED_SNAPSHOTS=""
71
POUDRIERE_SNAPSHOTS=""
72

    
73
# Handle command line arguments
74
while getopts lnprUi opt; do
75
	case ${opt} in
76
		n)
77
			NO_IMAGES="none"
78
			;;
79
		l)
80
			LOOPED_SNAPSHOTS=1
81
			;;
82
		p)
83
			POUDRIERE_SNAPSHOTS=--poudriere-snapshots
84
			;;
85
		r)
86
			NO_RESET=1
87
			;;
88
		U)
89
			UPLOAD="-U"
90
			;;
91
		i)
92
			_SKIP_FINAL_RSYNC="-i"
93
			;;
94
		*)
95
			usage
96
			exit 1
97
			;;
98
	esac
99
done
100

    
101
if [ -n "${POUDRIERE_SNAPSHOTS}" ]; then
102
	export minsleepvalue=${minsleepvalue:-"360"}
103
else
104
	export minsleepvalue=${minsleepvalue:-"28800"}
105
fi
106
export maxsleepvalue=${maxsleepvalue:-"86400"}
107

    
108
# Keeps track of how many time builder has looped
109
export BUILDCOUNTER=0
110
export COUNTER=0
111

    
112
# Global variable used to control SIGINFO action
113
export _sleeping=0
114

    
115
snapshot_update_status() {
116
	${BUILDER_ROOT}/build.sh ${_SKIP_FINAL_RSYNC} ${UPLOAD} \
117
		${POUDRIERE_SNAPSHOTS} --snapshot-update-status "$*"
118
}
119

    
120
exec_and_update_status() {
121
	local _cmd="${@}"
122

    
123
	[ -z "${_cmd}" ] \
124
		&& return 1
125

    
126
	# Ref. https://stackoverflow.com/a/30658405
127
	exec 4>&1
128
	local _result=$( \
129
	    { { ${_cmd} 2>&1 3>&-; printf $? 1>&3; } 4>&- \
130
	    | while read -r LINE; do \
131
	    snapshot_update_status "${LINE}"; done 1>&4; } 3>&1)
132
	exec 4>&-
133

    
134
	return ${_result}
135
}
136

    
137
git_last_commit() {
138
	[ -z "${NO_RESET}" ] \
139
		&& git -C "${BUILDER_ROOT}" reset --hard >/dev/null 2>&1
140
	git -C "${BUILDER_ROOT}" pull -q
141
	if [ -n "${POUDRIERE_SNAPSHOTS}" ]; then
142
		local _remote_repo=$(${BUILDER_ROOT}/build.sh -V POUDRIERE_PORTS_GIT_URL)
143
		local _remote_branch=$(${BUILDER_ROOT}/build.sh -V POUDRIERE_PORTS_GIT_BRANCH)
144
		export CURRENT_COMMIT=$(git ls-remote ${_remote_repo} ${_remote_branch} | cut -f1)
145
	else
146
		export CURRENT_COMMIT=$(git -C ${BUILDER_ROOT} log -1 --format='%H')
147
	fi
148
}
149

    
150
restart_build() {
151
	if [ ${_sleeping} -ne 0 ]; then
152
		snapshot_update_status ">>> SIGNINFO received, restarting build"
153
		COUNTER=$((maxsleepvalue + 60))
154
	fi
155
}
156

    
157
# This routine is called in between runs. We
158
# will sleep for a bit and check for new commits
159
# in between sleeping for short durations.
160
snapshots_sleep_between_runs() {
161
	# Handle SIGINFO (ctrl+T) and restart build
162
	trap restart_build SIGINFO
163

    
164
	# Initialize variables that keep track of last commit
165
	[ -z "${LAST_COMMIT}" ] \
166
		&& export LAST_COMMIT=${CURRENT_COMMIT}
167

    
168
	snapshot_update_status ">>> Sleeping for at least $minsleepvalue," \
169
		"at most $maxsleepvalue in between snapshot builder runs."
170
	snapshot_update_status ">>> Last known commit: ${LAST_COMMIT}"
171
	snapshot_update_status ">>> Freezing build process at $(date)"
172
	echo ">>> Press ctrl+T to start a new build"
173
	COUNTER=0
174
	_sleeping=1
175
	while [ ${COUNTER} -lt ${minsleepvalue} ]; do
176
		sleep 1
177
		COUNTER=$((COUNTER + 1))
178
	done
179

    
180
	if [ ${COUNTER} -lt ${maxsleepvalue} ]; then
181
		snapshot_update_status ">>> Thawing build process and" \
182
			"resuming checks for pending commits at $(date)."
183
		echo ">>> Press ctrl+T to start a new build"
184
	fi
185

    
186
	while [ $COUNTER -lt $maxsleepvalue ]; do
187
		sleep 1
188
		COUNTER=$(($COUNTER + 1))
189
		# Update this repo each 60 seconds
190
		if [ "$((${COUNTER} % 60))" != "0" ]; then
191
			continue
192
		fi
193
		git_last_commit
194
		if [ "${LAST_COMMIT}" != "${CURRENT_COMMIT}" ]; then
195
			snapshot_update_status ">>> New commit:" \
196
				"$CURRENT_COMMIT " \
197
				".. No longer sleepy."
198
			COUNTER=$(($maxsleepvalue + 60))
199
			export LAST_COMMIT="${CURRENT_COMMIT}"
200
		fi
201
	done
202
	_sleeping=0
203

    
204
	if [ $COUNTER -ge $maxsleepvalue ]; then
205
		snapshot_update_status ">>> Sleep timer expired." \
206
			"Restarting build."
207
		COUNTER=0
208
	fi
209

    
210
	trap "-" SIGINFO
211
}
212

    
213
# Main builder loop
214
while [ /bin/true ]; do
215
	BUILDCOUNTER=$((${BUILDCOUNTER}+1))
216

    
217
	git_last_commit
218

    
219
	OIFS=${IFS}
220
	IFS="
221
"
222
	if [ -n "${POUDRIERE_SNAPSHOTS}" ]; then
223
		exec_and_update_status \
224
		    ${BUILDER_ROOT}/build.sh --update-poudriere-ports
225
		rc=$?
226

    
227
		if [ $rc -eq 0 ]; then
228
			exec_and_update_status \
229
			    ${BUILDER_ROOT}/build.sh ${_SKIP_FINAL_RSYNC} \
230
			    ${UPLOAD} --update-pkg-repo
231
			rc=$?
232
		fi
233
	else
234
		exec_and_update_status \
235
		    ${BUILDER_ROOT}/build.sh --clean-builder
236
		rc=$?
237

    
238
		if [ $rc -eq 0 ]; then
239
			exec_and_update_status \
240
			    ${BUILDER_ROOT}/build.sh ${_SKIP_FINAL_RSYNC} \
241
			    ${UPLOAD} --flash-size '2g 4g' --snapshots ${IMAGES}
242
			rc=$?
243
		fi
244
	fi
245
	IFS=${OIFS}
246

    
247
	if [ -z "${LOOPED_SNAPSHOTS}" ]; then
248
		# only one build required, exiting
249
		exit ${rc}
250
	fi
251

    
252
	# Count some sheep or wait until a new commit turns up
253
	# for one days time.  We will wake up if a new commit
254
	# is detected during sleepy time.
255
	snapshots_sleep_between_runs
256
done
(1-1/3)