# lib/nova_plugins/functions-libvirt
# Common libvirt configuration functions

# Dependencies:
# ``functions`` file
# ``STACK_USER`` has to be defined

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

# Defaults
# --------

# if we should turn on massive libvirt debugging
DEBUG_LIBVIRT=$(trueorfalse False $DEBUG_LIBVIRT)

# Installs required distro-specific libvirt packages.
function install_libvirt {
    if is_ubuntu; then
        install_package qemu-kvm
        install_package libvirt-bin
        install_package python-libvirt
        install_package python-guestfs
    elif is_fedora || is_suse; then
        install_package kvm
        install_package libvirt
        install_package libvirt-python
        install_package python-libguestfs
    fi

    # Restart firewalld after install of libvirt to avoid a problem
    # with polkit, which libvirtd brings in.  See
    # https://bugzilla.redhat.com/show_bug.cgi?id=1099031

    # Note there is a difference between F20 rackspace cloud images
    # and HP images used in the gate; rackspace has firewalld but hp
    # cloud doesn't.  RHEL6 doesn't have firewalld either.  So we
    # don't care if it fails.
    if is_fedora && is_package_installed firewalld; then
        sudo service firewalld restart || true
    fi
}

# Configures the installed libvirt system so that is accessible by
# STACK_USER via qemu:///system with management capabilities.
function configure_libvirt {
    if is_service_enabled neutron && is_neutron_ovs_base_plugin && ! sudo grep -q '^cgroup_device_acl' $QEMU_CONF; then
        # Add /dev/net/tun to cgroup_device_acls, needed for type=ethernet interfaces
        cat <<EOF | sudo tee -a $QEMU_CONF
cgroup_device_acl = [
    "/dev/null", "/dev/full", "/dev/zero",
    "/dev/random", "/dev/urandom",
    "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
    "/dev/rtc", "/dev/hpet","/dev/net/tun",
]
EOF
    fi

    # Since the release of Debian Wheezy the libvirt init script is libvirtd
    # and not libvirtd-bin anymore.
    if is_ubuntu && [ ! -f /etc/init.d/libvirtd ]; then
        LIBVIRT_DAEMON=libvirt-bin
    else
        LIBVIRT_DAEMON=libvirtd
    fi

    if is_fedora || is_suse; then
        if is_fedora && [[ $DISTRO =~ (rhel6) || "$os_RELEASE" -le "17" ]]; then
            cat <<EOF | sudo tee /etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla
[libvirt Management Access]
Identity=unix-group:$LIBVIRT_GROUP
Action=org.libvirt.unix.manage
ResultAny=yes
ResultInactive=yes
ResultActive=yes
EOF
        elif is_suse && [[ $os_RELEASE = 12.2 || "$os_VENDOR" = "SUSE LINUX" ]]; then
            # openSUSE < 12.3 or SLE
            # Work around the fact that polkit-default-privs overrules pklas
            # with 'unix-group:$group'.
            cat <<EOF | sudo tee /etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla
[libvirt Management Access]
Identity=unix-user:$STACK_USER
Action=org.libvirt.unix.manage
ResultAny=yes
ResultInactive=yes
ResultActive=yes
EOF
        else
            # Starting with fedora 18 and opensuse-12.3 enable stack-user to
            # virsh -c qemu:///system by creating a policy-kit rule for
            # stack-user using the new Javascript syntax
            rules_dir=/etc/polkit-1/rules.d
            sudo mkdir -p $rules_dir
            cat <<EOF | sudo tee $rules_dir/50-libvirt-$STACK_USER.rules
polkit.addRule(function(action, subject) {
    if (action.id == 'org.libvirt.unix.manage' &&
        subject.user == '$STACK_USER') {
        return polkit.Result.YES;
    }
});
EOF
            unset rules_dir
        fi
    fi

    # The user that nova runs as needs to be member of **libvirtd** group otherwise
    # nova-compute will be unable to use libvirt.
    if ! getent group $LIBVIRT_GROUP >/dev/null; then
        sudo groupadd $LIBVIRT_GROUP
    fi
    add_user_to_group $STACK_USER $LIBVIRT_GROUP

    # Enable server side traces for libvirtd
    if [[ "$DEBUG_LIBVIRT" = "True" ]] ; then
        if is_ubuntu; then
            # Unexpectedly binary package builds in ubuntu get fully qualified
            # source file paths, not relative paths. This screws with the matching
            # of '1:libvirt' making everything turn on. So use libvirt.c for now.
            # This will have to be re-visited when Ubuntu ships libvirt >= 1.2.3
            local log_filters="1:libvirt.c 1:qemu 1:conf 1:security 3:object 3:event 3:json 3:file 1:util"
        else
            local log_filters="1:libvirt 1:qemu 1:conf 1:security 3:object 3:event 3:json 3:file 1:util"
        fi
        local log_outputs="1:file:/var/log/libvirt/libvirtd.log"
        if ! grep -q "log_filters=\"$log_filters\"" /etc/libvirt/libvirtd.conf; then
            echo "log_filters=\"$log_filters\"" | sudo tee -a /etc/libvirt/libvirtd.conf
        fi
        if ! grep -q "log_outputs=\"$log_outputs\"" /etc/libvirt/libvirtd.conf; then
            echo "log_outputs=\"$log_outputs\"" | sudo tee -a /etc/libvirt/libvirtd.conf
        fi
    fi

    # libvirt detects various settings on startup, as we potentially changed
    # the system configuration (modules, filesystems), we need to restart
    # libvirt to detect those changes.
    restart_service $LIBVIRT_DAEMON
}


# Restore xtrace
$LV_XTRACE

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