how to find VBox version from within guest

Discussions about using Linux guests in VirtualBox.
Post Reply
krthie
Posts: 13
Joined: 22. Aug 2011, 13:37
Primary OS: MS Windows XP
VBox Version: OSE other
Guest OSses: ubuntu

how to find VBox version from within guest

Post by krthie »

we'd like to be able to check the VBox version from in the Ubuntu guest, to check/warn the user if their VGA are out-of-date, or to auto-install the appropriate VGA. I know that once the VGA are installed, we get a warning in the GUI if they are out-of-date, so we want to do the same but from the command line.

we tried to use dmidecode but that actually returns the VGA version, not the VirtualBox version installed on the host (see https://github.com/CCPPETMR/CCPPETMR_VM/issues/30).

Any help would be appreciated.
JEBjames
Posts: 58
Joined: 26. Jan 2017, 18:27
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: Centos, Ubuntu, Debian, Various Windows
Contact:

Re: how to find VBox version from within guest

Post by JEBjames »

I have a script that does what you are talking about. Here are some snippets:

E.g. in a #!/bin/sh script you could add these routines:

note you must set $WEBSERVER to your webserver url that hosts all the iso's in the same dir.

Code: Select all

# Make sure only root can run our script
force_root() {
	if [ "$(id -u)" != "0" ]; then
		echo "${LRED}Error: insufficient permissions${LGRAY}"
		echo "Make sure you run this script with: sudo $0"
		exit 1
	fi
}

# -- color codes
setup_color_codes() {
	LRED='\033[1;31m'
	LGREEN='\033[1;32m'
	LGRAY='\033[0;37m'
}

# $1 = sha256 string to validate
# Note: sha256 strings must have lowercase hexidecimal characters.
validate_sha256_string() {
    if ! echo "$1" | grep -P -o -q '^[0-9a-f]{64}$' ; then
        echo "invalid SHA256 sum: $1"
        exit 1
    fi
}

# $1 = sha256sum
# $2 = filename
# $3 = "CONTINUE" if you want to continue if checksum doesn't match.
# sha256 check the file.  Deletes the file if it's invalid.
sha256_check_file() {
    validate_sha256_string "$1"

    if [ "$2" = "" ]; then
        echo "sha256_check_file: missing parameter #2, filename"
        exit 1
    else
        if [ ! -f "$2" ]; then
            echo "sha256_check_file: missing file $2"
            exit 1
        fi
    fi

    # validate the file
    printf "sha256sum checking file %s: ..." "$2"
    if ! echo "$1 $2" | sha256sum -c - ; then
        rm -f "$2"
        if [ "$3" = "CONTINUE" ]; then
            echo "${LRED}Bad sha256 checksum (expecting $1) ${LGRAY}"
            return 1
        else
            echo "${LRED}Bad sha256 checksum (expecting $1) ${LGRAY}"
            exit 1
        fi
    else
        echo "checksum matches."
        return 0
    fi
}

# --- download from web 
# $1 = url
# $2 = local file
# $3 = SHA256 checksum or "SKIP" to bypass check
# $4 = optional parameter.  Can be empty or "follow" to follow urls on 304 redirects
fetch_file() {
    if [ -z "$1" ]; then
        echo "fetch_file: ${LRED}Missing parameter #1, url${LGRAY}"
        exit 1
    fi

    if [ -z "$2" ]; then
        echo "fetch_file: ${LRED}Missing parameter #2, local file (url: $1)${LGRAY}"
        exit 1
    fi

    if [ -z "$3" ]; then
        echo "fetch_file: ${LRED}Missing parameter #3, SHA256$ (url: $1 and file: $2)${LGRAY}"
        exit 1
    fi

    if [ ! "$4" = "" ] && [ ! "$4" = "FOLLOW" ]; then
        echo "fetch_file: ${LRED}Invalid parameter #4, must be empty or \"follow\"${LGRAY}"
        exit 1
    fi

    FOLLOW_PARAM=""
    if [ "$4" = "FOLLOW" ]; then
        FOLLOW_PARAM="--location"
    fi
 
    # sha256 check the file if it [center][/center]exists
    if [ -f "$2" ] && [ ! "$3" = "SKIP" ]; then
        if sha256_check_file "$3" "$2" "CONTINUE" ; then
            echo "SHA256 for file $2 matches, download skipped"
            return 0
        fi
    fi

    # using -u so we get the name, but don't create the file
    TMP_DL="$(mktemp -u "$2".XXXXXXXXXX)"

    # download file if we don't already have it or server version is newer
    if [ -f "$2" ]; then
        # If no sha256...preserve existing "if changed" download behavior
        # this works around the -z -o quirk of it always downloading if the -o target file exists
        /usr/bin/curl $FOLLOW_PARAM "$1" -z "$2" -o "$TMP_DL"
    else
        # download missing file
        # or file if we know it's SHA256 has changed
        /usr/bin/curl $FOLLOW_PARAM "$1" -o "$TMP_DL"
    fi

    # shellcheck disable=SC2181
    # SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
    if [ ! $? -eq 0 ]; then
        rm -f "$TMP_DL"
        exit 1
    fi

    if [ -f "$TMP_DL" ]; then
        # fix permissions
        chmod u+rw "$TMP_DL"
        chown "$SLIDEUSER:$SLIDEUSER" "$TMP_DL"

        # sha256 check the file, will delete it if it's invalid
        if [ ! "$3" = "SKIP" ]; then
            if ! sha256_check_file "$3" "$TMP_DL" "CONTINUE" ; then
                rm -f "$TMP_DL"
                exit 1
            fi
        fi

        # replace original with new download
        mv -f "$TMP_DL" "$2"
    fi

    return 0
}




# return 0 if running in virtualbox, otherwise 1
detect_virtualbox_guest() {
    if [ "$(dmidecode | grep -i product | grep VirtualBox)" = "" ]; then
        return 1
    else
        return 0
    fi
}

# returns 0 if virtualbox guest additions are up to date, otherwise 1
virtualbox_guest_up_to_date() {
    # do nothing if not running under virtualbox
    detect_virtualbox_guest || return 0

    if [ ! "$(lsmod | grep vbox)" = "" ]; then
        echo "Guest drivers found"
        if [ ! "$(modinfo vboxguest | grep version | grep -i ubuntu)" = "" ]; then
            echo "Ubuntu specific drivers found"
            return 1
        else
            vbox_module_ver=$(modinfo vboxguest | grep version | grep -E -o '[[:digit:]\.]+' | head -n 1)
            VBOX_VER=$(dmidecode | grep -i vboxver | grep -E -o '[[:digit:]\.]+' | tail -n 1)

            # work around for 5.2.6 and 5.2.7 guest additions
            if [ "$VBOX_VER" = "5.2.6" ] && [ "$vbox_module_ver" = "5.2.7" ]; then
                echo "5.2.6 with 5.2.7 guest additions found"
                return 0
            fi

            if [ "$VBOX_VER" != "$vbox_module_ver" ]; then
                echo "Old guest additions"
                return 1
            else
                echo "Guest additions are up to date"
                return 0
            fi
        fi
    else
        echo "Guest additions not detected"
    fi
}

# Install or upgrade VirtualBox Guest Drivers
# set your $WEBSERVER variable correctly first!
virtualbox_guest_driver_install() {
    # do nothing if not running under virtualbox
    if ! detect_virtualbox_guest ; then
        echo "Not running under VirtualBox"
        return 0
    fi

    echo "Running under VirtualBox"

    if virtualbox_guest_up_to_date ; then
        return 0
    fi

    # install prerequisites
    if [ "$OS_FAMILY" = "debian" ]; then
        apt_cmd install -y build-essential module-assistant dkms
        install dkms
        m-a prepare
    else
        if [ "$OS_FAMILY" = "redhat" ]; then
            yum install dkms gcc kernel-devel
        else
            echo "virtualbox_guest_setup: only debian/ubuntu/centos/redhat tested!"
            exit 1
        fi
    fi;

    VBOX_VER=$(dmidecode | grep -i vboxver | grep -E -o '[[:digit:]\.]+' | tail -n 1)

    URL="$WEBSERVER/VBoxGuestAdditions_${VBOX_VER}.iso"

    case "$VBOX_VER" in
        "5.1.26")
            SHA256="6df8c8ab6e7ac3a70a5e29116f8a5dcdb7dfbd0b226ef849a5cd9502e956b06f"
            ;;
        "5.1.28")
            SHA256="66824ee3a0373da62b15f6687a68e2305d7e62d700e538cf32705227bb38c46d"
            ;;
        "5.1.30")
            SHA256="631ca8e8d513acf43a75de56a71a31aaffb5624864c57d10346ba657d991ec1e"
            ;;
        "5.2.4")
            SHA256="60da4bb2d522632f6ac82377354cb03a9ff25c36d6a881d3158d22c2b6c91a62"
            ;;
        "5.2.6")
            # really: 5.2.7-120326
            SHA256="f688fd4b489b9f99fa15b94e172e9581fce7f41187f1d0fe139f5e9d7bf42466"
            ;;
        *)
            echo "virtualbox_guest_setup: Unsupported version of virtualbox: $VBOX_VER"
            exit 1
            ;;
    esac

    LOCALFILE="/home/$SLIDEUSER/VBoxGuestAdditions_${VBOX_VER}.iso"

    fetch_file "$URL" "$LOCALFILE" "$SHA256"

    mkdir -p /root/tmpcd
    mount -o loop,ro "VBoxGuestAdditions_${VBOX_VER}.iso" /root/tmpcd

    oldpath=$(pwd)

    cd /root/tmpcd || exit 1
    ./VBoxLinuxAdditions.run

    cd "$oldpath" || exit 1

    umount /root/tmpcd
    rm "$LOCALFILE"

    auto_reboot
}

# do everything magically
setup_color_codes
force_root
WEBSERVER="http:/yourservergoeshere/guestadditiondirgoeshere/"
virtualbox_guest_driver_install

Last edited by JEBjames on 30. Jan 2018, 23:46, edited 1 time in total.
socratis
Site Moderator
Posts: 27329
Joined: 22. Oct 2010, 11:03
Primary OS: Mac OS X other
VBox Version: PUEL
Guest OSses: Win(*>98), Linux*, OSX>10.5
Location: Greece

Re: how to find VBox version from within guest

Post by socratis »

@JEBjames
This is really nice! :)
JEBjames wrote:Here are some snippets
What do you mean? There's more?

Can I make a couple of suggestions?
  • You can't access 'dmidecode' as a user, you got to be root. Could you incorporate that? Or a warning?
  • DKMS is no longer required, it's not a prerequisite.
  • Instead of statically embedding the SHA256 checksum, could you download the checksum from the appropriate "SHA256SUMS" link? For example https://www.virtualbox.org/download/hashes/5.2.6/SHA256SUMS?
  • You could default the 'WEBSERVER' to https://download.virtualbox.org/virtualbox/ (and note that the "s" in https is finally working... ;) ) with the option to be defined in the command line if needed.
Do NOT send me Personal Messages (PMs) for troubleshooting, they are simply deleted.
Do NOT reply with the "QUOTE" button, please use the "POST REPLY", at the bottom of the form.
If you obfuscate any information requested, I will obfuscate my response. These are virtual UUIDs, not real ones.
JEBjames
Posts: 58
Joined: 26. Jan 2017, 18:27
Primary OS: MS Windows other
VBox Version: OSE other
Guest OSses: Centos, Ubuntu, Debian, Various Windows
Contact:

Re: how to find VBox version from within guest

Post by JEBjames »

Thanks for the feedback Socratis,

You are right about checking for root. I forgot to include that part, I updated the post to include it.

Thanks for letting me know about the DKMS. I thought it was still needed for Centos. I'll give that a test and remove that part. :)

It's part of a larger set of tools. I can't release it all.

I agree for many people, downloading directly from the virtualbox site makes sense. Just for various reasons, this isn't the best option for me. If someone else wants to do those tweaks they are free to do so. :D
slycordinator
Posts: 8
Joined: 17. Sep 2007, 19:58

Re: how to find VBox version from within guest

Post by slycordinator »

By the way, instead of storing all the iso files you want on a random webserver, you could simply have it download directly from virtualbox.
The following are more like what I'd change in yours to keep it modular and use the upsteam site. As well, since you now have the upstream URL in the script, doing the checksum stuff becomes easier since you can get them directly as well.

Code: Select all

VBOX_VER=$(dmidecode | grep -i vboxver | grep -E -o '[[:digit:]\.]+' | tail -n 1)
FILE="VBoxGuestAdditions_${VBOX_VER}.iso"
WEBSERVER="https://download.virtualbox.org/virtualbox/${VBOX_VER}"
LOCALFILE="/home/${SLIDEUSER}/${FILE}"
URL="${WEBSERVER}/${FILE}"
Also, on worrying about ensuring that the script is run as root or not, you could also change it to use sudo as needed. As it is, if you ensure that the whole script is run as root, then you'll have files downloaded to your /home/username/ that only users in the root group can delete.

edit: Though, I really thank you for giving the dmidecode script part for finding the version. Before the other day, I was simply adding it as a CLI-argument to my own little script for installing the additions in ubuntu.
Post Reply