#!/bin/bash
#
# lib/nova_plugins/hypervisor-libvirt
# Configure the libvirt hypervisor

# Enable with:
# VIRT_DRIVER=libvirt

# Dependencies:
# ``functions`` file
# ``nova`` configuration

# install_nova_hypervisor - install any external requirements
# configure_nova_hypervisor - make configuration changes, including those to other services
# start_nova_hypervisor - start any external services
# stop_nova_hypervisor - stop any external services
# cleanup_nova_hypervisor - remove transient data and cache

# Save trace setting
_XTRACE_NOVA_LIBVIRT=$(set +o | grep xtrace)
set +o xtrace

source $TOP_DIR/lib/nova_plugins/functions-libvirt

# Defaults
# --------


# Entry Points
# ------------

# clean_nova_hypervisor - Clean up an installation
function cleanup_nova_hypervisor {
    # This function intentionally left blank
    :
}

# configure_nova_hypervisor - Set config files, create data dirs, etc
function configure_nova_hypervisor {
    configure_libvirt
    iniset $NOVA_CONF libvirt virt_type "$LIBVIRT_TYPE"
    iniset $NOVA_CONF libvirt cpu_mode "$LIBVIRT_CPU_MODE"
    # Do not enable USB tablet input devices to avoid QEMU CPU overhead.
    iniset $NOVA_CONF DEFAULT pointer_model "ps2mouse"
    iniset $NOVA_CONF libvirt live_migration_uri "qemu+ssh://$STACK_USER@%s/system"
    iniset $NOVA_CONF DEFAULT default_ephemeral_format "ext4"
    iniset $NOVA_CONF DEFAULT compute_driver "libvirt.LibvirtDriver"
    # Power architecture currently does not support graphical consoles.
    if is_arch "ppc64"; then
        iniset $NOVA_CONF vnc enabled "false"
    fi

    # arm64-specific configuration
    if is_arch "aarch64"; then
        iniset $NOVA_CONF libvirt cpu_mode "host-passthrough"
    fi

    if isset ENABLE_FILE_INJECTION; then
        if [ "$ENABLE_FILE_INJECTION" == "True" ]; then
            # -1 means use libguestfs to inspect the guest OS image for the
            # root partition to use for file injection.
            iniset $NOVA_CONF libvirt inject_partition '-1'
        fi
    fi

    if [[ "$LIBVIRT_TYPE" = "parallels" ]]; then
        iniset $NOVA_CONF libvirt connection_uri "parallels+unix:///system"
        iniset $NOVA_CONF libvirt images_type "ploop"
        iniset $NOVA_CONF DEFAULT force_raw_images  "False"
        iniset $NOVA_CONF vnc server_proxyclient_address  $HOST_IP
        iniset $NOVA_CONF vnc server_listen $HOST_IP
        iniset $NOVA_CONF vnc keymap
    elif [[ "$NOVA_BACKEND" == "LVM" ]]; then
        iniset $NOVA_CONF libvirt images_type "lvm"
        iniset $NOVA_CONF libvirt images_volume_group $DEFAULT_VOLUME_GROUP_NAME
        if isset LVM_VOLUME_CLEAR; then
            iniset $NOVA_CONF libvirt volume_clear "$LVM_VOLUME_CLEAR"
        fi
    fi
}

# install_nova_hypervisor() - Install external components
function install_nova_hypervisor {
    install_libvirt

    # Install and configure **LXC** if specified.  LXC is another approach to
    # splitting a system into many smaller parts.  LXC uses cgroups and chroot
    # to simulate multiple systems.
    if [[ "$LIBVIRT_TYPE" == "lxc" ]]; then
        if is_ubuntu; then
            if [[ "$DISTRO" > natty ]]; then
                install_package cgroup-lite
            fi
        else
            ### FIXME(dtroyer): figure this out
            echo "RPM-based cgroup not implemented yet"
            yum_install libcgroup-tools
        fi
    fi

    if [[ "$ENABLE_FILE_INJECTION" == "True" ]] ; then
        if is_ubuntu; then
            install_package python-guestfs
            # NOTE(andreaf) Ubuntu kernel can only be read by root, which breaks libguestfs:
            # https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725)
            INSTALLED_KERNELS="$(ls /boot/vmlinuz-*)"
            for kernel in $INSTALLED_KERNELS; do
                STAT_OVERRIDE="root root 644 ${kernel}"
                # unstack won't remove the statoverride, so make this idempotent
                if [[ ! $(dpkg-statoverride --list | grep "$STAT_OVERRIDE") ]]; then
                    sudo dpkg-statoverride --add --update $STAT_OVERRIDE
                fi
            done
        elif is_suse; then
            # Workaround for missing dependencies in python-libguestfs
            install_package python-libguestfs guestfs-data augeas augeas-lenses
        elif is_fedora; then
            install_package python3-libguestfs
        fi
    fi
}

# start_nova_hypervisor - Start any required external services
function start_nova_hypervisor {
    # This function intentionally left blank
    :
}

# stop_nova_hypervisor - Stop any external services
function stop_nova_hypervisor {
    # This function intentionally left blank
    :
}


# Restore xtrace
$_XTRACE_NOVA_LIBVIRT

# Local variables:
# mode: shell-script
# End:
