#!/bin/sh # This file is part of Cockpit. # # Copyright (C) 2013 Red Hat, Inc. # # Cockpit is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # # Cockpit is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Cockpit; If not, see . VIRSH=/bin/virsh QEMU_BRIDGE_HELPER=/usr/libexec/qemu-bridge-helper BASE=$(dirname $0) SELF=vm-prep set -euf usage() { echo >&2 "usage: $SELF [-u]" } warning() { echo >&2 "$SELF: $@" } silent() { "$@" > /dev/null 2> /dev/null return $? } prepare() { if ! virsh list >/dev/null 2>&1; then if systemctl status >/dev/null 2>&1; then systemctl start libvirtd else libvirtd -d virtlogd -d fi fi if silent $VIRSH net-info $NETWORK_NAME; then $VIRSH net-destroy $NETWORK_NAME || true $VIRSH net-undefine $NETWORK_NAME fi # In case a network has leaked in from elsewhere if ip address show dev $NETWORK_NAME >/dev/null 2>/dev/null; then ip link set $NETWORK_NAME down || true brctl delbr $NETWORK_NAME || true fi # HACK: NetworkManager races with dnsmasq-dhcp on bridge # https://bugzilla.redhat.com/show_bug.cgi?id=1205081 cat > /etc/sysconfig/network-scripts/ifcfg-$NETWORK_NAME << EOF DEVICE=$NETWORK_NAME NM_CONTROLLED=no EOF # HACK: In case of read-only /sys avoid libvirt writing there mount -o bind /mnt /sys/devices/virtual/net/ $VIRSH net-define $BASE/common/network-cockpit.xml $VIRSH net-autostart $NETWORK_NAME $VIRSH net-start $NETWORK_NAME umount /sys/devices/virtual/net if [ ! -u $QEMU_BRIDGE_HELPER ]; then chmod -v u+s $QEMU_BRIDGE_HELPER fi qemu_config_dirs=() for d in /etc/qemu-kvm/ /etc/qemu; do if test -f ${d}/bridge.conf; then qemu_config_dirs+=(${d}) fi done if [ ${#qemu_config_dirs[@]} -eq 0 ]; then warning "Could not find qemu config dir" exit 1 fi rule="allow $NETWORK_NAME" for qemu_config_dir in ${qemu_config_dirs[@]}; do if ! silent grep -F $NETWORK_NAME ${qemu_config_dir}/bridge.conf; then echo "$rule" >> ${qemu_config_dir}/bridge.conf fi done # We really want nested virtualization if [ -d /sys/module/kvm_intel -a -d /etc/modprobe.d -a ! -f /etc/modprobe.d/kvm-intel.conf ]; then echo "options kvm-intel nested=1" > /etc/modprobe.d/kvm-intel.conf rmmod kvm-intel && modprobe kvm-intel || true fi if [ -d /sys/module/kvm_amd -a -d /etc/modprobe.d -a ! -f /etc/modprobe.d/kvm-amd.conf ]; then echo "options kvm-amd nested=1" > /etc/modprobe.d/kvm-amd.conf rmmod kvm-amd && modprobe kvm-amd || true fi } unprepare() { if ! silent virsh net-info $NETWORK_NAME; then warning "the $NETWORK_NAME network has not been configured" exit 1 fi $VIRSH net-destroy $NETWORK_NAME $VIRSH net-undefine $NETWORK_NAME } operation=prepare args=$(getopt -o "uh" -l "help" -- "$@") eval set -- "$args" while [ $# -gt 0 ]; do case $1 in -h|--help) usage exit 0 ;; -u) operation=unprepare ;; --) shift break ;; esac shift done if [ $# -ne 0 ]; then usage exit 2 fi uid=$(id -u) if [ "$uid" != "0" ]; then warning "this script must be run as root" exit 1 fi NETWORK_NAME=cockpit1 $operation