VirtualBox

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

Last change on this file since 57585 was 56859, checked in by vboxsync, 9 years ago

Installers/linux: make systemd without sysvinit work.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 13.0 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
224
225[Install]
226WantedBy=multi-user.target
227EOF
228}
229
230## Installs a file containing a shell script as an init script
231install_init_script()
232{
233 self="install_init_script"
234 ## The init script to be installed. The file may be copied or referenced.
235 script="$1"
236 ## Name for the service.
237 name="$2"
238 test -x "$script" && test ! "$name" = "" || \
239 { log "$self: invalid arguments" && return 1; }
240 test -d /lib/systemd/system || test -d /usr/lib/systemd/system && systemd_wrap_init_script "$script" "$name"
241 if test -d /etc/rc.d/init.d
242 then
243 cp "$script" "/etc/rc.d/init.d/$name" 2> /dev/null
244 chmod 755 "/etc/rc.d/init.d/$name" 2> /dev/null
245 elif test -d /etc/init.d
246 then
247 cp "$script" "/etc/init.d/$name" 2> /dev/null
248 chmod 755 "/etc/init.d/$name" 2> /dev/null
249 fi
250 return 0
251}
252
253## Remove the init script "name"
254remove_init_script()
255{
256 self="remove_init_script"
257 ## Name of the service to remove.
258 name="$1"
259 test ! "$name" = "" || \
260 { log "$self: missing argument" && return 1; }
261 rm -f /lib/systemd/system/"$name".service /usr/lib/systemd/system/"$name".service
262 if test -d /etc/rc.d/init.d
263 then
264 rm -f "/etc/rc.d/init.d/$name" > /dev/null 2>&1
265 elif test -d /etc/init.d
266 then
267 rm -f "/etc/init.d/$name" > /dev/null 2>&1
268 fi
269 return 0
270}
271
272## Perform an action on a service
273do_sysvinit_action()
274{
275 self="do_sysvinit_action"
276 ## Name of service to start.
277 name="${1}"
278 ## The action to perform, normally "start", "stop" or "status".
279 action="${2}"
280 test ! -z "${name}" && test ! -z "${action}" || \
281 { log "${self}: missing argument" && return 1; }
282 if test -x "`which systemctl 2>/dev/null`"
283 then
284 systemctl ${action} "${name}"
285 elif test -x "`which service 2>/dev/null`"
286 then
287 service "${name}" ${action}
288 elif test -x "`which invoke-rc.d 2>/dev/null`"
289 then
290 invoke-rc.d "${name}" ${action}
291 elif test -x "/etc/rc.d/init.d/${name}"
292 then
293 "/etc/rc.d/init.d/${name}" "${action}"
294 elif test -x "/etc/init.d/${name}"
295 then
296 "/etc/init.d/${name}" "${action}"
297 fi
298}
299
300## Start a service
301start_init_script()
302{
303 do_sysvinit_action "${1}" start
304}
305
306## Stop the init script "name"
307stop_init_script()
308{
309 do_sysvinit_action "${1}" stop
310}
311
312## Extract chkconfig information from a sysvinit script.
313get_chkconfig_info()
314{
315 ## The script to extract the information from.
316 script="${1}"
317 set `sed -n 's/# *chkconfig: *\([0-9]*\) *\(.*\)/\1 \2/p' "${script}"`
318 ## Which runlevels should we start in?
319 runlevels="${1}"
320 ## How soon in the boot process will we start, from 00 (first) to 99
321 start_order="${2}"
322 ## How soon in the shutdown process will we stop, from 99 (first) to 00
323 stop_order="${3}"
324 test ! -z "${name}" || \
325 { log "${self}: missing name" && return 1; }
326 expr "${start_order}" + 0 > /dev/null 2>&1 && \
327 expr 0 \<= "${start_order}" > /dev/null 2>&1 && \
328 test `expr length "${start_order}"` -eq 2 > /dev/null 2>&1 || \
329 { log "${self}: start sequence number must be between 00 and 99" && return 1; }
330 expr "${stop_order}" + 0 > /dev/null 2>&1 && \
331 expr 0 \<= "${stop_order}" > /dev/null 2>&1 && \
332 test `expr length "${stop_order}"` -eq 2 > /dev/null 2>&1 || \
333 { log "${self}: stop sequence number must be between 00 and 99" && return 1; }
334 return 0
335}
336
337## Add a service to a runlevel
338addrunlevel()
339{
340 self="addrunlevel"
341 ## Service name.
342 name="${1}"
343 test -n "${name}" || \
344 { log "${self}: missing argument" && return 1; }
345 test -x "`which systemctl 2>/dev/null`" && \
346 { systemctl enable "${name}"; return; }
347 if test -x "/etc/rc.d/init.d/${name}"
348 then
349 init_d_path=/etc/rc.d
350 elif test -x "/etc/init.d/${name}"
351 then
352 init_d_path=/etc
353 else
354 log "${self}: error: unknown init type or unknown service ${name}"
355 return 1
356 fi
357 get_chkconfig_info "${init_d_path}/init.d/${name}" || return 1
358 # Redhat based sysvinit systems
359 if test -x "`which chkconfig 2>/dev/null`"
360 then
361 chkconfig --add "${name}" || {
362 log "Failed to set up init script ${name}" && return 1
363 }
364 # SUSE-based sysvinit systems
365 elif test -x "`which insserv 2>/dev/null`"
366 then
367 insserv "${name}" > /dev/null
368 # Debian/Ubuntu-based systems
369 elif test -x "`which update-rc.d 2>/dev/null`"
370 then
371 # Old Debians did not support dependencies
372 update-rc.d "${name}" defaults "${start_order}" "${stop_order}" \
373 > /dev/null 2>&1
374 # Gentoo Linux
375 elif test -x "`which rc-update 2>/dev/null`"; then
376 rc-update add "${name}" default > /dev/null 2>&1
377 # Generic sysvinit
378 elif test -n "${init_d_path}/rc0.d"
379 then
380 for locali in 0 1 2 3 4 5 6
381 do
382 target="${init_d_path}/rc${locali}.d/K${stop_order}${name}"
383 expr "${runlevels}" : ".*${locali}" >/dev/null && \
384 target="${init_d_path}/rc${locali}.d/S${start_order}${name}"
385 test -e "${init_d_path}/rc${locali}.d/"[KS][0-9]*"${name}" || \
386 ln -fs "${init_d_path}/init.d/${name}" "${target}" 2> /dev/null
387 done
388 else
389 log "${self}: error: unknown init type"
390 return 1
391 fi
392 return 0
393}
394
395
396## Delete a service from a runlevel
397delrunlevel()
398{
399 self="delrunlevel"
400 ## Service name.
401 name="${1}"
402 test -n "${name}" || \
403 { log "${self}: missing argument" && return 1; }
404 if test -x "`which systemctl 2>/dev/null`"
405 then
406 systemctl disable "${name}"
407 # Redhat-based systems
408 elif test -x "/sbin/chkconfig"
409 then
410 /sbin/chkconfig --del "${name}" > /dev/null 2>&1
411 # SUSE-based sysvinit systems
412 elif test -x /sbin/insserv
413 then
414 /sbin/insserv -r "${name}" > /dev/null 2>&1
415 # Debian/Ubuntu-based systems
416 elif test -x "`which update-rc.d 2>/dev/null`"
417 then
418 update-rc.d -f "${name}" remove > /dev/null 2>&1
419 # Gentoo Linux
420 elif test -x "`which rc-update 2>/dev/null`"
421 then
422 rc-update del "${name}" > /dev/null 2>&1
423 # Generic sysvinit
424 elif test -d /etc/rc.d/init.d
425 then
426 rm /etc/rc.d/rc?.d/[SK]??"${name}" > /dev/null 2>&1
427 elif test -d /etc/init.d
428 then
429 rm /etc/rc?.d/[SK]??"${name}" > /dev/null 2>&1
430 else
431 log "${self}: error: unknown init type"
432 return 1
433 fi
434 return 0
435}
436
437
438terminate_proc() {
439 PROC_NAME="${1}"
440 SERVER_PID=`pidof $PROC_NAME 2> /dev/null`
441 if [ "$SERVER_PID" != "" ]; then
442 killall -TERM $PROC_NAME > /dev/null 2>&1
443 sleep 2
444 fi
445}
446
447
448maybe_run_python_bindings_installer() {
449 VBOX_INSTALL_PATH="${1}"
450
451 PYTHON=python
452 if [ ! `python -c 'print "test"' 2> /dev/null` = "test" ]; then
453 echo 1>&2 "Python not available, skipping bindings installation."
454 return 1
455 fi
456
457 echo 1>&2 "Python found: $PYTHON, installing bindings..."
458 # Pass install path via environment
459 export VBOX_INSTALL_PATH
460 $SHELL -c "cd $VBOX_INSTALL_PATH/sdk/installer && $PYTHON vboxapisetup.py install"
461 # remove files created during build
462 rm -rf $VBOX_INSTALL_PATH/sdk/installer/build
463
464 return 0
465}
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