Project

General

Profile

Download (6.63 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/bin/sh
2

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

    
49
# pkg should not ask for confirmations
50
export ASSUME_ALWAYS_YES=true
51

    
52
# Disable automatic update
53
export REPO_AUTOUPDATE=false
54

    
55
# Firmware lock subsystem
56
firmwarelock=/var/run/firmwarelock.dirty
57

    
58
# File used to detect second call, after kernel update and reboot
59
upgrade_in_progress="/cf/conf/upgrade_in_progress"
60

    
61
if [ -f "${firmwarelock}" ]; then
62
	_echo "ERROR: Another upgrade is running... aborting."
63
	exit 0
64
fi
65

    
66
stdout='/dev/null'
67
unset yes
68
while getopts dys opt; do
69
	case ${opt} in
70
		d)
71
			stdout=''
72
			;;
73
		y)
74
			yes=1
75
			;;
76
		*)
77
			usage
78
			exit 1
79
			;;
80
	esac
81
done
82

    
83
usage() {
84
	_echo "Usage: $(basename ${0}) [-d] [-y] [-c]"
85
}
86

    
87
_echo() {
88
	local _n=""
89
	if [ "${1}" = "-n" ]; then
90
		shift
91
		_n="-n"
92
	fi
93

    
94
	if [ -z "${logfile}" ]; then
95
		logfile=/dev/null
96
	fi
97

    
98
	echo ${_n} "${1}" | tee -a ${logfile}
99
}
100

    
101
_exec() {
102
	local _cmd="${1}"
103
	local _msg="${2}"
104
	local _mute="${3}"
105
	local _ignore_result="${4}"
106
	local _stdout="${stdout}"
107

    
108
	if [ -z "${_cmd}" -o -z "${_msg}" ]; then
109
		return 1
110
	fi
111

    
112
	if [ "${_mute}" != "mute" ]; then
113
		_stdout=''
114
	fi
115

    
116
	_echo -n ">>> ${_msg}... "
117
	if [ -z "${_stdout}" ]; then
118
		_echo ""
119
		${_cmd} 2>&1 | tee -a ${logfile}
120
	else
121
		${_cmd} >${_stdout} 2>&1 | tee -a ${logfile}
122
	fi
123
	local _result=$?
124

    
125
	if [ ${_result} -eq 0 -o -n "${_ignore_result}" ]; then
126
		[ -n "${_stdout}" ] \
127
			&& _echo "done."
128
		return 0
129
	else
130
		[ -n "${_stdout}" ] \
131
			&& _echo "failed."
132
		return 1
133
	fi
134
}
135

    
136
_exit() {
137
	if [ -n "${kernel_pkg}" ]; then
138
		_exec "pkg lock ${kernel_pkg}" "Locking kernel package" mute ignore_result
139
	fi
140
	if [ -f "${firmwarelock}" ]; then
141
		rm -f ${firmwarelock}
142
	fi
143
}
144

    
145
first_step() {
146
	_exec "pkg update" "Updating repositories" mute ignore_result
147

    
148
	# figure out which kernel variant is running
149
	kernel_pkg=$(pkg query %n $(pkg info pfSense-kernel-\*))
150

    
151
	if [ -z "${kernel_pkg}" ]; then
152
		_echo "ERROR: It was not possible to identify which pfSense kernel is installed"
153
		exit 1
154
	fi
155

    
156
	kernel_local=$(pkg query %v ${kernel_pkg})
157

    
158
	if [ -z "${kernel_local}" ]; then
159
		_echo "ERROR: It was not possible to determine pfSense kernel local version"
160
		exit 1
161
	fi
162

    
163
	kernel_remote=$(pkg rquery %v ${kernel_pkg})
164

    
165
	if [ -z "${kernel_remote}" ]; then
166
		_echo "ERROR: It was not possible to determine pfSense kernel remote version"
167
		exit 1
168
	fi
169

    
170
	kernel_version_compare=$(pkg version -t ${kernel_local} ${kernel_remote})
171

    
172
	if [ "${kernel_version_compare}" = "<" ]; then
173
		kernel_update=1
174
		# Make sure we lock kernel package again
175
		trap _exit 1 2 15 EXIT
176
		_exec "pkg unlock ${kernel_pkg}" "Unlocking kernel package" mute ignore_result
177
	elif [ "${kernel_version_compare}" = "=" ]; then
178
		kernel_update=0
179
	elif [ "${kernel_version_compare}" = ">" ]; then
180
		_echo "ERROR: You are using a newer kernel version than remote repository"
181
		exit 1
182
	else
183
		_echo "ERROR: Error comparing pfSense kernel local and remote versions"
184
		exit 1
185
	fi
186

    
187
	# XXX find a samrter way to do it
188
	l=$(pkg upgrade -nq | wc -l)
189
	if [ ${l} -eq 1 ]; then
190
		_echo "Your packages are up to date"
191
		exit 0
192
	fi
193

    
194
	if [ -z "${yes}" ]; then
195
		# Show user which packages are going to be upgraded
196
		pkg upgrade -nq 2>&1 | tee -a ${logfile}
197

    
198
		_echo ""
199
		if [ ${kernel_update} -eq 1 ]; then
200
			_echo "**** WARNING ****"
201
			_echo "Reboot will be required!!"
202
		fi
203
		_echo -n "Proceed with upgrade? (y/N) "
204
		read answer
205
		if [ "${answer}" != "y" ]; then
206
			_echo "Aborting..."
207
			exit 0
208
		fi
209
	fi
210

    
211
	_echo ">>> Downloading packages..."
212
	if ! pkg upgrade -F 2>&1 | tee -a ${logfile}; then
213
		_echo "ERROR: It was not possible to download packages"
214
		exit 1
215
	fi
216

    
217
	# Mark firmware subsystem dirty
218
	trap _exit 1 2 15 EXIT
219
	touch ${firmwarelock}
220

    
221
	# First upgrade kernel and reboot
222
	if [ ${kernel_update} -eq 1 ]; then
223
		_exec "pkg upgrade ${kernel_pkg}" "Upgrading pfSense kernel"
224
		touch ${upgrade_in_progress}
225
		_echo "Rebooting..."
226
		/etc/rc.reboot
227
	fi
228
}
229

    
230
second_step() {
231
	_echo "Upgrading necessary packages..."
232
	if ! pkg upgrade 2>&1 | tee -a ${logfile}; then
233
		_echo "ERROR: An error occurred when upgrade was running..."
234
		exit 1
235
	fi
236

    
237
	_exec "pkg autoremove" "Removing unnecessary packages" mute ignore_result
238
	_exec "pkg clean" "Cleanup pkg cache" mute ignore_result
239

    
240
	# cleanup caches
241

    
242
	rm -f ${upgrade_in_progress}
243
	rm -f ${firmwarelock}
244
}
245

    
246
logfile=/cf/conf/upgrade_log.txt
247

    
248
unset need_reboot
249
if [ ! -f "${upgrade_in_progress}" ]; then
250
	if [ -f "${logfile}" ]; then
251
		rm -f ${logfile}
252
	fi
253

    
254
	first_step
255
	need_reboot=1
256
fi
257

    
258
second_step
259

    
260
if [ -n "${need_reboot}" ]; then
261
	_echo "Rebooting..."
262
	/etc/rc.reboot
263
fi
264

    
265
exit 0
(10-10/20)