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.
569 lines
12 KiB
569 lines
12 KiB
#!/usr/bin/env bash
|
|
|
|
# FOR DEBUG : tmux kill-session -t name
|
|
|
|
# Options prédéfinies pour ssh lors d'un vdn-ssh.
|
|
|
|
set +u
|
|
[ -z "$USER" ] && export USER=$(id -un)
|
|
set -u
|
|
|
|
set -a
|
|
VDN_RESOURCES_ALLOCATOR=${VDN_RESOURCES_ALLOCATOR:-default}
|
|
DB_CURRENT_HOST=${DB_CURRENT_USER:-$USER}
|
|
DB_CURRENT_HOST=${DB_CURRENT_NETWORK:-}
|
|
DB_CURRENT_HOST=${DB_CURRENT_HOST:-}
|
|
set +a
|
|
|
|
#SSH_OPTS="-o NoHostAuthenticationForLocalhost=yes -c aes128-ctr"
|
|
SSH_OPTS="-o NoHostAuthenticationForLocalhost=yes"
|
|
|
|
# Options prédéfinies pour scp lors d'un vdn-scp.
|
|
|
|
SCP_OPTS="-o NoHostAuthenticationForLocalhost=yes -c aes128-ctr"
|
|
|
|
# Utilise le mode master de ssh pour la connexion avec les systèmes virtuels.
|
|
|
|
SSH_GUEST_MASTER=1
|
|
|
|
#set +u
|
|
#[ -z "$PAUSE" ] && export PAUSE=1 || :
|
|
#set -u
|
|
|
|
|
|
warning() {
|
|
echo -e "\n`basename $0` : warning : $@ !" >&2
|
|
}
|
|
|
|
error() {
|
|
echo -e "`basename $0` : error : $@ !" >&2
|
|
READ_ON_ERROR=${READ_ON_ERROR:-0}
|
|
|
|
if [ "$READ_ON_ERROR" = "1" ]; then
|
|
echo "Appuyez sur Entrée pour quitter"
|
|
read
|
|
fi
|
|
exit 64
|
|
}
|
|
|
|
request() {
|
|
echo
|
|
echo -e "$@"
|
|
echo
|
|
echo -n "Confirmez (O/n) : "
|
|
read
|
|
if [ -z "$REPLY" -o "$REPLY" = "o" -o "$REPLY" = "O" ]; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
requestNo() {
|
|
echo
|
|
echo -e "$@"
|
|
echo
|
|
echo -n "Confirmez (o/N) : "
|
|
read
|
|
if [ "$REPLY" = "o" -o "$REPLY" = "O" ]; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
testInstallDebian() {
|
|
local notFound=0
|
|
#local bin="lsb_release qemu-system-x86_64 neato bzip2 wget"
|
|
local bin="lsb_release bzip2 wget"
|
|
|
|
for i in $bin; do
|
|
if ! whereis $i | grep -q bin; then
|
|
echo "Impossible de trouver l'exécutable : $i !"
|
|
notFound=1
|
|
fi
|
|
done
|
|
|
|
if [ $notFound = 1 ]; then
|
|
request "Programme(s) manquant(s) !\nL'administrateur doit préparer le système via la commande :\nvdn-prepare-debian\nAbandonner le démarrage de VDN ?"
|
|
if [ $? -eq 0 ]; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
computeHostRelease() {
|
|
|
|
set +u
|
|
[ -n "$HOST_RELEASE" ] && return || :
|
|
set -u
|
|
|
|
if [ -e /usr/lib/os-release ]; then
|
|
ID=$(cat /usr/lib/os-release | grep '^ID=' | cut -d '=' -f 2)
|
|
if [ -z "$ID" ]; then
|
|
ID="empty"
|
|
fi
|
|
VERSION_CODENAME=$(cat /usr/lib/os-release | grep '^VERSION_CODENAME=' | cut -d '=' -f 2)
|
|
if [ -z "$VERSION_CODENAME" ]; then
|
|
VERSION_CODENAME="empty"
|
|
fi
|
|
|
|
export HOST_RELEASE="$ID/$VERSION_CODENAME"
|
|
|
|
else
|
|
export HOST_RELEASE="empty/empty"
|
|
fi
|
|
}
|
|
|
|
|
|
# Fixe GUEST_PATH, GUEST_CONF et GUEST_SAVE
|
|
# $1 : GUEST_NAME
|
|
setGuestVars() {
|
|
set -a
|
|
MODE=tgz
|
|
GUEST_OWNER=$USER
|
|
GUEST_NAME=$1
|
|
GUEST_PATH="$NETWORK_DIR"
|
|
GUEST_CONF="$GUEST_PATH/$1.conf"
|
|
#if [ ! -e "$GUEST_CONF" ]; then
|
|
# error "WARNING : Le système $(basename $NETWORK_DIR)/$1 n'existe pas !"
|
|
#fi
|
|
##NETWORK="$(basename $NETWORK_DIR)"
|
|
#IDENT=""
|
|
#IDENT=$(grep '^IDENT=[0-9]' $GUEST_CONF | \
|
|
# sed -re 's/^.*IDENT=([0-9]+).*/\1/')
|
|
#[ -z "$IDENT" ] && error "IDENT n'est pas fixé dans $GUEST_CONF" || :
|
|
|
|
SSH_IDENTITY="$HOME/.ssh/id_dsa.pub $HOME/.ssh/id_rsa.pub"
|
|
SWAP_FILE="$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-swap"
|
|
|
|
# fichier utilisé pour la partition de l'union.
|
|
# si fixée à "" alors un tmpfs est utilisé
|
|
|
|
AUFS_FILE="$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-part"
|
|
OUT_FILE="$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-out"
|
|
|
|
ALIVE_FILE=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER.alive
|
|
|
|
EXCLUDE_SERVICES=""
|
|
|
|
KVM_NETWORKS_OPTS=""
|
|
KVM_DISKS_OPTS=""
|
|
KVM_OPTS=""
|
|
KVM_CMD=""
|
|
NET_MODEL=${NET_MODEL:-ne2k_pci}
|
|
|
|
set +u
|
|
[ -n "$EXPR" -a "$EXPR" != '[]' ] && {
|
|
eval "$EXPR"
|
|
}
|
|
set -u
|
|
|
|
set +a
|
|
}
|
|
|
|
loadGuestVars() {
|
|
setGuestVars $1
|
|
computeNetworks
|
|
. $VDN_PATH/config.template
|
|
[ -e $VDN_PATH/config.template.local ] && . $VDN_PATH/config.template.local || :
|
|
. $GUEST_CONF
|
|
set -a
|
|
set +u
|
|
[ -n "$EXPR" -a "$EXPR" != '[]' ] && {
|
|
eval "$EXPR"
|
|
}
|
|
set -u
|
|
set +a
|
|
|
|
case "$MODE" in
|
|
tgz|tgz2)
|
|
SAVE_FILE="$SAVE_DIR/$GUEST_NAME.tgz"
|
|
;;
|
|
overlay)
|
|
#SAVE_FILE="$SAVE_DIR/$GUEST_NAME.tgz"
|
|
SAVE_FILE="$SAVE_DIR/$GUEST_NAME.overlay"
|
|
;;
|
|
*)
|
|
SAVE_FILE="$SAVE_DIR/$GUEST_NAME.cow"
|
|
;;
|
|
esac
|
|
|
|
[ ! -d "$(dirname $SAVE_FILE)" ] && mkdir -p "$(dirname $SAVE_FILE)" || :
|
|
}
|
|
|
|
# retourne 0 (vrai) si le système existe
|
|
|
|
isDefined() {
|
|
GUEST_PATH="$NETWORK_DIR"
|
|
GUEST_CONF="$GUEST_PATH/$1.conf"
|
|
test -e "$GUEST_CONF"
|
|
return $?
|
|
}
|
|
|
|
resizeMultipleOf512() {
|
|
local s=$(stat -c %s $1)
|
|
local n=$(( (($s/512)+($s%512!=0)*1)*512 ))
|
|
#echo "s=$s, n=$n"
|
|
truncate -s $n $1
|
|
}
|
|
|
|
debugNet1() {
|
|
set +u
|
|
[ -z "$DEBUG_NET" ] && export DEBUG_NET="false"
|
|
set -u
|
|
echo "debugNet1 host:$KHOST K:$K K_HIGH:$K_HIGH K_LOW:$K_LOW U:$U U1:$U_LOW U2:$U_HIGH" >&2
|
|
}
|
|
|
|
computeNetworksOld() {
|
|
|
|
local K U i
|
|
|
|
set +u
|
|
ident=$1
|
|
set -u
|
|
|
|
[ -z "$ident" ] && ident=$IDENT || :
|
|
|
|
# Configuration des réseaux (brins Ethernet, adresse IP et adresses MAC)
|
|
|
|
# Ce fichier est lu avant la lecture du fichier de configuration d'un
|
|
# système et est utilisé pour définir les réseaux (virtuels).
|
|
# Lorsque ce fichier est lu, la variable IDENT contenant
|
|
# l'identificateur du système à démarrer est fixée.
|
|
|
|
# ###
|
|
# 1. Calcule les adresses "multicast" des brins Ethernet virtuels.
|
|
# ###
|
|
|
|
# Détermine la clé propre à chaque utilisateur.
|
|
# Remarque : conflit si même poids faible de l'UID.
|
|
|
|
U=$(($(id -u)%512))
|
|
|
|
# !!!
|
|
#[ "$USER" = gudavala ] && U=511
|
|
|
|
U_LOW=$(($U%256))
|
|
U_HIGH=$(($U/256))
|
|
|
|
|
|
# Détermine la clé K propre à la machine hôte (poids faible de l'IP)
|
|
|
|
#K=`/sbin/ifconfig eth0 | grep Bcast | head -n 1 | cut -d ':' -f 2 | \
|
|
# cut -d ' ' -f 1 | cut -d '.' -f 4`A
|
|
|
|
IP_LINE=$(ip addr | grep '192\.168' | head -n 1)
|
|
#IP_LINE=$(echo " inet 192.168.1.37/24 brd 192.168.1.255 scope global dynamic eth0" | grep '192\.168' | head -n 1)
|
|
|
|
K=$(echo $IP_LINE | sed -re 's/.*192\.168\.([0-9]+)\.([0-9]+)\/.*$/\1 \2/')
|
|
|
|
|
|
#IP_LINE=$(echo " inet 192.168.1.37/24 brd 192.168.1.255 scope global dynamic eth0" | grep '192\.168' | head -n 1)
|
|
|
|
K=$(echo $IP_LINE | sed -re 's/.*192\.168\.([0-9]+)\.([0-9]+)\/.*$/\1 \2/')
|
|
|
|
[ -z "$K" ] && {
|
|
echo "Warning : can't find network host uniq number ! use "1" !"
|
|
K=1
|
|
}
|
|
|
|
#KK=""
|
|
#if [ -e $NETWORK_DIR/hosts.txt ]; then
|
|
# local h=$(hostname)
|
|
# h=$(echo $h | sed -re 's/iutclinf(.*)l/\1/')
|
|
# KK=$(cat $NETWORK_DIR/hosts.txt | grep -n $h | cut -d ':' -f 1)
|
|
# [ -n "$k2" ] && K=$K_LOW
|
|
#fi
|
|
#echo "KEY:$K K_LOW=$KK"
|
|
|
|
|
|
K_HIGH=$(echo $K | cut -d ' ' -f 1)
|
|
K_LOW=$(echo $K | cut -d ' ' -f 2)
|
|
|
|
KHOST=$K_LOW
|
|
[ "$K_HIGH" = "128" ] && KHOST=$((512+$K_LOW))
|
|
|
|
[ $K_HIGH = 128 ] && K_HIGH=1 || K_HIGH=0
|
|
|
|
#K_HIGH=$(($K_HIGH%16))
|
|
K_LOW=$(($K_LOW%256))
|
|
|
|
set +u
|
|
#[ "$USER" = "gudavala" ] && [ -z "$VDN_FIRST" ] && debugNet1
|
|
set -u
|
|
|
|
set -a
|
|
|
|
# Brin Ethernet PARTAGÉ par TOUS les systèmes de TOUS les utilisateurs.
|
|
# [Internet virtuel]
|
|
|
|
NET_G="239.2.0.0:1999"
|
|
|
|
# Brins privés à une machine hôte
|
|
|
|
for i in `seq 0 64`; do
|
|
eval NET_$i="234.$K_HIGH.$K_LOW.$U_LOW:$((2000+$U*16+$i))"
|
|
done
|
|
|
|
# ###
|
|
# 2. Calcule l'adresse IP "réservée" sur le brin PARTAGÉ
|
|
# ###
|
|
|
|
###PUBLIC_IP="$((20+$K_HIGH+U_HIGH*2)).$K_LOW.$U_LOW.$ident"
|
|
|
|
#set -x
|
|
PUBLIC_IP=$(vdn-query PUBLIC_IP 0 $GUEST_NAME.$NETWORK_NAME)
|
|
#set +x
|
|
|
|
# ###
|
|
# 3. Calcule les adresses MAC des cartes Ethernet
|
|
# ###
|
|
|
|
U_LOW=`printf "%02X" $U_LOW`
|
|
|
|
V=$((54+$K_HIGH+$U_HIGH*2))
|
|
V=$(printf "%02d" $V)
|
|
K_HIGH=`printf "%02X" $K_HIGH`
|
|
K_LOW=`printf "%02X" $K_LOW`
|
|
|
|
|
|
|
|
F_IDENT=$(printf "%02d" $ident)
|
|
|
|
MAC_0=52:$V:$K_LOW:$U_LOW:$F_IDENT:00
|
|
MAC_1=52:$V:$K_LOW:$U_LOW:$F_IDENT:01
|
|
MAC_2=52:$V:$K_LOW:$U_LOW:$F_IDENT:02
|
|
MAC_3=52:$V:$K_LOW:$U_LOW:$F_IDENT:03
|
|
MAC_4=52:$V:$K_LOW:$U_LOW:$F_IDENT:04
|
|
MAC_5=52:$V:$K_LOW:$U_LOW:$F_IDENT:05
|
|
MAC_6=52:$V:$K_LOW:$U_LOW:$F_IDENT:06
|
|
MAC_7=52:$V:$K_LOW:$U_LOW:$F_IDENT:07
|
|
|
|
set +a
|
|
}
|
|
|
|
computeNetworks() {
|
|
|
|
set -a
|
|
# NET_G ?
|
|
# NET_ ?
|
|
|
|
#PUBLIC_IP=$(vdn-query PUBLIC_IP 0 $GUEST_NAME.$NETWORK_NAME)
|
|
|
|
# MAC_ ?
|
|
}
|
|
|
|
# "Calcule" le port utilisé pour une redirection (interface pour la connexion
|
|
# avec l'hôte).
|
|
# En unique argument, le port de la machine virtuelle à rediriger vers un port
|
|
# local. En sortie, affichage du port "théorique" pour la redirection.
|
|
# En pratique le premier port libre égal ou supérieur au port "théorique" sera
|
|
# utilisé.
|
|
|
|
vdn_redirOld() {
|
|
echo $((5000+100*$IDENT+$1))
|
|
}
|
|
|
|
getIpNotUsed() {
|
|
name=$1
|
|
eth=$2
|
|
|
|
#vdn-infos $name >&2
|
|
local nets=$(vdn-infos $name | grep '^NETWORKS=' | sed -re 's/^NETWORKS=//')
|
|
local ip=$(echo $nets | cut -d ' ' -f $((eth+1)) | cut -d '#' -f 2 | sed -re 's/^[^0-9]*([0-9.]+).*$/\1/')
|
|
|
|
echo $ip
|
|
}
|
|
|
|
# Vérifie l'unicité des identificateurs des systèmes du réseau courant.
|
|
|
|
verifIdentOld() {
|
|
local i=0
|
|
local configs="`find $NETWORK_DIR -follow -type f -name \"*.conf\" 2> /dev/null`"
|
|
[ -n "$configs" ] || return 0
|
|
l=$(grep -E '^[[:space:]]*IDENT=[0-9]+' $configs | \
|
|
sed -re 's,^.*/([^/]*)/config:[[:space:]]*IDENT=([0-9]+).*$,\1:\2,' | sort -n -t : -k 2)
|
|
|
|
local t
|
|
|
|
for i in $l; do
|
|
name=$(echo $i | cut -d ':' -f 1)
|
|
ident=$(echo $i | cut -d ':' -f 2)
|
|
set +u
|
|
t[$ident]="${t[$ident]},$name"
|
|
set -u
|
|
done
|
|
|
|
local found=0
|
|
for i in ${t[*]}; do
|
|
l=$(echo $i | sed -re 's/^,//')
|
|
if echo $l | grep -q ','; then
|
|
n=$(echo $l | cut -d ',' -f 1)
|
|
ident=$(vdn-config $n IDENT)
|
|
echo "Erreur : l'identificateur $ident est partagé par $l !"
|
|
found=1
|
|
fi
|
|
done
|
|
|
|
return $found
|
|
|
|
|
|
}
|
|
|
|
|
|
# Démarre un ssh pour un système virtuel en mode "master"
|
|
sshGuestControlMaster() {
|
|
Login=${LOGIN}localhost
|
|
|
|
# wait lock
|
|
local n=0
|
|
local lock=$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-ssh-lock
|
|
while ! mkdir $lock 2> /dev/null; do
|
|
sleep 0.5
|
|
# Securité
|
|
n=$(($n+1))
|
|
if [ $n -gt 5 ]; then
|
|
rmdir $lock 2> /dev/null || :
|
|
fi
|
|
done
|
|
|
|
sleep 0.1
|
|
|
|
#echo "Locked"
|
|
|
|
#echo "Login:$Login" >&2
|
|
#ps auwx > /tmp/p
|
|
#ps auwx | grep -v grep | grep $Login | grep -q -- "-N -M" > /tmp/o || :
|
|
local sign="$TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest"
|
|
test="ps auwx | grep -v grep | grep $Login | grep $sign"
|
|
#[ $GUEST_OWNER = gudavala ] && echo "test:$test"
|
|
if ! ps auwx | grep -v grep | grep $Login | grep $sign | grep -q -- "-N -M"; then
|
|
rmdir $lock 2> /dev/null || :
|
|
#[ $GUEST_OWNER = gudavala ] && echo "Master... $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest"
|
|
ssh -g $Login $SSH_OPTS $@ -o ServerAliveInterval=5 -p $SSH_REDIR_PORT -X -f -n -N -M -S $TMPDIR/vdn-$GUEST_NAME-$GUEST_OWNER-guest-%r@%h:%p &> /dev/null
|
|
else
|
|
rmdir $lock 2> /dev/null || :
|
|
fi
|
|
|
|
}
|
|
|
|
findUnusedPort() {
|
|
# $1 : proto
|
|
# $2 : port
|
|
|
|
local proto port dst hex proc
|
|
|
|
proto=$1
|
|
port=$2
|
|
|
|
|
|
hex=`printf "%04X" $port`
|
|
proc="/proc/net/$proto"
|
|
|
|
while cat $proc | cut -d : -f2- | cut -d ' ' -f2,3 | grep -q ":$hex"; do
|
|
#echo "$proto port $port (for $dst) is used ! find next !" >&2
|
|
port=$(($port+1))
|
|
hex=`printf "%04X" $port `
|
|
done
|
|
|
|
echo $port
|
|
}
|
|
|
|
|
|
|
|
setEnv() {
|
|
|
|
set +u
|
|
local save="$NETWORK_DIR"
|
|
set -u
|
|
set -a
|
|
|
|
. $VDN_PATH/config.rc # ! set NETWORK_DIR
|
|
[ -e $VDN_PATH/config.rc.local ] && . $VDN_PATH/config.rc.local || :
|
|
|
|
|
|
# NETWORK_DIR priority
|
|
|
|
if [ -n "$save" ]; then
|
|
NETWORK_DIR=$save
|
|
fi
|
|
|
|
set +a
|
|
|
|
set +u
|
|
[ -z "$EDITOR" ] && export EDITOR="vi"
|
|
set -u
|
|
|
|
export HOST_RELEASE
|
|
|
|
export VDN_WS_PROXY_SOCKET=$TMPDIR/vdn-$USER-ws-sock
|
|
}
|
|
|
|
vdn_init() {
|
|
|
|
export VDN_NETWORKS_BASE_DIR=${VDN_NETWORKS_BASE_DIR:-$VDN_PATH/networks}
|
|
set +u
|
|
CURRENT_NETWORK_DIR="$NETWORK_DIR" # var. d'env. prioritaire
|
|
|
|
NETWORK_NAME=""
|
|
[ -n "$CURRENT_NETWORK_DIR" ] && NETWORK_NAME=$(basename $CURRENT_NETWORK_DIR)
|
|
|
|
#[ -z "$NETWORK_NAME" ] && error "NETWORK_NAME empty !"
|
|
set -u
|
|
|
|
PATH="$PATH:$VDN_PATH/bin"
|
|
setEnv
|
|
|
|
set -a
|
|
[ ! -e "$TMPDIR" ] && (umask 077 && mkdir -p "$TMPDIR" )
|
|
[ -n "$CURRENT_NETWORK_DIR" ] && NETWORK_DIR="$CURRENT_NETWORK_DIR"
|
|
|
|
set +u
|
|
if [ -n "$NETWORK_DIR" ]; then
|
|
if [ ! -d "$NETWORK_DIR" ]; then
|
|
#echo "Le réseau $NETWORK_DIR n'existe pas !" >&2 || :
|
|
NETWORK_DIR=""
|
|
SAVE_DIR=""
|
|
#exit 1
|
|
|
|
fi
|
|
if [ "$NETWORK_DIR" != "" ]; then
|
|
. $NETWORK_DIR/network.vdn
|
|
SAVE_DIR="$SAVE_PATH/$(basename $NETWORK_DIR)"
|
|
fi
|
|
else
|
|
SAVE_DIR=""
|
|
fi
|
|
|
|
set -u
|
|
set +a
|
|
|
|
set +u
|
|
[ -z "$VDN_DEBUG" ] && export VDN_DEBUG=0 || :
|
|
set -u
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
sendToGui() {
|
|
local pid=$(ps auwx | grep 'ruby' | grep 'vdn-gui' | tr -s " " | cut -d ' ' -f 2)
|
|
if [ -n "$pid" ]; then
|
|
#echo "SENDTOGUI ($TMPDIR/vdn-gui-$USER-fifo-ctrl) : $@"
|
|
echo "$@" > $TMPDIR/vdn-gui-$USER-fifo-ctrl
|
|
fi
|
|
}
|
|
|
|
# main
|
|
|
|
set +u
|
|
[ -z "$VDN_PATH" ] && export VDN_PATH=$(readlink -f $(dirname $0)/..) || :
|
|
! echo "$PATH" | grep -q $VDN_PATH && export PATH="$VDN_PATH/bin:$PATH"
|
|
set -u
|
|
|
|
computeHostRelease
|
|
|
|
setEnv
|
|
|
|
vdn_init
|