VirtualBox

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

Last change on this file since 79804 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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