- # Oracle VM VirtualBox
- # VirtualBox installer shell routines
- #
- # Copyright (C) 2007-2015 Oracle Corporation
- #
- # This file is part of VirtualBox Open Source Edition (OSE), as
- # available from http://www.virtualbox.org. This file is free software;
- # you can redistribute it and/or modify it under the terms of the GNU
- # General Public License (GPL) as published by the Free Software
- # Foundation, in version 2 as it comes in the "COPYING" file of the
- # VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- # hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- #
- ro_LOG_FILE=""
- ro_X11_AUTOSTART="/etc/xdg/autostart"
- ro_KDE_AUTOSTART="/usr/share/autostart"
- ## Aborts the script and prints an error message to stderr.
- #
- # syntax: abort message
- abort()
- {
- echo 1>&2 "$1"
- exit 1
- }
- ## Creates an empty log file and remembers the name for future logging
- # operations
- create_log()
- {
- ## The path of the file to create.
- ro_LOG_FILE="$1"
- if [ "$ro_LOG_FILE" = "" ]; then
- abort "create_log called without an argument! Aborting..."
- fi
- # Create an empty file
- echo > "$ro_LOG_FILE" 2> /dev/null
- if [ ! -f "$ro_LOG_FILE" -o "`cat "$ro_LOG_FILE"`" != "" ]; then
- abort "Error creating log file! Aborting..."
- fi
- }
- ## Writes text to standard error
- #
- # Syntax: info text
- info()
- {
- echo 1>&2 "$1"
- }
- ## Writes text to the log file
- #
- # Syntax: log text
- log()
- {
- if [ "$ro_LOG_FILE" = "" ]; then
- abort "Error! Logging has not been set up yet! Aborting..."
- fi
- echo "$1" >> $ro_LOG_FILE
- return 0
- }
- ## Writes test to standard output and to the log file
- #
- # Syntax: infolog text
- infolog()
- {
- info "$1"
- log "$1"
- }
- ## Checks whether a module is loaded with a given string in its name.
- #
- # syntax: module_loaded string
- module_loaded()
- {
- if [ "$1" = "" ]; then
- log "module_loaded called without an argument. Aborting..."
- abort "Error in installer. Aborting..."
- fi
- lsmod | grep -q $1
- }
- ## Abort if we are not running as root
- check_root()
- {
- if [ `id -u` -ne 0 ]; then
- abort "This program must be run with administrator privileges. Aborting"
- fi
- }
- ## Abort if a copy of VirtualBox is already running
- check_running()
- {
- VBOXSVC_PID=`pidof VBoxSVC 2> /dev/null`
- if [ -n "$VBOXSVC_PID" ]; then
- if [ -f /etc/init.d/vboxweb-service ]; then
- kill -USR1 $VBOXSVC_PID
- fi
- sleep 1
- if pidof VBoxSVC > /dev/null 2>&1; then
- echo 1>&2 "A copy of VirtualBox is currently running. Please close it and try again."
- abort "Please note that it can take up to ten seconds for VirtualBox to finish running."
- fi
- fi
- }
- ## Creates a systemd wrapper in /lib for an LSB init script
- systemd_wrap_init_script()
- {
- self="systemd_wrap_init_script"
- ## The init script to be installed. The file may be copied or referenced.
- script="$(readlink -f -- "${1}")"
- ## Name for the service.
- name="$2"
- test -x "$script" && test ! "$name" = "" || \
- { echo "$self: invalid arguments" >&2 && return 1; }
- test -d /usr/lib/systemd/system && unit_path=/usr/lib/systemd/system
- test -d /lib/systemd/system && unit_path=/lib/systemd/system
- test -n "${unit_path}" || \
- { echo "$self: systemd unit path not found" >&2 && return 1; }
- description=`sed -n 's/# *Short-Description: *\(.*\)/\1/p' "${script}"`
- required=`sed -n 's/# *Required-Start: *\(.*\)/\1/p' "${script}" | sed 's/\$[a-z]*//'`
- runlevels=`sed -n 's/# *Default-Start: *\(.*\)/\1/p' "${script}"`
- before=`for i in ${runlevels}; do printf "runlevel${i}.target "; done`
- after=`for i in ${required}; do printf "${i}.service "; done`
- cat > "${unit_path}/${name}.service" << EOF
- [Unit]
- SourcePath=${script}
- Description=${description}
- Before=${before}shutdown.target
- After=${after}
- Conflicts=shutdown.target
- [Service]
- Type=forking
- Restart=no
- TimeoutSec=5min
- IgnoreSIGPIPE=no
- KillMode=process
- GuessMainPID=no
- RemainAfterExit=yes
- ExecStart=${script} start
- ExecStop=${script} stop
- [Install]
- WantedBy=multi-user.target
- EOF
- systemctl daemon-reexec
- }
- ## Installs a file containing a shell script as an init script
- install_init_script()
- {
- self="install_init_script"
- ## The init script to be installed. The file may be copied or referenced.
- script="$1"
- ## Name for the service.
- name="$2"
- test -x "${script}" && test ! "${name}" = "" ||
- { echo "${self}: invalid arguments" >&2; return 1; }
- # Do not unconditionally silence the following "ln".
- test -L "/sbin/rc${name}" && rm "/sbin/rc${name}"
- ln -s "${script}" "/sbin/rc${name}"
- if test -x "`which systemctl 2>/dev/null`"; then
- if ! test -f /sbin/init || ls -l /sbin/init | grep -q ">.*systemd"; then
- { systemd_wrap_init_script "$script" "$name"; return; }
- fi
- fi
- if test -d /etc/rc.d/init.d; then
- cp "${script}" "/etc/rc.d/init.d/${name}" &&
- chmod 755 "/etc/rc.d/init.d/${name}"
- elif test -d /etc/init.d; then
- cp "${script}" "/etc/init.d/${name}" &&
- chmod 755 "/etc/init.d/${name}"
- else
- { echo "${self}: error: unknown init type" >&2; return 1; }
- fi
- }
- ## Remove the init script "name"
- remove_init_script()
- {
- self="remove_init_script"
- ## Name of the service to remove.
- name="$1"
- test -n "${name}" ||
- { echo "$self: missing argument"; return 1; }
- rm -f "/sbin/rc${name}"
- rm -f /lib/systemd/system/"$name".service /usr/lib/systemd/system/"$name".service
- rm -f "/etc/rc.d/init.d/$name"
- rm -f "/etc/init.d/$name"
- }
- ## Did we install a systemd service?
- systemd_service_installed()
- {
- ## Name of service to test.
- name="${1}"
- test -f /lib/systemd/system/"${name}".service ||
- test -f /usr/lib/systemd/system/"${name}".service
- }
- ## Perform an action on a service
- do_sysvinit_action()
- {
- self="do_sysvinit_action"
- ## Name of service to start.
- name="${1}"
- ## The action to perform, normally "start", "stop" or "status".
- action="${2}"
- test ! -z "${name}" && test ! -z "${action}" ||
- { echo "${self}: missing argument" >&2; return 1; }
- if systemd_service_installed "${name}"; then
- systemctl -q ${action} "${name}"
- elif test -x "`which service 2>/dev/null`"; then
- service "${name}" ${action}
- elif test -x "`which invoke-rc.d 2>/dev/null`"; then
- invoke-rc.d "${name}" ${action}
- elif test -x "/etc/rc.d/init.d/${name}"; then
- "/etc/rc.d/init.d/${name}" "${action}"
- elif test -x "/etc/init.d/${name}"; then
- "/etc/init.d/${name}" "${action}"
- fi
- }
- ## Start a service
- start_init_script()
- {
- do_sysvinit_action "${1}" start
- }
- ## Stop the init script "name"
- stop_init_script()
- {
- do_sysvinit_action "${1}" stop
- }
- ## Extract chkconfig information from a sysvinit script.
- get_chkconfig_info()
- {
- ## The script to extract the information from.
- script="${1}"
- set `sed -n 's/# *chkconfig: *\([0-9]*\) *\(.*\)/\1 \2/p' "${script}"`
- ## Which runlevels should we start in?
- runlevels="${1}"
- ## How soon in the boot process will we start, from 00 (first) to 99
- start_order="${2}"
- ## How soon in the shutdown process will we stop, from 99 (first) to 00
- stop_order="${3}"
- test ! -z "${name}" || \
- { echo "${self}: missing name" >&2; return 1; }
- expr "${start_order}" + 0 > /dev/null 2>&1 && \
- expr 0 \<= "${start_order}" > /dev/null 2>&1 && \
- test `expr length "${start_order}"` -eq 2 > /dev/null 2>&1 || \
- { echo "${self}: start sequence number must be between 00 and 99" >&2;
- return 1; }
- expr "${stop_order}" + 0 > /dev/null 2>&1 && \
- expr 0 \<= "${stop_order}" > /dev/null 2>&1 && \
- test `expr length "${stop_order}"` -eq 2 > /dev/null 2>&1 || \
- { echo "${self}: stop sequence number must be between 00 and 99" >&2;
- return 1; }
- }
- ## Add a service to a runlevel
- addrunlevel()
- {
- self="addrunlevel"
- ## Service name.
- name="${1}"
- test -n "${name}" || \
- { echo "${self}: missing argument" >&2; return 1; }
- systemd_service_installed "${name}" && \
- { systemctl -q enable "${name}"; return; }
- if test -x "/etc/rc.d/init.d/${name}"; then
- init_d_path=/etc/rc.d
- elif test -x "/etc/init.d/${name}"; then
- init_d_path=/etc
- else
- { echo "${self}: error: unknown init type" >&2; return 1; }
- fi
- get_chkconfig_info "${init_d_path}/init.d/${name}" || return 1
- # Redhat based sysvinit systems
- if test -x "`which chkconfig 2>/dev/null`"; then
- chkconfig --add "${name}"
- # SUSE-based sysvinit systems
- elif test -x "`which insserv 2>/dev/null`"; then
- insserv "${name}"
- # Debian/Ubuntu-based systems
- elif test -x "`which update-rc.d 2>/dev/null`"; then
- # Old Debians did not support dependencies
- update-rc.d "${name}" defaults "${start_order}" "${stop_order}"
- # Gentoo Linux
- elif test -x "`which rc-update 2>/dev/null`"; then
- rc-update add "${name}" default
- # Generic sysvinit
- elif test -n "${init_d_path}/rc0.d"
- then
- for locali in 0 1 2 3 4 5 6
- do
- target="${init_d_path}/rc${locali}.d/K${stop_order}${name}"
- expr "${runlevels}" : ".*${locali}" >/dev/null && \
- target="${init_d_path}/rc${locali}.d/S${start_order}${name}"
- test -e "${init_d_path}/rc${locali}.d/"[KS][0-9]*"${name}" || \
- ln -fs "${init_d_path}/init.d/${name}" "${target}"
- done
- else
- { echo "${self}: error: unknown init type" >&2; return 1; }
- fi
- }
- ## Delete a service from a runlevel
- delrunlevel()
- {
- self="delrunlevel"
- ## Service name.
- name="${1}"
- test -n "${name}" ||
- { echo "${self}: missing argument" >&2; return 1; }
- systemctl -q disable "${name}" >/dev/null 2>&1
- # Redhat-based systems
- chkconfig --del "${name}" >/dev/null 2>&1
- # SUSE-based sysvinit systems
- insserv -r "${name}" >/dev/null 2>&1
- # Debian/Ubuntu-based systems
- update-rc.d -f "${name}" remove >/dev/null 2>&1
- # Gentoo Linux
- rc-update del "${name}" >/dev/null 2>&1
- # Generic sysvinit
- rm -f /etc/rc.d/rc?.d/[SK]??"${name}"
- rm -f /etc/rc?.d/[SK]??"${name}"
- }
- terminate_proc() {
- PROC_NAME="${1}"
- SERVER_PID=`pidof $PROC_NAME 2> /dev/null`
- if [ "$SERVER_PID" != "" ]; then
- killall -TERM $PROC_NAME > /dev/null 2>&1
- sleep 2
- fi
- }
- maybe_run_python_bindings_installer() {
- VBOX_INSTALL_PATH="${1}"
- PYTHON=python
- if [ ! `python -c 'print "test"' 2> /dev/null` = "test" ]; then
- echo 1>&2 "Python not available, skipping bindings installation."
- return 1
- fi
- echo 1>&2 "Python found: $PYTHON, installing bindings..."
- # Pass install path via environment
- export VBOX_INSTALL_PATH
- $SHELL -c "cd $VBOX_INSTALL_PATH/sdk/installer && $PYTHON vboxapisetup.py install \
- --record $CONFIG_DIR/python-$CONFIG_FILES"
- cat $CONFIG_DIR/python-$CONFIG_FILES >> $CONFIG_DIR/$CONFIG_FILES
- rm $CONFIG_DIR/python-$CONFIG_FILES
- # remove files created during build
- rm -rf $VBOX_INSTALL_PATH/sdk/installer/build
- return 0
- }