VirtualBox

source: vbox/trunk/src/VBox/Installer/linux/routines.sh@ 66257

Last change on this file since 66257 was 63858, checked in by vboxsync, 8 years ago

bugref:3809: Linux installer maintenance: when we start system V init scripts from within installers, always call them directly rather than through the init system. This lets us pass a quiet parameter so that they do not output init-time information at install time.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1# Oracle VM VirtualBox
2# VirtualBox installer shell routines
3#
4
5# Copyright (C) 2007-2015 Oracle Corporation
6#
7# This file is part of VirtualBox Open Source Edition (OSE), as
8# available from http://www.virtualbox.org. This file is free software;
9# you can redistribute it and/or modify it under the terms of the GNU
10# General Public License (GPL) as published by the Free Software
11# Foundation, in version 2 as it comes in the "COPYING" file of the
12# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14#
15
16ro_LOG_FILE=""
17ro_X11_AUTOSTART="/etc/xdg/autostart"
18ro_KDE_AUTOSTART="/usr/share/autostart"
19
20## Aborts the script and prints an error message to stderr.
21#
22# syntax: abort message
23
24abort()
25{
26 echo 1>&2 "$1"
27 exit 1
28}
29
30## Creates an empty log file and remembers the name for future logging
31# operations
32create_log()
33{
34 ## The path of the file to create.
35 ro_LOG_FILE="$1"
36 if [ "$ro_LOG_FILE" = "" ]; then
37 abort "create_log called without an argument! Aborting..."
38 fi
39 # Create an empty file
40 echo > "$ro_LOG_FILE" 2> /dev/null
41 if [ ! -f "$ro_LOG_FILE" -o "`cat "$ro_LOG_FILE"`" != "" ]; then
42 abort "Error creating log file! Aborting..."
43 fi
44}
45
46## Writes text to standard error
47#
48# Syntax: info text
49info()
50{
51 echo 1>&2 "$1"
52}
53
54## Writes text to the log file
55#
56# Syntax: log text
57log()
58{
59 if [ "$ro_LOG_FILE" = "" ]; then
60 abort "Error! Logging has not been set up yet! Aborting..."
61 fi
62 echo "$1" >> $ro_LOG_FILE
63 return 0
64}
65
66## Writes test to standard output and to the log file
67#
68# Syntax: infolog text
69infolog()
70{
71 info "$1"
72 log "$1"
73}
74
75## Checks whether a module is loaded with a given string in its name.
76#
77# syntax: module_loaded string
78module_loaded()
79{
80 if [ "$1" = "" ]; then
81 log "module_loaded called without an argument. Aborting..."
82 abort "Error in installer. Aborting..."
83 fi
84 lsmod | grep -q $1
85}
86
87## Abort if we are not running as root
88check_root()
89{
90 if [ `id -u` -ne 0 ]; then
91 abort "This program must be run with administrator privileges. Aborting"
92 fi
93}
94
95## Abort if a copy of VirtualBox is already running
96check_running()
97{
98 VBOXSVC_PID=`pidof VBoxSVC 2> /dev/null`
99 if [ -n "$VBOXSVC_PID" ]; then
100 if [ -f /etc/init.d/vboxweb-service ]; then
101 kill -USR1 $VBOXSVC_PID
102 fi
103 sleep 1
104 if pidof VBoxSVC > /dev/null 2>&1; then
105 echo 1>&2 "A copy of VirtualBox is currently running. Please close it and try again."
106 abort "Please note that it can take up to ten seconds for VirtualBox to finish running."
107 fi
108 fi
109}
110
111## Creates a systemd wrapper in /lib for an LSB init script
112systemd_wrap_init_script()
113{
114 self="systemd_wrap_init_script"
115 ## The init script to be installed. The file may be copied or referenced.
116 script="$(readlink -f -- "${1}")"
117 ## Name for the service.
118 name="$2"
119 test -x "$script" && test ! "$name" = "" || \
120 { echo "$self: invalid arguments" >&2 && return 1; }
121 test -d /usr/lib/systemd/system && unit_path=/usr/lib/systemd/system
122 test -d /lib/systemd/system && unit_path=/lib/systemd/system
123 test -n "${unit_path}" || \
124 { echo "$self: systemd unit path not found" >&2 && return 1; }
125 description=`sed -n 's/# *Short-Description: *\(.*\)/\1/p' "${script}"`
126 required=`sed -n 's/# *Required-Start: *\(.*\)/\1/p' "${script}" | sed 's/\$[a-z]*//'`
127 runlevels=`sed -n 's/# *Default-Start: *\(.*\)/\1/p' "${script}"`
128 before=`for i in ${runlevels}; do printf "runlevel${i}.target "; done`
129 after=`for i in ${required}; do printf "${i}.service "; done`
130 cat > "${unit_path}/${name}.service" << EOF
131[Unit]
132SourcePath=${script}
133Description=${description}
134Before=${before}shutdown.target
135After=${after}
136Conflicts=shutdown.target
137
138[Service]
139Type=forking
140Restart=no
141TimeoutSec=5min
142IgnoreSIGPIPE=no
143KillMode=process
144GuessMainPID=no
145RemainAfterExit=yes
146ExecStart=${script} start
147ExecStop=${script} stop
148
149[Install]
150WantedBy=multi-user.target
151EOF
152 systemctl daemon-reexec
153}
154
155## Installs a file containing a shell script as an init script
156install_init_script()
157{
158 self="install_init_script"
159 ## The init script to be installed. The file may be copied or referenced.
160 script="$1"
161 ## Name for the service.
162 name="$2"
163
164 test -x "${script}" && test ! "${name}" = "" ||
165 { echo "${self}: invalid arguments" >&2; return 1; }
166 # Do not unconditionally silence the following "ln".
167 test -L "/sbin/rc${name}" && rm "/sbin/rc${name}"
168 ln -s "${script}" "/sbin/rc${name}"
169 if test -x "`which systemctl 2>/dev/null`"; then
170 if ! test -f /sbin/init || ls -l /sbin/init | grep -q ">.*systemd"; then
171 { systemd_wrap_init_script "$script" "$name"; return; }
172 fi
173 fi
174 if test -d /etc/rc.d/init.d; then
175 cp "${script}" "/etc/rc.d/init.d/${name}" &&
176 chmod 755 "/etc/rc.d/init.d/${name}"
177 elif test -d /etc/init.d; then
178 cp "${script}" "/etc/init.d/${name}" &&
179 chmod 755 "/etc/init.d/${name}"
180 else
181 { echo "${self}: error: unknown init type" >&2; return 1; }
182 fi
183}
184
185## Remove the init script "name"
186remove_init_script()
187{
188 self="remove_init_script"
189 ## Name of the service to remove.
190 name="$1"
191
192 test -n "${name}" ||
193 { echo "$self: missing argument"; return 1; }
194 rm -f "/sbin/rc${name}"
195 rm -f /lib/systemd/system/"$name".service /usr/lib/systemd/system/"$name".service
196 rm -f "/etc/rc.d/init.d/$name"
197 rm -f "/etc/init.d/$name"
198}
199
200## Did we install a systemd service?
201systemd_service_installed()
202{
203 ## Name of service to test.
204 name="${1}"
205
206 test -f /lib/systemd/system/"${name}".service ||
207 test -f /usr/lib/systemd/system/"${name}".service
208}
209
210## Perform an action on a service
211do_sysvinit_action()
212{
213 self="do_sysvinit_action"
214 ## Name of service to start.
215 name="${1}"
216 ## The action to perform, normally "start", "stop" or "status".
217 action="${2}"
218
219 test ! -z "${name}" && test ! -z "${action}" ||
220 { echo "${self}: missing argument" >&2; return 1; }
221 if systemd_service_installed "${name}"; then
222 systemctl -q ${action} "${name}"
223 elif test -x "/etc/rc.d/init.d/${name}"; then
224 "/etc/rc.d/init.d/${name}" "${action}" quiet
225 elif test -x "/etc/init.d/${name}"; then
226 "/etc/init.d/${name}" "${action}" quiet
227 fi
228}
229
230## Start a service
231start_init_script()
232{
233 do_sysvinit_action "${1}" start
234}
235
236## Stop the init script "name"
237stop_init_script()
238{
239 do_sysvinit_action "${1}" stop
240}
241
242## Extract chkconfig information from a sysvinit script.
243get_chkconfig_info()
244{
245 ## The script to extract the information from.
246 script="${1}"
247
248 set `sed -n 's/# *chkconfig: *\([0-9]*\) *\(.*\)/\1 \2/p' "${script}"`
249 ## Which runlevels should we start in?
250 runlevels="${1}"
251 ## How soon in the boot process will we start, from 00 (first) to 99
252 start_order="${2}"
253 ## How soon in the shutdown process will we stop, from 99 (first) to 00
254 stop_order="${3}"
255 test ! -z "${name}" || \
256 { echo "${self}: missing name" >&2; return 1; }
257 expr "${start_order}" + 0 > /dev/null 2>&1 && \
258 expr 0 \<= "${start_order}" > /dev/null 2>&1 && \
259 test `expr length "${start_order}"` -eq 2 > /dev/null 2>&1 || \
260 { echo "${self}: start sequence number must be between 00 and 99" >&2;
261 return 1; }
262 expr "${stop_order}" + 0 > /dev/null 2>&1 && \
263 expr 0 \<= "${stop_order}" > /dev/null 2>&1 && \
264 test `expr length "${stop_order}"` -eq 2 > /dev/null 2>&1 || \
265 { echo "${self}: stop sequence number must be between 00 and 99" >&2;
266 return 1; }
267}
268
269## Add a service to a runlevel
270addrunlevel()
271{
272 self="addrunlevel"
273 ## Service name.
274 name="${1}"
275
276 test -n "${name}" || \
277 { echo "${self}: missing argument" >&2; return 1; }
278 systemd_service_installed "${name}" && \
279 { systemctl -q enable "${name}"; return; }
280 if test -x "/etc/rc.d/init.d/${name}"; then
281 init_d_path=/etc/rc.d
282 elif test -x "/etc/init.d/${name}"; then
283 init_d_path=/etc
284 else
285 { echo "${self}: error: unknown init type" >&2; return 1; }
286 fi
287 get_chkconfig_info "${init_d_path}/init.d/${name}" || return 1
288 # Redhat based sysvinit systems
289 if test -x "`which chkconfig 2>/dev/null`"; then
290 chkconfig --add "${name}"
291 # SUSE-based sysvinit systems
292 elif test -x "`which insserv 2>/dev/null`"; then
293 insserv "${name}"
294 # Debian/Ubuntu-based systems
295 elif test -x "`which update-rc.d 2>/dev/null`"; then
296 # Old Debians did not support dependencies
297 update-rc.d "${name}" defaults "${start_order}" "${stop_order}"
298 # Gentoo Linux
299 elif test -x "`which rc-update 2>/dev/null`"; then
300 rc-update add "${name}" default
301 # Generic sysvinit
302 elif test -n "${init_d_path}/rc0.d"
303 then
304 for locali in 0 1 2 3 4 5 6
305 do
306 target="${init_d_path}/rc${locali}.d/K${stop_order}${name}"
307 expr "${runlevels}" : ".*${locali}" >/dev/null && \
308 target="${init_d_path}/rc${locali}.d/S${start_order}${name}"
309 test -e "${init_d_path}/rc${locali}.d/"[KS][0-9]*"${name}" || \
310 ln -fs "${init_d_path}/init.d/${name}" "${target}"
311 done
312 else
313 { echo "${self}: error: unknown init type" >&2; return 1; }
314 fi
315}
316
317
318## Delete a service from a runlevel
319delrunlevel()
320{
321 self="delrunlevel"
322 ## Service name.
323 name="${1}"
324
325 test -n "${name}" ||
326 { echo "${self}: missing argument" >&2; return 1; }
327 systemctl -q disable "${name}" >/dev/null 2>&1
328 # Redhat-based systems
329 chkconfig --del "${name}" >/dev/null 2>&1
330 # SUSE-based sysvinit systems
331 insserv -r "${name}" >/dev/null 2>&1
332 # Debian/Ubuntu-based systems
333 update-rc.d -f "${name}" remove >/dev/null 2>&1
334 # Gentoo Linux
335 rc-update del "${name}" >/dev/null 2>&1
336 # Generic sysvinit
337 rm -f /etc/rc.d/rc?.d/[SK]??"${name}"
338 rm -f /etc/rc?.d/[SK]??"${name}"
339}
340
341
342terminate_proc() {
343 PROC_NAME="${1}"
344 SERVER_PID=`pidof $PROC_NAME 2> /dev/null`
345 if [ "$SERVER_PID" != "" ]; then
346 killall -TERM $PROC_NAME > /dev/null 2>&1
347 sleep 2
348 fi
349}
350
351
352maybe_run_python_bindings_installer() {
353 VBOX_INSTALL_PATH="${1}"
354
355 PYTHON=python
356 if [ "`python -c 'import sys
357if sys.version_info >= (2, 6):
358 print \"test\"' 2> /dev/null`" != "test" ]; then
359 echo 1>&2 "Python 2.6 or later not available, skipping bindings installation."
360 return 1
361 fi
362
363 echo 1>&2 "Python found: $PYTHON, installing bindings..."
364 # Pass install path via environment
365 export VBOX_INSTALL_PATH
366 $SHELL -c "cd $VBOX_INSTALL_PATH/sdk/installer && $PYTHON vboxapisetup.py install \
367 --record $CONFIG_DIR/python-$CONFIG_FILES"
368 cat $CONFIG_DIR/python-$CONFIG_FILES >> $CONFIG_DIR/$CONFIG_FILES
369 rm $CONFIG_DIR/python-$CONFIG_FILES
370 # remove files created during build
371 rm -rf $VBOX_INSTALL_PATH/sdk/installer/build
372
373 return 0
374}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette