VirtualBox

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

Last change on this file since 92601 was 92601, checked in by vboxsync, 3 years ago

Installer/linux: Enable install of python3 API support, if it's version 3.3 or later. bugref:9840

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 12.6 KB
Line 
1# $Id: routines.sh 92601 2021-11-25 19:22:44Z vboxsync $
2# Oracle VM VirtualBox
3# VirtualBox installer shell routines
4#
5
6#
7# Copyright (C) 2007-2020 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 required_target=`sed -n 's/# *X-Required-Target-Start: *\(.*\)/\1/p' "${script}"`
148 startbefore=`sed -n 's/# *X-Start-Before: *\(.*\)/\1/p' "${script}" | sed 's/\$[a-z]*//'`
149 runlevels=`sed -n 's/# *Default-Start: *\(.*\)/\1/p' "${script}"`
150 servicetype=`sed -n 's/# *X-Service-Type: *\(.*\)/\1/p' "${script}"`
151 test -z "${servicetype}" && servicetype="forking"
152 targets=`for i in ${runlevels}; do printf "runlevel${i}.target "; done`
153 before=`for i in ${startbefore}; do printf "${i}.service "; done`
154 after=`for i in ${required_target}; do printf "${i}.target "; done; for i in ${required}; do printf "${i}.service "; done`
155 cat > "${unit_path}/${name}.service" << EOF
156[Unit]
157SourcePath=${script}
158Description=${description}
159Before=${targets}shutdown.target ${before}
160After=${after}
161Conflicts=shutdown.target ${conflicts}
162
163[Service]
164Type=${servicetype}
165Restart=no
166TimeoutSec=5min
167IgnoreSIGPIPE=no
168KillMode=process
169GuessMainPID=no
170RemainAfterExit=yes
171ExecStart=${script} start
172ExecStop=${script} stop
173
174[Install]
175WantedBy=multi-user.target
176EOF
177}
178
179use_systemd()
180{
181 test ! -f /sbin/init || test -L /sbin/init
182}
183
184## Installs a file containing a shell script as an init script. Call
185# finish_init_script_install when all scripts have been installed.
186install_init_script()
187{
188 self="install_init_script"
189 ## The init script to be installed. The file may be copied or referenced.
190 script="$1"
191 ## Name for the service.
192 name="$2"
193
194 test -x "${script}" && test ! "${name}" = "" ||
195 { echo "${self}: invalid arguments" >&2; return 1; }
196 # Do not unconditionally silence the following "ln".
197 test -L "/sbin/rc${name}" && rm "/sbin/rc${name}"
198 ln -s "${script}" "/sbin/rc${name}"
199 if test -x "`which systemctl 2>/dev/null`"; then
200 if use_systemd; then
201 { systemd_wrap_init_script "$script" "$name"; return; }
202 fi
203 fi
204 if test -d /etc/rc.d/init.d; then
205 cp "${script}" "/etc/rc.d/init.d/${name}" &&
206 chmod 755 "/etc/rc.d/init.d/${name}"
207 elif test -d /etc/init.d; then
208 cp "${script}" "/etc/init.d/${name}" &&
209 chmod 755 "/etc/init.d/${name}"
210 else
211 { echo "${self}: error: unknown init type" >&2; return 1; }
212 fi
213}
214
215## Remove the init script "name"
216remove_init_script()
217{
218 self="remove_init_script"
219 ## Name of the service to remove.
220 name="$1"
221
222 test -n "${name}" ||
223 { echo "$self: missing argument"; return 1; }
224 rm -f "/sbin/rc${name}"
225 rm -f /lib/systemd/system/"$name".service /usr/lib/systemd/system/"$name".service
226 rm -f "/etc/rc.d/init.d/$name"
227 rm -f "/etc/init.d/$name"
228}
229
230## Tell systemd services have been installed or removed. Should not be done
231# after each individual one, as systemd can crash if it is done too often
232# (reported by the OL team for OL 7.6, may not apply to other versions.)
233finish_init_script_install()
234{
235 if use_systemd; then
236 systemctl daemon-reload
237 fi
238}
239
240## Did we install a systemd service?
241systemd_service_installed()
242{
243 ## Name of service to test.
244 name="${1}"
245
246 test -f /lib/systemd/system/"${name}".service ||
247 test -f /usr/lib/systemd/system/"${name}".service
248}
249
250## Perform an action on a service
251do_sysvinit_action()
252{
253 self="do_sysvinit_action"
254 ## Name of service to start.
255 name="${1}"
256 ## The action to perform, normally "start", "stop" or "status".
257 action="${2}"
258
259 test ! -z "${name}" && test ! -z "${action}" ||
260 { echo "${self}: missing argument" >&2; return 1; }
261 if systemd_service_installed "${name}"; then
262 systemctl -q ${action} "${name}"
263 elif test -x "/etc/rc.d/init.d/${name}"; then
264 "/etc/rc.d/init.d/${name}" "${action}" quiet
265 elif test -x "/etc/init.d/${name}"; then
266 "/etc/init.d/${name}" "${action}" quiet
267 fi
268}
269
270## Start a service
271start_init_script()
272{
273 do_sysvinit_action "${1}" start
274}
275
276## Stop the init script "name"
277stop_init_script()
278{
279 do_sysvinit_action "${1}" stop
280}
281
282## Extract chkconfig information from a sysvinit script.
283get_chkconfig_info()
284{
285 ## The script to extract the information from.
286 script="${1}"
287
288 set `sed -n 's/# *chkconfig: *\([0-9]*\) *\(.*\)/\1 \2/p' "${script}"`
289 ## Which runlevels should we start in?
290 runlevels="${1}"
291 ## How soon in the boot process will we start, from 00 (first) to 99
292 start_order="${2}"
293 ## How soon in the shutdown process will we stop, from 99 (first) to 00
294 stop_order="${3}"
295 test ! -z "${name}" || \
296 { echo "${self}: missing name" >&2; return 1; }
297 expr "${start_order}" + 0 > /dev/null 2>&1 && \
298 expr 0 \<= "${start_order}" > /dev/null 2>&1 && \
299 test `expr length "${start_order}"` -eq 2 > /dev/null 2>&1 || \
300 { echo "${self}: start sequence number must be between 00 and 99" >&2;
301 return 1; }
302 expr "${stop_order}" + 0 > /dev/null 2>&1 && \
303 expr 0 \<= "${stop_order}" > /dev/null 2>&1 && \
304 test `expr length "${stop_order}"` -eq 2 > /dev/null 2>&1 || \
305 { echo "${self}: stop sequence number must be between 00 and 99" >&2;
306 return 1; }
307}
308
309## Add a service to its default runlevels (annotated inside the script, see get_chkconfig_info).
310addrunlevel()
311{
312 self="addrunlevel"
313 ## Service name.
314 name="${1}"
315
316 test -n "${name}" || \
317 { echo "${self}: missing argument" >&2; return 1; }
318 systemd_service_installed "${name}" && \
319 { systemctl -q enable "${name}"; return; }
320 if test -x "/etc/rc.d/init.d/${name}"; then
321 init_d_path=/etc/rc.d
322 elif test -x "/etc/init.d/${name}"; then
323 init_d_path=/etc
324 else
325 { echo "${self}: error: unknown init type" >&2; return 1; }
326 fi
327 get_chkconfig_info "${init_d_path}/init.d/${name}" || return 1
328 # Redhat based sysvinit systems
329 if test -x "`which chkconfig 2>/dev/null`"; then
330 chkconfig --add "${name}"
331 # SUSE-based sysvinit systems
332 elif test -x "`which insserv 2>/dev/null`"; then
333 insserv "${name}"
334 # Debian/Ubuntu-based systems
335 elif test -x "`which update-rc.d 2>/dev/null`"; then
336 # Old Debians did not support dependencies
337 update-rc.d "${name}" defaults "${start_order}" "${stop_order}"
338 # Gentoo Linux
339 elif test -x "`which rc-update 2>/dev/null`"; then
340 rc-update add "${name}" default
341 # Generic sysvinit
342 elif test -n "${init_d_path}/rc0.d"
343 then
344 for locali in 0 1 2 3 4 5 6
345 do
346 target="${init_d_path}/rc${locali}.d/K${stop_order}${name}"
347 expr "${runlevels}" : ".*${locali}" >/dev/null && \
348 target="${init_d_path}/rc${locali}.d/S${start_order}${name}"
349 test -e "${init_d_path}/rc${locali}.d/"[KS][0-9]*"${name}" || \
350 ln -fs "${init_d_path}/init.d/${name}" "${target}"
351 done
352 else
353 { echo "${self}: error: unknown init type" >&2; return 1; }
354 fi
355}
356
357
358## Delete a service from a runlevel
359delrunlevel()
360{
361 self="delrunlevel"
362 ## Service name.
363 name="${1}"
364
365 test -n "${name}" ||
366 { echo "${self}: missing argument" >&2; return 1; }
367 systemctl -q disable "${name}" >/dev/null 2>&1
368 # Redhat-based systems
369 chkconfig --del "${name}" >/dev/null 2>&1
370 # SUSE-based sysvinit systems
371 insserv -r "${name}" >/dev/null 2>&1
372 # Debian/Ubuntu-based systems
373 update-rc.d -f "${name}" remove >/dev/null 2>&1
374 # Gentoo Linux
375 rc-update del "${name}" >/dev/null 2>&1
376 # Generic sysvinit
377 rm -f /etc/rc.d/rc?.d/[SK]??"${name}"
378 rm -f /etc/rc?.d/[SK]??"${name}"
379}
380
381
382terminate_proc() {
383 PROC_NAME="${1}"
384 SERVER_PID=`pidof $PROC_NAME 2> /dev/null`
385 if [ "$SERVER_PID" != "" ]; then
386 killall -TERM $PROC_NAME > /dev/null 2>&1
387 sleep 2
388 fi
389}
390
391
392maybe_run_python_bindings_installer() {
393 VBOX_INSTALL_PATH="${1}"
394
395 # Check for specific python2 versions only, because python3 is handled
396 # by a generic library which should work with 3.3 and later.
397 PYTHON=""
398 for p in python python2 python2.6 python2.7 python3; do
399 if [ "`$p -c 'import sys
400if sys.version_info >= (2, 6) and (sys.version_info < (3, 0) or sys.version_info >= (3, 3)):
401 print(\"test\")' 2> /dev/null`" = "test" ]; then
402 PYTHON=$p
403 fi
404 done
405 if [ -z "$PYTHON" ]; then
406 echo 1>&2 "Python (2.6, 2.7 or 3.3 and later) unavailable, skipping bindings installation."
407 return 1
408 fi
409
410 echo 1>&2 "Python found: $PYTHON, installing bindings..."
411 # Pass install path via environment
412 export VBOX_INSTALL_PATH
413 $SHELL -c "cd $VBOX_INSTALL_PATH/sdk/installer && $PYTHON vboxapisetup.py install \
414 --record $CONFIG_DIR/python-$CONFIG_FILES"
415 cat $CONFIG_DIR/python-$CONFIG_FILES >> $CONFIG_DIR/$CONFIG_FILES
416 rm $CONFIG_DIR/python-$CONFIG_FILES
417 # remove files created during build
418 rm -rf $VBOX_INSTALL_PATH/sdk/installer/build
419
420 return 0
421}
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