VirtualBox

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

Last change on this file since 56850 was 56850, checked in by vboxsync, 10 years ago

Installers/linux: support systemd.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 12.6 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## Do we have bzip2?
112check_bzip2()
113{
114 if ! ls /bin/bzip2 /usr/bin/bzip2 /usr/local/bin/bzip2 2> /dev/null | grep bzip2 > /dev/null; then
115 echo 1>&2 "Please install the bzip2 utility."
116 log "Please install bzip2."
117 return 1
118 fi
119 return 0
120}
121
122## Do we have GNU make?
123check_gmake()
124{
125make --version 2>&1 | grep GNU > /dev/null
126 if [ ! $? = 0 ]; then
127 echo 1>&2 "Please install GNU make."
128 log "Please install GNU make."
129 return 1
130 fi
131 return 0
132}
133
134## Can we find the kernel source?
135check_ksource()
136{
137 ro_KBUILD_DIR=/lib/modules/`uname -r`/build
138 if [ ! -d $ro_KBUILD_DIR/include ]; then
139 ro_KBUILD_DIR=/usr/src/linux
140 if [ ! -d $ro_KBUILD_DIR/include ]; then
141 echo 1>&2 "Please install the build and header files for your current Linux kernel."
142 echo 1>&2 "The current kernel version is `uname -r`"
143 ro_KBUILD_DIR=""
144 log "Could not find the Linux kernel header files - the directories"
145 log " /lib/modules/`uname -r`/build/include and /usr/src/linux/include"
146 log " do not exist."
147 return 1
148 fi
149 fi
150 return 0
151}
152
153## Is GCC installed?
154check_gcc()
155{
156 ro_gcc_version=`gcc --version 2> /dev/null | head -n 1`
157 if [ "$ro_gcc_version" = "" ]; then
158 echo 1>&2 "Please install the GNU compiler."
159 log "Please install the GNU compiler."
160 return 1
161 fi # GCC installed
162 return 0
163}
164
165## Is bash installed? You never know...
166check_bash()
167{
168 if [ ! -x /bin/bash ]; then
169 echo 1>&2 "Please install GNU bash."
170 log "Please install GNU bash."
171 return 1
172 fi
173 return 0
174}
175
176## Is perl installed?
177check_perl()
178{
179 if [ ! `perl -e 'print "test"' 2> /dev/null` = "test" ]; then
180 echo 1>&2 "Please install perl."
181 echo "Please install perl."
182 return 1
183 fi
184 return 0
185}
186
187## Creates a systemd wrapper in /lib for an LSB init script
188systemd_wrap_init_script()
189{
190 self="systemd_wrap_init_script"
191 ## The init script to be installed. The file may be copied or referenced.
192 script="$(readlink -f -- "${1}")"
193 ## Name for the service.
194 name="$2"
195 test -x "$script" && test ! "$name" = "" || \
196 { log "$self: invalid arguments" && return 1; }
197 test -d /usr/lib/systemd/system && unit_path=/usr/lib/systemd/system
198 test -d /lib/systemd/system && unit_path=/lib/systemd/system
199 test -n "${unit_path}" || \
200 { log "$self: systemd unit path not found" && return 1; }
201 description=`sed -n 's/# *Description: *\(.*\)/\1/p' "${script}"`
202 required=`sed -n 's/# *Required-Start: *\(.*\)/\1/p' "${script}"`
203 runlevels=`sed -n 's/# *Default-Start: *\(.*\)/\1/p' "${script}"`
204 before=`for i in ${runlevels}; do printf "runlevel${i}.target "; done`
205 after=`for i in ${required}; do printf "${i}.service "; done`
206 cat > "${unit_path}/${name}.service" << EOF
207[Unit]
208SourcePath=${script}
209Description=${description}
210Before=${before}shutdown.target
211After=${after}
212Conflicts=shutdown.target
213
214[Service]
215Type=forking
216Restart=no
217TimeoutSec=5min
218IgnoreSIGPIPE=no
219KillMode=process
220GuessMainPID=no
221RemainAfterExit=yes
222ExecStart=${script} start
223ExecStop=${script} stop
224EOF
225}
226
227## Installs a file containing a shell script as an init script
228install_init_script()
229{
230 self="install_init_script"
231 ## The init script to be installed. The file may be copied or referenced.
232 script="$1"
233 ## Name for the service.
234 name="$2"
235 test -x "$script" && test ! "$name" = "" || \
236 { log "$self: invalid arguments" && return 1; }
237 test -d /lib/systemd/system || test -d /usr/lib/systemd/system && systemd_wrap_init_script "$script" "$name"
238 if test -d /etc/rc.d/init.d
239 then
240 cp "$script" "/etc/rc.d/init.d/$name" 2> /dev/null
241 chmod 755 "/etc/rc.d/init.d/$name" 2> /dev/null
242 elif test -d /etc/init.d
243 then
244 cp "$script" "/etc/init.d/$name" 2> /dev/null
245 chmod 755 "/etc/init.d/$name" 2> /dev/null
246 fi
247 return 0
248}
249
250## Remove the init script "name"
251remove_init_script()
252{
253 self="remove_init_script"
254 ## Name of the service to remove.
255 name="$1"
256 test ! "$name" = "" || \
257 { log "$self: missing argument" && return 1; }
258 rm -f /lib/systemd/system/"$name".service /usr/lib/systemd/system/"$name".service
259 if test -d /etc/rc.d/init.d
260 then
261 rm -f "/etc/rc.d/init.d/$name" > /dev/null 2>&1
262 elif test -d /etc/init.d
263 then
264 rm -f "/etc/init.d/$name" > /dev/null 2>&1
265 fi
266 return 0
267}
268
269## Perform an action on a service
270do_sysvinit_action()
271{
272 self="do_sysvinit_action"
273 ## Name of service to start.
274 name="${1}"
275 ## The action to perform, normally "start", "stop" or "status".
276 action="${2}"
277 test ! -z "${name}" && test ! -z "${action}" || \
278 { log "${self}: missing argument" && return 1; }
279 if test -x "`which systemctl 2>/dev/null`"
280 then
281 systemctl ${action} "${name}"
282 elif test -x "`which service 2>/dev/null`"
283 then
284 service "${name}" ${action}
285 elif test -x "`which invoke-rc.d 2>/dev/null`"
286 then
287 invoke-rc.d "${name}" ${action}
288 elif test -x "/etc/rc.d/init.d/${name}"
289 then
290 "/etc/rc.d/init.d/${name}" "${action}"
291 elif test -x "/etc/init.d/${name}"
292 then
293 "/etc/init.d/${name}" "${action}"
294 fi
295}
296
297## Start a service
298start_init_script()
299{
300 do_sysvinit_action "${1}" start
301}
302
303## Stop the init script "name"
304stop_init_script()
305{
306 do_sysvinit_action "${1}" stop
307}
308
309## Extract chkconfig information from a sysvinit script.
310get_chkconfig_info()
311{
312 ## The script to extract the information from.
313 script="${1}"
314 set `sed -n 's/# *chkconfig: *\([0-9]*\) *\(.*\)/\1 \2/p' "${script}"`
315 ## Which runlevels should we start in?
316 runlevels="${1}"
317 ## How soon in the boot process will we start, from 00 (first) to 99
318 start_order="${2}"
319 ## How soon in the shutdown process will we stop, from 99 (first) to 00
320 stop_order="${3}"
321 test ! -z "${name}" || \
322 { log "${self}: missing name" && return 1; }
323 expr "${start_order}" + 0 > /dev/null 2>&1 && \
324 expr 0 \<= "${start_order}" > /dev/null 2>&1 && \
325 test `expr length "${start_order}"` -eq 2 > /dev/null 2>&1 || \
326 { log "${self}: start sequence number must be between 00 and 99" && return 1; }
327 expr "${stop_order}" + 0 > /dev/null 2>&1 && \
328 expr 0 \<= "${stop_order}" > /dev/null 2>&1 && \
329 test `expr length "${stop_order}"` -eq 2 > /dev/null 2>&1 || \
330 { log "${self}: stop sequence number must be between 00 and 99" && return 1; }
331 return 0
332}
333
334## Add a service to a runlevel
335addrunlevel()
336{
337 self="addrunlevel"
338 ## Service name.
339 name="${1}"
340 if test -x "/etc/rc.d/init.d/${name}"
341 then
342 init_d_path=/etc/rc.d
343 elif test -x "/etc/init.d/${name}"
344 then
345 init_d_path=/etc
346 else
347 log "${self}: error: unknown init type or unknown service ${name}"
348 return 1
349 fi
350 get_chkconfig_info "${init_d_path}/init.d/${name}" || return 1
351 # Redhat based sysvinit systems
352 if test -x "`which chkconfig 2>/dev/null`"
353 then
354 chkconfig --add "${name}" || {
355 log "Failed to set up init script ${name}" && return 1
356 }
357 # SUSE-based sysvinit systems
358 elif test -x "`which insserv 2>/dev/null`"
359 then
360 insserv "${name}" > /dev/null
361 # Debian/Ubuntu-based systems
362 elif test -x "`which update-rc.d 2>/dev/null`"
363 then
364 # Old Debians did not support dependencies
365 update-rc.d "${name}" defaults "${start_order}" "${stop_order}" \
366 > /dev/null 2>&1
367 # Gentoo Linux
368 elif test -x "`which rc-update 2>/dev/null`"; then
369 rc-update add "${name}" default > /dev/null 2>&1
370 # Generic sysvinit
371 elif test -n "${init_d_path}/rc0.d"
372 then
373 for locali in 0 1 2 3 4 5 6
374 do
375 target="${init_d_path}/rc${locali}.d/K${stop_order}${name}"
376 expr "${runlevels}" : ".*${locali}" >/dev/null && \
377 target="${init_d_path}/rc${locali}.d/S${start_order}${name}"
378 test -e "${init_d_path}/rc${locali}.d/"[KS][0-9]*"${name}" || \
379 ln -fs "${init_d_path}/init.d/${name}" "${target}" 2> /dev/null
380 done
381 else
382 log "${self}: error: unknown init type"
383 return 1
384 fi
385 return 0
386}
387
388
389## Delete a service from a runlevel
390delrunlevel()
391{
392 self="delrunlevel"
393 ## Service name.
394 name="${1}"
395 test ! -z "${name}" || \
396 { log "${self}: missing argument" && return 1; }
397 # Redhat-based systems
398 if test -x "/sbin/chkconfig"
399 then
400 /sbin/chkconfig --del "${name}" > /dev/null 2>&1
401 # SUSE-based sysvinit systems
402 elif test -x /sbin/insserv
403 then
404 /sbin/insserv -r "${name}" > /dev/null 2>&1
405 # Debian/Ubuntu-based systems
406 elif test -x "`which update-rc.d 2>/dev/null`"
407 then
408 update-rc.d -f "${name}" remove > /dev/null 2>&1
409 # Gentoo Linux
410 elif test -x "`which rc-update 2>/dev/null`"
411 then
412 rc-update del "${name}" > /dev/null 2>&1
413 # Generic sysvinit
414 elif test -d /etc/rc.d/init.d
415 then
416 rm /etc/rc.d/rc?.d/[SK]??"${name}" > /dev/null 2>&1
417 elif test -d /etc/init.d
418 then
419 rm /etc/rc?.d/[SK]??"${name}" > /dev/null 2>&1
420 else
421 log "${self}: error: unknown init type"
422 return 1
423 fi
424 return 0
425}
426
427
428terminate_proc() {
429 PROC_NAME="${1}"
430 SERVER_PID=`pidof $PROC_NAME 2> /dev/null`
431 if [ "$SERVER_PID" != "" ]; then
432 killall -TERM $PROC_NAME > /dev/null 2>&1
433 sleep 2
434 fi
435}
436
437
438maybe_run_python_bindings_installer() {
439 VBOX_INSTALL_PATH="${1}"
440
441 PYTHON=python
442 if [ ! `python -c 'print "test"' 2> /dev/null` = "test" ]; then
443 echo 1>&2 "Python not available, skipping bindings installation."
444 return 1
445 fi
446
447 echo 1>&2 "Python found: $PYTHON, installing bindings..."
448 # Pass install path via environment
449 export VBOX_INSTALL_PATH
450 $SHELL -c "cd $VBOX_INSTALL_PATH/sdk/installer && $PYTHON vboxapisetup.py install"
451 # remove files created during build
452 rm -rf $VBOX_INSTALL_PATH/sdk/installer/build
453
454 return 0
455}
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