You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
994 lines
23 KiB
994 lines
23 KiB
#!/usr/bin/env bash
|
|
|
|
set -eu
|
|
|
|
set -m # Jobs control
|
|
|
|
# Script pour l'exécution d'un système virtuel
|
|
# --------------------------------------------
|
|
|
|
NICE=10
|
|
EXPR=""
|
|
READ_ON_ERROR=0
|
|
GUI=0;
|
|
VDN_TERM=0
|
|
BG=0
|
|
|
|
EXCLUDE_SERVICES=""
|
|
|
|
set -a
|
|
|
|
# Dans le cas où une redirection (cf. REDIRS ci-dessus) échoue,
|
|
# attendre que le port se libère (0) ou chercher le premier port libre
|
|
# suivant (1).
|
|
|
|
PORT_INC_ALLOWED=1
|
|
|
|
set +a
|
|
|
|
# début des fonctions
|
|
|
|
synopsis() {
|
|
cat << EOF
|
|
Usage : `basename $0` [-h] [-f] [-g] [-e] [-t] [-v expr] system
|
|
EOF
|
|
}
|
|
|
|
help() {
|
|
cat << EOF
|
|
|
|
`basename $0` démarre un système virtuel.
|
|
|
|
`synopsis`
|
|
|
|
Un nom de système correspond au nom d'un répertoire situé dans le
|
|
sous répertoire "systems" de Vdn.
|
|
|
|
-h : affiche cette aide
|
|
-b : execute le système en arrière plan.
|
|
-d : mode DEBUG.
|
|
-g : si l'interface graphique est démarrée, lui délègue le démarrage.
|
|
-t : le terminal courant est utilisé en console.
|
|
-e : Attendre "Entrée" si erreur.
|
|
-v exp : évalue une expression. Pratique pour la surcharge de variables.
|
|
exemple : -v "MEMORY=32; SWAP_SIZE=32"
|
|
|
|
EOF
|
|
}
|
|
|
|
usage() {
|
|
synopsis
|
|
exit 2
|
|
}
|
|
|
|
args() {
|
|
local opt
|
|
while getopts "hebdgtv:" opt; do
|
|
case $opt in
|
|
h) help; exit 0;;
|
|
b) BG=1;;
|
|
d) export VDN_DEBUG=1;;
|
|
e) READ_ON_ERROR=1;;
|
|
g) GUI=1;;
|
|
t) VDN_TERM=1;;
|
|
v) export EXPR="$OPTARG";;
|
|
?) usage;;
|
|
esac
|
|
done
|
|
shift $(($OPTIND - 1))
|
|
[ $# -ne 1 ] && usage
|
|
|
|
GUEST_NAME="$1"
|
|
if echo $GUEST_NAME | grep -q '/'; then
|
|
error "$GUEST_NAME est un nom de système invalide"
|
|
fi
|
|
|
|
case "$GUEST_NAME" in
|
|
sae103)
|
|
|
|
VDN_TERM=1
|
|
|
|
net=$(vdn-get-network)
|
|
if [ "$net" != "/home/UCA/vdn/vdn-bullseye/networks/sae103" ]; then
|
|
vdn-set-network-dir /home/UCA/vdn/vdn-bullseye/networks/sae103
|
|
export NETWORK_DIR=/home/UCA/vdn/vdn-bullseye/networks/sae103
|
|
SAVE_DIR="$SAVE_PATH/$(basename $NETWORK_DIR)"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
testIfAlreadyStarted() {
|
|
set +e
|
|
vdn-alive $GUEST_NAME
|
|
r=$?
|
|
|
|
[ $r -eq 0 ] && error "Le système virtuel $GUEST_NAME est déjà lancé"
|
|
}
|
|
|
|
|
|
testVariables() {
|
|
[ -z "$AUFS_SIZE" ] && error "AUFS_SIZE not set"
|
|
}
|
|
|
|
createConfigFile() {
|
|
local dir=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-config/etc/vdn
|
|
set +u
|
|
[ -z "$http_proxy" ] && export http_proxy=""
|
|
[ -z "$https_proxy" ] && export https_proxy=""
|
|
[ -z "$POST_BOOT" ] && POST_BOOT=""
|
|
set -u
|
|
|
|
NB_ETH=$(echo $NETWORKS | wc -w)
|
|
|
|
|
|
echo -n "Compute network vars... "
|
|
#PUBLICS_IP=$(for i in $(vdn-list); do ip=$(vdn-infos $i | grep PUB | sed -re 's/^.*"([0-9.]+)" .*$/\1/'); echo -n "$i:$ip "; done)
|
|
PUBLICS_IP=$(for i in $(vdn-list); do ip=$(vdn-query PUBLIC_IP $i); echo -n "$i:$ip "; done)
|
|
|
|
PUBLIC_IP=$(vdn-query PUBLIC_IP 0 $GUEST_NAME.$NETWORK_NAME)
|
|
|
|
echo "done"
|
|
|
|
echo >&2
|
|
echo "NETWORKS : $NETWORKS" >&2
|
|
echo "NB_ETH : $NB_ETH" >&2
|
|
echo "PUBLICS_IP: $PUBLICS_IP" >&2
|
|
|
|
cat <<EOF > $dir/config
|
|
|
|
PUBLICS_IP="$PUBLICS_IP"
|
|
HOSTS="$HOSTS"
|
|
NETWORKS="$NETWORKS"
|
|
NETWORK_DIR="$NETWORK_DIR"
|
|
|
|
VDN_RESOLV="$VDN_RESOLV"
|
|
|
|
VDN_RESOURCES_ALLOCATOR="$VDN_RESOURCES_ALLOCATOR"
|
|
|
|
|
|
VDN_PATH="$VDN_PATH"
|
|
GUEST_SYS="$GUEST_SYS"
|
|
MOUNT_ROOT_PATH="$MOUNT_ROOT_PATH"
|
|
EMULATOR="$EMULATOR"
|
|
|
|
MODE="$MODE"
|
|
|
|
HDA="$HDA"
|
|
HDB="$HDB"
|
|
HDB_PART_FORMAT="$HDB_PART_FORMAT"
|
|
HDB_DIRS="$HDB_DIRS"
|
|
|
|
GUEST_PATH="$GUEST_PATH"
|
|
GUEST_NAME="$GUEST_NAME"
|
|
GUEST_OWNER="$GUEST_OWNER"
|
|
|
|
NB_ETH="$NB_ETH"
|
|
NB_DISK="$NB_DISK"
|
|
PUBLIC_IP="$PUBLIC_IP"
|
|
|
|
ON_BOOT="$ON_BOOT" # deprecié
|
|
POST_BOOT="$POST_BOOT"
|
|
SET_HOSTNAME="$SET_HOSTNAME"
|
|
|
|
EXTRA_ETH="$EXTRA_ETH"
|
|
EXTRA_ETH_DEFAULT_ROUTE="$EXTRA_ETH_DEFAULT_ROUTE"
|
|
EXTRA_ETH_MASQUERADING="$EXTRA_ETH_MASQUERADING"
|
|
SET_PROXY="$SET_PROXY"
|
|
|
|
AUFS_FILE="$AUFS_FILE"
|
|
AUFS_SIZE="$AUFS_SIZE"
|
|
|
|
SAVE_EXCLUDE="$SAVE_EXCLUDE"
|
|
CLEAR_LOG_WHEN_SAVE="$CLEAR_LOG_WHEN_SAVE"
|
|
DELETE_LOG_GZ="$DELETE_LOG_GZ"
|
|
|
|
SWAP_FILE="$SWAP_FILE"
|
|
SWAP_SIZE="$SWAP_SIZE"
|
|
|
|
SSH_IDENTITY="$SSH_IDENTITY"
|
|
|
|
EXTRA_SERVICES="$EXTRA_SERVICES"
|
|
EXCLUDE_SERVICES="$EXCLUDE_SERVICES"
|
|
|
|
RUNLEVEL="$RUNLEVEL"
|
|
|
|
DATE=`date +%Y.%m.%d-%T`
|
|
|
|
if [ "\$SET_PROXY" = 1 ]; then
|
|
|
|
HTTP_PROXY="$http_proxy"
|
|
HTTPS_PROXY="$https_proxy"
|
|
|
|
echo "export http_proxy=\"\$HTTP_PROXY\"" >> /etc/bash.bashrc
|
|
echo "export https_proxy=\"\$HTTPS_PROXY\"" >> /etc/bash.bashrc
|
|
fi
|
|
|
|
DEFAULT_LANG="$DEFAULT_LANG"
|
|
|
|
TIMEZONE="$TIMEZONE"
|
|
|
|
XKBMODEL="$XKBMODEL"
|
|
XKBLAYOUT="$XKBLAYOUT"
|
|
XKBVARIANT="$XKBVARIANT"
|
|
XKBOPTIONS="$XKBOPTIONS"
|
|
BACKSPACE="$BACKSPACE"
|
|
|
|
VDN_DEBUG="$VDN_DEBUG"
|
|
EOF
|
|
}
|
|
|
|
waitEndOfRedirsOld() {
|
|
local n=0
|
|
#while netstat -A inet -a -n | grep TIME_WAIT | \
|
|
while ss -a -f inet -n -i state time-wait | \
|
|
grep -q "^$1[[:space:]].*:$2[[:space:]]"; do
|
|
if [ $n = 0 ]; then
|
|
echo "Attente de la libération du port $2 (1 minute environ...)">&2
|
|
fi
|
|
n=1
|
|
sleep 1
|
|
done
|
|
}
|
|
|
|
|
|
|
|
# Create partition for union
|
|
|
|
createUnionPart() {
|
|
echo "Create overlayfs ($AUFS_SIZE Mo). "
|
|
|
|
|
|
|
|
if [ -n "$AUFS_FILE" ]; then
|
|
|
|
[ ! -d $(dirname $AUFS_FILE) ] && mkdir -p $(dirname $AUFS_FILE)
|
|
|
|
[ -e $AUFS_FILE ] && rm $AUFS_FILE
|
|
dd of=$AUFS_FILE bs=1k seek=$(($AUFS_SIZE*1024)) count=0 &> /dev/null
|
|
/sbin/mke2fs -q -F -t ext4 $AUFS_FILE
|
|
fi
|
|
|
|
#rm -f $OUT_FILE
|
|
#dd of=$OUT_FILE bs=1k seek=$(($AUFS_SIZE*1024)) count=0
|
|
|
|
|
|
}
|
|
|
|
prepareSwap() {
|
|
if [ -n "$SWAP_FILE" ]; then
|
|
[ -e $SWAP_FILE ] && rm $SWAP_FILE
|
|
if [ -z "$SWAP_SIZE" ]; then
|
|
echo -e "SWAP_SIZE not set !" >&2
|
|
exit 2
|
|
fi
|
|
echo "Create swap ($SWAP_SIZE Mo). "
|
|
dd of=$SWAP_FILE bs=1k seek=$(($SWAP_SIZE*1024)) count=0 &> /dev/null
|
|
chmod 600 $SWAP_FILE
|
|
/sbin/mkswap $SWAP_FILE > /dev/null
|
|
#echo " done."
|
|
fi
|
|
}
|
|
|
|
tgzPrepare() {
|
|
createUnionPart
|
|
}
|
|
|
|
injectScriptsInConfigDir() {
|
|
local srcDir=$1
|
|
local dstDir=$2
|
|
|
|
if [ -d $srcDir ]; then
|
|
local list=$(cd $srcDir; ls | grep -v prepare.sh*)
|
|
if [ -n "$list" ]; then
|
|
( cd $srcDir; cp -a $list $dir/etc/vdn )
|
|
if [ -e $dir/etc/vdn/rc.local ]; then
|
|
mv $dir/etc/vdn/rc.local $dir/etc
|
|
chmod 755 $dir/etc/rc.local
|
|
#echo "SET FILE : $dir/etc/rc.local"
|
|
#echo "=== EXTRA === : "
|
|
#cat $dir/etc/rc.local | grep EXTRA
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
createConfigDir() {
|
|
local dir=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-config
|
|
local tgz="$dir.tgz"
|
|
|
|
|
|
#echo "Create config dir..."
|
|
|
|
rm -Rf $dir
|
|
|
|
mkdir -m 700 $dir
|
|
|
|
mkdir -p $dir/etc/vdn
|
|
|
|
# Copie des fichiers d'initialisation (/etc/rc.local et autres
|
|
# du répertoire direct
|
|
|
|
injectScriptsInConfigDir $VDN_PATH/distribs/guests/direct/$GUEST_SYS $dir
|
|
|
|
# idem mais spécialise les fichiers (COW, OVERLAY, TGZ)
|
|
|
|
if [ $MODE != direct ]; then
|
|
injectScriptsInConfigDir $VDN_PATH/distribs/guests/$MODE/$GUEST_SYS $dir
|
|
fi
|
|
|
|
createConfigFile
|
|
|
|
local cp=0
|
|
|
|
for i in $SSH_IDENTITY; do
|
|
[ ! -d $dir/etc/vdn/.ssh ] && {
|
|
mkdir -p $dir/etc/vdn/.ssh
|
|
chmod 700 $dir/etc/vdn/.ssh
|
|
}
|
|
if [ -e $i ]; then
|
|
cp $i $dir/etc/vdn/.ssh/
|
|
cp=1
|
|
fi
|
|
done
|
|
|
|
[ $cp = 0 ] && error "Aucune clé SSH !"
|
|
|
|
[ -e $NETWORK_DIR/authorized-root.txt ] && \
|
|
cp $NETWORK_DIR/authorized-root.txt $dir/etc/vdn
|
|
|
|
# Add host files
|
|
|
|
for i in $HOST_FILES; do
|
|
[ ! -d $dir/etc/vdn/host/$(dirname $i) ] && mkdir -p $dir/etc/vdn/host/$(dirname $i) || :
|
|
cp -a $i $dir/etc/vdn/host/$(dirname $i)
|
|
done
|
|
|
|
if [ -d $NETWORK_DIR/all ]; then
|
|
[ ! -d $dir/etc/vdn/all ] && mkdir -p $dir/etc/vdn/all
|
|
( cd $NETWORK_DIR/all && tar czf - . ) | ( cd $dir/etc/vdn/all && tar -xpzf -)
|
|
fi
|
|
|
|
if [ -d $NETWORK_DIR/$GUEST_NAME ]; then
|
|
[ ! -d $dir/etc/vdn/guest ] && mkdir -p $dir/etc/vdn/guest
|
|
( cd $NETWORK_DIR/$GUEST_NAME && tar czf - . ) | ( cd $dir/etc/vdn/guest && tar -xpzf - )
|
|
fi
|
|
|
|
# note used
|
|
#cp /etc/hosts $dir/etc/vdn
|
|
#cp /etc/resolv.conf $dir/etc/vdn
|
|
|
|
if [ -d $VDN_PATH/scripts ]; then
|
|
cp -a $VDN_PATH/scripts/* $dir/etc/vdn
|
|
fi
|
|
|
|
# Add allocator
|
|
[ -d $dir/etc/vdn/allocators ] && rm -Rf $dir/etc/vdn/allocators
|
|
cp -a $VDN_PATH/allocators $dir/etc/vdn
|
|
|
|
# Add vdn resolv
|
|
cp $VDN_PATH/tools/libnss_vdn.so $dir/etc/vdn
|
|
|
|
# Build disk
|
|
|
|
( cd $dir; tar -czf $tgz .; chmod 600 $tgz)
|
|
#echo -n "Create config disk... "
|
|
dd if=/dev/zero bs=512 count=1 >> $tgz 2> /dev/null
|
|
#echo "done."
|
|
|
|
#echo "done."
|
|
|
|
}
|
|
|
|
### KVM (Kernel Virtual Machine)
|
|
|
|
|
|
kvm_query_networks() {
|
|
|
|
. $VDN_PATH/allocators/$VDN_RESOURCES_ALLOCATOR
|
|
|
|
|
|
# 1. redirections
|
|
|
|
#if [ $EXTRA_ETH = 1 ]; then
|
|
|
|
rm -f $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs
|
|
REDIRS=$(echo "$REDIRS" | sed -re 's/[[:space:]]+/ /g')
|
|
REDIRS=$(echo "$REDIRS" | sed -re 's/^[[:space:]]+//g')
|
|
REDIRS=$(echo "$REDIRS" | sed -re 's/[[:space:]]+$//g')
|
|
REDIRS=$(echo "$REDIRS" | sed -re 's/[[:space:]]/\n/g')
|
|
|
|
|
|
#echo "REDIRS:$REDIRS" >&2
|
|
|
|
redirs=`
|
|
redirsOpt=""
|
|
[ -n "$REDIRS" ] || error "REDIRS empty !"
|
|
echo "$REDIRS" | (
|
|
export IFS=":"
|
|
i=0
|
|
while read proto dstPort com; do
|
|
[ -z "$dstPort" ] && continue
|
|
|
|
|
|
#echo "dstPort:$dstPort" >&2
|
|
#srcPort=$(vdn_redir $dstPort)
|
|
[ -z "$proto" ] && continue
|
|
|
|
#set -x
|
|
|
|
srcPort=$(computeRedir $GUEST_NAME $proto $dstPort)
|
|
|
|
echo "port:$srcPort" >&2
|
|
#set +x
|
|
|
|
#if [ "$PORT_INC_ALLOWED" = 1 ]; then
|
|
# srcPort=$(findUnusedPort $proto $srcPort $dstPort)
|
|
#fi
|
|
#waitEndOfRedirs $proto $srcPort
|
|
redirsOpt="$redirsOpt -redir $proto:$srcPort::$dstPort"
|
|
|
|
echo "Add to : $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs" >&2
|
|
echo "$proto:$srcPort:$dstPort:$com">>$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-redirs
|
|
done
|
|
echo "$redirsOpt"
|
|
)
|
|
`
|
|
#fi
|
|
|
|
# 2. cartes Ethernet
|
|
|
|
set - $NETWORKS
|
|
|
|
#echo -n "-net user "
|
|
|
|
#for i in `seq 0 $(($NB_ETH-1))`; do
|
|
|
|
ETH=0
|
|
|
|
for i; do
|
|
#set -x
|
|
net="$i"
|
|
|
|
comment=$(echo $net | cut -d '#' -f 2)
|
|
net=$(echo $net | cut -d '#' -f 1)
|
|
[ "$net" = "$comment" ] && comment=""
|
|
|
|
|
|
|
|
[ "$net" = "NET_G" ] && net="NET_0"
|
|
|
|
[ "$net" = "$comment" ] && comment=""
|
|
|
|
netNum=$(echo $net | sed -re 's/^ *NET_([0-9]+).*$/\1/')
|
|
|
|
mac=$(computeMacAddr $GUEST_NAME $ETH)
|
|
|
|
if [ "$net" = "none" ]; then
|
|
local qemuVersion=$(qemu-system-x86_64 --version | grep version | sed -re 's/^.*version ([0-9.]+).*$/\1/')
|
|
if [ "$qemuVersion" \< "3.0.0" ]; then
|
|
echo -n "-device virtio-net-pci,mac=$mac "
|
|
else
|
|
echo -n "-device virtio-net-pci,mac=$mac -nic none "
|
|
fi
|
|
else
|
|
if [ $netNum = 0 ]; then
|
|
group=$MCAST_COMMON_ADDR
|
|
port=$MCAST_BASE_PORT
|
|
else
|
|
mcast=$(computeEthLink $GUEST_NAME $netNum)
|
|
echo "inetNum:$netNum mcast:$mcast" >&2
|
|
group=`echo $mcast | cut -d : -f 1`
|
|
port=`echo $mcast | cut -d : -f 2`
|
|
fi
|
|
|
|
echo -n "-device virtio-net-pci,netdev=n$(($netNum)),mac=$mac -netdev socket,id=n$(($netNum)),mcast=$group:$port "
|
|
fi
|
|
|
|
ETH=$(($ETH+1))
|
|
|
|
done
|
|
|
|
[ $EXTRA_ETH = 1 ] && {
|
|
mac=$(computeMacAddr $GUEST_NAME $NB_ETH)
|
|
redirs=$(echo $redirs | sed -re 's/^ *//')
|
|
|
|
echo -n "-device virtio-net-pci,netdev=e0,mac=$mac -netdev user,id=e0$redirs"
|
|
#echo -n "-net nic,vlan=0,model=$NET_MODEL -net user,vlan=0$redirs"
|
|
|
|
} || :
|
|
}
|
|
|
|
kvm_graphic() {
|
|
GRAPHICAL_OPTS=""
|
|
|
|
if [ $KVM_VIEWER = "vnc" ]; then
|
|
set +e
|
|
ps auwx | grep -v grep |grep -q 'ruby.*vdn-gui'
|
|
GUI_RUNNING=$?
|
|
set -e
|
|
if [ $KVM_VIEWER_AUTOSTART = 1 ]; then
|
|
if [ $KVM_VIEWER_EMBEDDED = 1 -a $GUI_RUNNING = 0 ]; then
|
|
( sleep 3; sendToGui "vnc-viewer $GUEST_NAME" ) &
|
|
else
|
|
(sleep 3; vdn-vnc-viewer $GUEST_NAME ) &
|
|
fi
|
|
fi
|
|
GRAPHICAL_OPTS="-serial mon:stdio -monitor null -vnc unix:$TMPDIR/vdn-vnc-$USER-$GUEST_NAME-socket -spice unix,disable-ticketing,addr=$TMPDIR/vdn-spice-$USER-$GUEST_NAME-socket"
|
|
#GRAPHICAL_OPTS="$GRAPHICAL_OPTS -device virtio-serial -chardev spicevmc,id=vdagent,debug=0,name=vdagent -device virtserialport,chardev=vdagent,name=com.redhat.spice.0"
|
|
|
|
elif [ $KVM_VIEWER = "spice" ]; then
|
|
set +e
|
|
ps auwx | grep -v grep |grep -q 'ruby.*vdn-gui'
|
|
GUI_RUNNING=$?
|
|
set -e
|
|
if [ $KVM_VIEWER_AUTOSTART = 1 ]; then
|
|
#if [ $KVM_VIEWER_EMBEDDED = 1 -a $GUI_RUNNING = 0 ]; then
|
|
# ( sleep 3; sendToGui "spice-viewer $GUEST_NAME" ) &
|
|
#else
|
|
(sleep 1; vdn-spice-viewer -b $GUEST_NAME ) &
|
|
#fi
|
|
fi
|
|
GRAPHICAL_OPTS="-serial mon:stdio -monitor null -vnc unix:$TMPDIR/vdn-vnc-$USER-$GUEST_NAME-socket -spice unix,disable-ticketing,addr=$TMPDIR/vdn-spice-$USER-$GUEST_NAME-socket"
|
|
GRAPHICAL_OPTS="$GRAPHICAL_OPTS -device virtio-serial -chardev spicevmc,id=vdagent,debug=0,name=vdagent -device virtserialport,chardev=vdagent,name=com.redhat.spice.0"
|
|
#GRAPHICAL_OPTS="$GRAPHICAL_OPTS -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel1,id=channel1,name=org.spice-space.stream.0 -chardev spiceport,name=org.spice-space.stream.0,id=charchannel1"
|
|
|
|
elif [ $KVM_VIEWER = "sdl" ]; then
|
|
GRAPHICAL_OPTS="-serial mon:stdio -monitor null"
|
|
|
|
else
|
|
GRAPHICAL_OPTS="-serial mon:stdio -monitor null -nographic"
|
|
fi
|
|
}
|
|
|
|
startKvmTgz() {
|
|
|
|
# Config
|
|
|
|
local r=0
|
|
|
|
[ ! -d $(dirname $SAVE_FILE) ] && mkdir -p $(dirname $SAVE_FILE)
|
|
|
|
case "$MODE" in
|
|
tgz)
|
|
# Sauvegarde
|
|
[ ! -e $SAVE_FILE ] && {
|
|
#echo -n "Create minimal save file. "
|
|
dd if=/dev/zero of=$SAVE_FILE count=1 bs=1 &> /dev/null
|
|
#echo "done."
|
|
}
|
|
DISK_OPTS="$DISK_OPTS -drive file=$SAVE_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
# aufs part
|
|
DISK_OPTS="$DISK_OPTS -drive file=$AUFS_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
# swap
|
|
[ -n "$SWAP_FILE" ] &&
|
|
DISK_OPTS="$DISK_OPTS -drive file=$SWAP_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
#DISK_OPTS="$DISK_OPTS -drive file=$OUT_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
;;
|
|
tgz2)
|
|
# Sauvegarde
|
|
[ ! -e $SAVE_FILE ] && {
|
|
#echo -n "Create minimal save file. "
|
|
dd if=/dev/zero of=$SAVE_FILE count=1 bs=1 &> /dev/null
|
|
#echo "done."
|
|
}
|
|
DISK_OPTS="$DISK_OPTS -drive file=$SAVE_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
# aufs part
|
|
DISK_OPTS="$DISK_OPTS -drive file=$AUFS_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
# swap
|
|
[ -n "$SWAP_FILE" ] &&
|
|
DISK_OPTS="$DISK_OPTS -drive file=$SWAP_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
|
|
;;
|
|
overlay)
|
|
# Sauvegarde
|
|
[ ! -e $SAVE_FILE ] && {
|
|
#echo -n "Create minimal save file. "
|
|
dd of=$SAVE_FILE bs=1k seek=$(($AUFS_SIZE*1024)) count=0 &> /dev/null
|
|
/sbin/mke2fs -q -F -t ext4 $SAVE_FILE
|
|
#echo "done."
|
|
}
|
|
DISK_OPTS="$DISK_OPTS -drive file=$SAVE_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
# aufs part
|
|
# none, is $SAVE_FILE
|
|
|
|
# swap
|
|
|
|
[ -n "$SWAP_FILE" ] &&
|
|
DISK_OPTS="$DISK_OPTS -drive file=$SWAP_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
;;
|
|
esac
|
|
|
|
KVM_NETWORKS_OPTS="$networks"
|
|
|
|
# Options passées au noyau
|
|
|
|
case "$MODE" in
|
|
tgz2) KOPTS="";;
|
|
*) KOPTS="root=/dev/vda1 ro console=ttyS0,115200n8"
|
|
KOPTS="$KOPTS vdn-emulator=kvm vdn-mode=$MODE"
|
|
KOPTS="$KOPTS net.ifnames=0 noresume" # fastboot quiet"
|
|
|
|
KOPTS="root=/dev/vda1 ro console=ttyS0,115200n8"
|
|
KOPTS="$KOPTS vdn-emulator=kvm vdn-mode=$MODE"
|
|
KOPTS="$KOPTS net.ifnames=0 noresume" # fastboot quiet"
|
|
esac
|
|
|
|
createConfigDir
|
|
|
|
# config disk (last disk)
|
|
configTgz=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-config.tgz
|
|
DISK_OPTS="$DISK_OPTS -drive file=$configTgz,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
kvm_graphic
|
|
|
|
echo "Start begin (EMULATOR=$EMULATOR, SAVE_FILE=$SAVE_FILE)"
|
|
|
|
case "$MODE" in
|
|
tgz2) cmd="ionice -c 3 nice -$NICE $EMULATOR \
|
|
$KVM_OPTS $GRAPHICAL_OPTS \
|
|
$DISK_OPTS \
|
|
$KVM_NETWORKS_OPTS \
|
|
"
|
|
|
|
echo "==> CMD: $cmd"
|
|
|
|
;;
|
|
|
|
*) cmd="ionice -c 3 nice -$NICE $EMULATOR \
|
|
$KVM_OPTS $GRAPHICAL_OPTS \
|
|
-initrd $VDN_PATH/files/$INITRAMFS \
|
|
-kernel $VDN_PATH/files/$KERNEL \
|
|
-append '$KOPTS' \
|
|
$DISK_OPTS \
|
|
$KVM_NETWORKS_OPTS \
|
|
"
|
|
;;
|
|
esac
|
|
|
|
set +u
|
|
[ -z "$FORCE_BG" ] && export FORCE_BG=0 || :
|
|
|
|
set -u
|
|
|
|
#echo $cmd | tr ' ' '\n'
|
|
|
|
if [ $BG = 1 -o \( $FORCE_BG = 1 -a $WITH_GUI = 0 \) ]; then
|
|
eval $cmd < /dev/null &> /dev/null &
|
|
#r=$?
|
|
#trap - 0
|
|
return 0
|
|
fi
|
|
#if [ $FORCE_BG = 1 ]; then
|
|
# eval $cmd &
|
|
#fi
|
|
|
|
|
|
if [ "$VDN_TERM" = 0 ]; then
|
|
set -e
|
|
|
|
$VDN_PATH/bin/vdn-terminal "$cmd"
|
|
|
|
r=$?
|
|
set +e
|
|
else
|
|
set +e
|
|
eval $cmd
|
|
r=$?
|
|
stty sane
|
|
set -e
|
|
fi
|
|
return $r
|
|
}
|
|
|
|
startKvmDirectOrCow() {
|
|
|
|
local r=0
|
|
|
|
set +u
|
|
if [ "$HDA" = "$VDN_DISK_ENV" ]; then
|
|
error "Impossible de monter en écriture le disque $VDN_DISK_ENV \nservant à l'environnement chroot.\nAbandon"
|
|
fi
|
|
set -u
|
|
|
|
if [ ! -e "$VDN_PATH/files/$HDA" ]; then
|
|
[ -z "$HDA_SIZE" ] && error "Need HDA_SIZE (in Mo)"
|
|
echo "Create $HDA. Size=$HDA_SIZE (Mo)"
|
|
dd if=/dev/zero of=$VDN_PATH/files/$HDA count=1 bs=512
|
|
dd of=$VDN_PATH/files/$HDA count=0 bs=1M seek=$HDA_SIZE
|
|
fi
|
|
|
|
[ $MODE = direct -a ! -w $VDN_PATH/files/$HDA ] && \
|
|
error "No write permission on $VDN_PATH/files/$HDA"
|
|
|
|
KVM_NETWORKS_OPTS="$networks"
|
|
#KVM_NETWORKS_OPTS="$(eval echo $networks)"
|
|
|
|
[ -n "$SWAP_FILE" ] &&
|
|
DISK_OPTS="$DISK_OPTS -drive file=$SWAP_FILE,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
createConfigDir
|
|
configTgz=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-config.tgz
|
|
|
|
set +u
|
|
[ -z "$DISK_OPTS" ] && DISK_OPTS=""
|
|
set -u
|
|
|
|
DISK_OPTS="$DISK_OPTS -drive file=$configTgz,if=$KVM_DISK_MODEL,media=disk,format=raw"
|
|
|
|
kvm_graphic
|
|
|
|
echo "Start startKvmDirect begin (EMULATOR=$EMULATOR)"
|
|
|
|
cmd="ionice -c 3 nice -$NICE $EMULATOR \
|
|
$KVM_OPTS $GRAPHICAL_OPTS \
|
|
$DISK_OPTS \
|
|
$KVM_NETWORKS_OPTS \
|
|
"
|
|
|
|
if [ $BG = 1 ]; then
|
|
eval $cmd < /dev/null &> /dev/null &
|
|
r=$?
|
|
trap - 0
|
|
return $r
|
|
fi
|
|
|
|
if [ "$VDN_TERM" = 0 ]; then
|
|
set -e
|
|
$VDN_PATH/bin/vdn-terminal "$cmd"
|
|
r=$?
|
|
set +e
|
|
else
|
|
set +e
|
|
eval $cmd
|
|
r=$?
|
|
stty sane
|
|
set -e
|
|
fi
|
|
|
|
return $r
|
|
}
|
|
|
|
startKvm() {
|
|
|
|
local r=0
|
|
|
|
echo "Start KVM"
|
|
|
|
networks=`kvm_query_networks`
|
|
|
|
# for last QEMU versions ( -redir -> hostfwd )
|
|
if echo "$networks" | grep -q -- -redir; then
|
|
n=$(echo "$networks" | sed -re 's/-redir +(tcp|udp):([^:]+)::([0-9]+)( |$)/,hostfwd=\1::\2-:\3/g')
|
|
networks=$(echo "$n" | sed -re 's/-net user /-net user/g')
|
|
fi
|
|
|
|
echo "networks : $NETWORKS" >&2
|
|
|
|
NB_DISK=0
|
|
DISK_OPTS=""
|
|
|
|
#echo "MODE 1:$MODE"
|
|
case "$MODE" in
|
|
tgz|overlay|tgz2)
|
|
[ $BOOT_CDROM = 1 ] && error "BOOT_CDROM=1 : Can't boot on cdrom !"
|
|
#[ -n "$CDROM" ] && warning "CDROM not allowed in tgz mode"
|
|
#CDROM=""
|
|
tgzPrepare
|
|
;;
|
|
cow)
|
|
[ -z "$HDA" ] && error "Mode COW : Need HDA Disk" || :
|
|
[ -z "$SAVE_FILE" ] && error "Mode COW : Need SAVE_FILE" || :
|
|
[ ! -d $(dirname $SAVE_FILE) ] && mkdir -p $(dirname $SAVE_FILE)
|
|
[ ! -e "$SAVE_FILE" ] && {
|
|
#echo "Create $SAVE_FILE"
|
|
|
|
[ $VDN_DEBUG = 1 ] && set -x || :
|
|
( umask 077; qemu-img create -b $VDN_PATH/files/$HDA -f qcow2 $SAVE_FILE )
|
|
set +x
|
|
}
|
|
;;
|
|
esac
|
|
|
|
local boot_hda=on
|
|
local boot_cdrom=off
|
|
local boot_drive=c
|
|
local boot_order=c
|
|
|
|
[ $BOOT_CDROM = 1 ] && {
|
|
boot_hda=off
|
|
boot_cdrom=on
|
|
local boot_drive=d
|
|
local boot_order=d
|
|
}
|
|
|
|
#set +x
|
|
|
|
case "$MODE" in
|
|
tgz|overlay|tgz2)
|
|
DISK_OPTS="-boot order=$boot_order -drive file=$VDN_PATH/files/$HDA,if=$KVM_DISK_MODEL,snapshot=on,format=raw"
|
|
;;
|
|
cow)
|
|
DISK_OPTS="-boot order=$boot_order -drive file=$SAVE_FILE,if=$KVM_DISK_MODEL"
|
|
;;
|
|
direct)
|
|
DISK_OPTS="-boot order=$boot_order -drive file=$VDN_PATH/files/$HDA,if=$KVM_DISK_MODEL,format=raw"
|
|
;;
|
|
*) error "Invalide mode : $MODE"
|
|
;;
|
|
esac
|
|
|
|
NB_DISK=$(($NB_DISK+1))
|
|
|
|
set +u
|
|
[ -z "$SAVE_DIR_HDB" ] && SAVE_DIR_HDB=$SAVE_DIR || :
|
|
set -u
|
|
|
|
[ ! -d $SAVE_DIR_HDB ] && mkdir -p $SAVE_DIR_HDB || :
|
|
|
|
[ -n "$HDB" ] && {
|
|
[ ! -e "$SAVE_DIR_HDB/$HDB" ] && {
|
|
[ -n "$HDB_SIZE" ] && {
|
|
#echo -n "Create HDB ($HDB_SIZE) : $SAVE_DIR_HDB/$HDB... "
|
|
dd of=$SAVE_DIR_HDB/$HDB count=0 bs=1M seek=$HDB_SIZE
|
|
#echo "done."
|
|
}
|
|
}
|
|
DISK_OPTS="$DISK_OPTS -drive file=$SAVE_DIR_HDB/$HDB,if=$KVM_DISK_MODEL,format=raw"
|
|
NB_DISK=$(($NB_DISK+1))
|
|
}
|
|
|
|
[ -n "$CDROM" ] && {
|
|
[ ! -e "$VDN_PATH/files/$CDROM" ] && {
|
|
warning "Cdrom \"$CDROM\" not found !"
|
|
} || {
|
|
DISK_OPTS="-boot order=$boot_order $DISK_OPTS -drive file=$VDN_PATH/files/$CDROM,media=cdrom"
|
|
#NB_DISK=$(($NB_DISK+1)) # /dev/cdrom -> /dev/sr0
|
|
}
|
|
}
|
|
|
|
prepareSwap
|
|
|
|
if [ $KVM_USB_DEVICE_TABLET = 1 ]; then
|
|
KVM_OPTS="$KVM_OPTS -usbdevice tablet"
|
|
fi
|
|
|
|
case $KVM_VIEWER in
|
|
no) KVM_OPTS="$KVM_OPTS -nographic";;
|
|
sdl) ;;
|
|
vnc) ;;
|
|
esac
|
|
|
|
case "$EMULATOR" in
|
|
kvm) [ -w /dev/kvm ] && {
|
|
KVM_OPTS="-enable-kvm -cpu host $KVM_OPTS"
|
|
cpu=$(getconf _NPROCESSORS_ONLN)
|
|
KVM_OPTS="-smp $cpu $KVM_OPTS"
|
|
}
|
|
EMULATOR=qemu-system-x86_64
|
|
|
|
;;
|
|
qemu) KVM_OPTS="-smp 1 $KVM_OPTS"
|
|
EMULATOR=qemu-system-x86_64
|
|
;;
|
|
esac
|
|
|
|
#echo "MODE: beforeStart : $MODE"
|
|
case $MODE in
|
|
tgz|overlay|tgz2) startKvmTgz; r=$?;;
|
|
direct|cow) startKvmDirectOrCow; r=$?;;
|
|
*) error "Mode $MODE not available"
|
|
esac
|
|
|
|
return $r
|
|
|
|
}
|
|
|
|
quit() {
|
|
echo ""
|
|
#echo "*** $GUEST_NAME stopped !"
|
|
#echo "Wait return before rm files !"
|
|
#read
|
|
#rm -Rf $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-*
|
|
}
|
|
|
|
# Programme principal
|
|
|
|
echo "vdn-start $@"
|
|
|
|
VDN_PATH=$(readlink -f $(dirname $0)/..); . $VDN_PATH/bin/functions.sh
|
|
|
|
args "$@"
|
|
|
|
myLocalHostname=$(hostname)
|
|
|
|
if [ "$myLocalHostname" = "tokyo" -o "$myLocalHostname" = "iutclinfvm01l" ]; then
|
|
echo "Lancer des VM sur $myLocalHostname n'est ni autorisé ni judicieux !" >&2
|
|
echo "Allez sur une machine de TP (commande scan-dept pour lister celles allumées) !" >&2
|
|
exit 9
|
|
fi
|
|
|
|
set +u
|
|
[ "$VDN_DEBUG" = "1" ] && set -x || :
|
|
set -u
|
|
|
|
#verifIdent || exit 2
|
|
|
|
export HOSTS=""
|
|
|
|
setGuestVars $GUEST_NAME
|
|
|
|
GUEST_OWNER=$USER
|
|
|
|
DIRECT=0
|
|
|
|
loadGuestVars $GUEST_NAME
|
|
|
|
#if ! /sbin/route -n | grep -q '0.0.0.0' ; then
|
|
if ! /sbin/ip route | grep -q default; then
|
|
error "Pas de route par défaut ! Consultez la FAQ"
|
|
fi
|
|
|
|
AUFS_OPTS=""
|
|
|
|
NB_ETH=`echo $NETWORKS | wc -w`
|
|
|
|
|
|
testIfAlreadyStarted
|
|
|
|
|
|
# Délègue à interface graphique
|
|
|
|
set +u
|
|
[ -z "$WITH_GUI" ] && export WITH_GUI=0
|
|
[ -z "$VDN_GUI" ] && export VDN_GUI=0
|
|
set -u
|
|
|
|
if [ $GUI = 1 ]; then
|
|
if ps auwx | grep -v grep | grep -q 'ruby.*vdn-gui' ; then
|
|
sendToGui "start $GUEST_NAME $EXPR"
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
set +u
|
|
if [ ! -e $VDN_PATH/files/$INITRAMFS_PATH ]; then
|
|
if [ $MODE = "tgz" -o $MODE = "overlay" -o $MODE = "tgz2"]; then
|
|
error "Impossible de trouver : $INITRAMFS_PATH"
|
|
fi
|
|
fi
|
|
set -u
|
|
|
|
|
|
export MOUNT_ROOT_PATH="$VDN_PATH/distribs/guests/$GUEST_SYS/mount-root"
|
|
|
|
#echo
|
|
#echo "*** Start $GUEST_NAME ($EMULATOR)"
|
|
#echo
|
|
|
|
|
|
trap quit 0
|
|
|
|
[ -z "$EMULATOR" ] && EMULATOR="kvm"
|
|
|
|
case "$EMULATOR" in
|
|
kvm|qemu*)
|
|
#EXCLUDE_SERVICES=""
|
|
#echo "Start kvm..."
|
|
startKvm
|
|
r=$?;;
|
|
|
|
*) echo "L'émulateur $EMULATOR n'est pas supporté !" >&2; exit 2;;
|
|
esac
|
|
|
|
exit $r
|
|
|