Project

General

Profile

Download (5.47 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-2020 Rubicon Communications, LLC (Netgate)
7
# All rights reserved.
8
#
9
# Licensed under the Apache License, Version 2.0 (the "License");
10
# you may not use this file except in compliance with the License.
11
# You may obtain a copy of the License at
12
#
13
# http://www.apache.org/licenses/LICENSE-2.0
14
#
15
# Unless required by applicable law or agreed to in writing, software
16
# distributed under the License is distributed on an "AS IS" BASIS,
17
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
# See the License for the specific language governing permissions and
19
# limitations under the License.
20

    
21
usage() {
22
	echo "Usage: $(basename $0) [-l] [-n] [-r] [-U] [-p] [-i]"
23
	echo "	-l: Build looped operations"
24
	echo "	-n: Do not build images, only core pkg repo"
25
	echo "	-p: Update poudriere repo"
26
	echo "	-r: Do not reset local changes"
27
	echo "	-U: Upload snapshots"
28
	echo "	-i: Skip rsync to final server"
29
}
30

    
31
export BUILDER_TOOLS=$(realpath $(dirname ${0}))
32
export BUILDER_ROOT=$(realpath "${BUILDER_TOOLS}/..")
33

    
34
IMAGES="all"
35
NO_RESET=""
36
UPLOAD=""
37
_SKIP_FINAL_RSYNC=""
38
LOOPED_SNAPSHOTS=""
39
POUDRIERE_SNAPSHOTS=""
40

    
41
# Handle command line arguments
42
while getopts lnprUi opt; do
43
	case ${opt} in
44
		n)
45
			IMAGES="none"
46
			;;
47
		l)
48
			LOOPED_SNAPSHOTS=1
49
			;;
50
		p)
51
			POUDRIERE_SNAPSHOTS=--poudriere-snapshots
52
			;;
53
		r)
54
			NO_RESET=1
55
			;;
56
		U)
57
			UPLOAD="-U"
58
			;;
59
		i)
60
			_SKIP_FINAL_RSYNC="-i"
61
			;;
62
		*)
63
			usage
64
			exit 1
65
			;;
66
	esac
67
done
68

    
69
if [ -n "${POUDRIERE_SNAPSHOTS}" ]; then
70
	export minsleepvalue=${minsleepvalue:-"360"}
71
else
72
	export minsleepvalue=${minsleepvalue:-"28800"}
73
fi
74
export maxsleepvalue=${maxsleepvalue:-"86400"}
75

    
76
# Keeps track of how many time builder has looped
77
export BUILDCOUNTER=0
78
export COUNTER=0
79

    
80
# Global variable used to control SIGINFO action
81
export _sleeping=0
82

    
83
snapshot_update_status() {
84
	${BUILDER_ROOT}/build.sh ${_SKIP_FINAL_RSYNC} ${UPLOAD} \
85
		${POUDRIERE_SNAPSHOTS} --snapshot-update-status "$*"
86
}
87

    
88
exec_and_update_status() {
89
	local _cmd="${@}"
90

    
91
	[ -z "${_cmd}" ] \
92
		&& return 1
93

    
94
	# Ref. https://stackoverflow.com/a/30658405
95
	exec 4>&1
96
	local _result=$( \
97
	    { { ${_cmd} 2>&1 3>&-; printf $? 1>&3; } 4>&- \
98
	    | while read -r LINE; do \
99
	    snapshot_update_status "${LINE}"; done 1>&4; } 3>&1)
100
	exec 4>&-
101

    
102
	return ${_result}
103
}
104

    
105
git_last_commit() {
106
	[ -z "${NO_RESET}" ] \
107
		&& git -C "${BUILDER_ROOT}" reset --hard >/dev/null 2>&1
108
	git -C "${BUILDER_ROOT}" pull -q
109
	if [ -n "${POUDRIERE_SNAPSHOTS}" ]; then
110
		local _remote_repo=$(${BUILDER_ROOT}/build.sh -V POUDRIERE_PORTS_GIT_URL)
111
		local _remote_branch=$(${BUILDER_ROOT}/build.sh -V POUDRIERE_PORTS_GIT_BRANCH)
112
		export CURRENT_COMMIT=$(git ls-remote ${_remote_repo} ${_remote_branch} | cut -f1)
113
	else
114
		export CURRENT_COMMIT=$(git -C ${BUILDER_ROOT} log -1 --format='%H')
115
	fi
116
}
117

    
118
restart_build() {
119
	if [ ${_sleeping} -ne 0 ]; then
120
		snapshot_update_status ">>> SIGNINFO received, restarting build"
121
		COUNTER=$((maxsleepvalue + 60))
122
	fi
123
}
124

    
125
# This routine is called in between runs. We
126
# will sleep for a bit and check for new commits
127
# in between sleeping for short durations.
128
snapshots_sleep_between_runs() {
129
	# Handle SIGINFO (ctrl+T) and restart build
130
	trap restart_build SIGINFO
131

    
132
	# Initialize variables that keep track of last commit
133
	[ -z "${LAST_COMMIT}" ] \
134
		&& export LAST_COMMIT=${CURRENT_COMMIT}
135

    
136
	snapshot_update_status ">>> Sleeping for at least $minsleepvalue," \
137
		"at most $maxsleepvalue in between snapshot builder runs."
138
	snapshot_update_status ">>> Last known commit: ${LAST_COMMIT}"
139
	snapshot_update_status ">>> Freezing build process at $(date)"
140
	echo ">>> Press ctrl+T to start a new build"
141
	COUNTER=0
142
	_sleeping=1
143
	while [ ${COUNTER} -lt ${minsleepvalue} ]; do
144
		sleep 1
145
		COUNTER=$((COUNTER + 1))
146
	done
147

    
148
	if [ ${COUNTER} -lt ${maxsleepvalue} ]; then
149
		snapshot_update_status ">>> Thawing build process and" \
150
			"resuming checks for pending commits at $(date)."
151
		echo ">>> Press ctrl+T to start a new build"
152
	fi
153

    
154
	while [ $COUNTER -lt $maxsleepvalue ]; do
155
		sleep 1
156
		COUNTER=$(($COUNTER + 1))
157
		# Update this repo each 60 seconds
158
		if [ "$((${COUNTER} % 60))" != "0" ]; then
159
			continue
160
		fi
161
		git_last_commit
162
		if [ "${LAST_COMMIT}" != "${CURRENT_COMMIT}" ]; then
163
			snapshot_update_status ">>> New commit:" \
164
				"$CURRENT_COMMIT " \
165
				".. No longer sleepy."
166
			COUNTER=$(($maxsleepvalue + 60))
167
			export LAST_COMMIT="${CURRENT_COMMIT}"
168
		fi
169
	done
170
	_sleeping=0
171

    
172
	if [ $COUNTER -ge $maxsleepvalue ]; then
173
		snapshot_update_status ">>> Sleep timer expired." \
174
			"Restarting build."
175
		COUNTER=0
176
	fi
177

    
178
	trap "-" SIGINFO
179
}
180

    
181
# Main builder loop
182
while [ /bin/true ]; do
183
	BUILDCOUNTER=$((${BUILDCOUNTER}+1))
184

    
185
	git_last_commit
186

    
187
	OIFS=${IFS}
188
	IFS="
189
"
190
	if [ -n "${POUDRIERE_SNAPSHOTS}" ]; then
191
		exec_and_update_status \
192
		    ${BUILDER_ROOT}/build.sh --update-poudriere-ports
193
		rc=$?
194

    
195
		if [ $rc -eq 0 ]; then
196
			exec_and_update_status \
197
			    ${BUILDER_ROOT}/build.sh ${_SKIP_FINAL_RSYNC} \
198
			    ${UPLOAD} --update-pkg-repo
199
			rc=$?
200
		fi
201
	else
202
		exec_and_update_status \
203
		    ${BUILDER_ROOT}/build.sh --clean-builder
204
		rc=$?
205

    
206
		if [ $rc -eq 0 ]; then
207
			exec_and_update_status \
208
			    ${BUILDER_ROOT}/build.sh ${_SKIP_FINAL_RSYNC} \
209
			    ${UPLOAD} --snapshots ${IMAGES}
210
			rc=$?
211
		fi
212
	fi
213
	IFS=${OIFS}
214

    
215
	if [ -z "${LOOPED_SNAPSHOTS}" ]; then
216
		# only one build required, exiting
217
		exit ${rc}
218
	fi
219

    
220
	# Count some sheep or wait until a new commit turns up
221
	# for one days time.  We will wake up if a new commit
222
	# is detected during sleepy time.
223
	snapshots_sleep_between_runs
224
done
(1-1/3)