ssh first try
This commit is contained in:
parent
eb5e16f585
commit
b224a88e7d
111
nlvmi
111
nlvmi
|
@ -5,13 +5,23 @@ source /etc/nlvmi/nlvmi.conf
|
||||||
if [ $LOGLEVEL -gt "1" ]; then echo "configuration loaded"; fi
|
if [ $LOGLEVEL -gt "1" ]; then echo "configuration loaded"; fi
|
||||||
|
|
||||||
#checking directories
|
#checking directories
|
||||||
echo $VMDIRECTORY | while read line; do IFS='|' read -r -a array
|
#echo $VMDIRECTORY | while read line; do IFS='|' read -r -a array
|
||||||
for dir in "${array[@]}"; do
|
# for dir in "${array[@]}"; do
|
||||||
if [ ! -d $dir ]; then echo "VMDIRECTORY wrong, $dir does not exist"; exit 1; fi
|
# if [ ! -d $dir ]; then echo "VMDIRECTORY wrong, $dir does not exist"; exit 1; fi
|
||||||
done
|
# done
|
||||||
done <<< "$line"
|
#done <<< "$line"
|
||||||
|
|
||||||
if [ ! -d $RUNDIRECTORY ]; then if [ $LOGLEVEL -gt "1" ]; then echo "creating $RUNDIRECTORY"; fi; mkdir -p $RUNDIRECTORY; fi
|
#check if we are root and wrap if we are not
|
||||||
|
U=`/usr/bin/whoami`
|
||||||
|
if [ $U != "root" ]; then
|
||||||
|
if [ ! -z $1 ]; then A=$1; else A="bla"; fi
|
||||||
|
if [ ! -z $2 ]; then B=$2; else B="bla"; fi
|
||||||
|
if [ ! -z $3 ]; then C=$3; else C="bla"; fi
|
||||||
|
/usr/bin/wrap-nlvmi $A $B $C && exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ ! -d $RUNDIRECTORY ]; then if [ $LOGLEVEL -gt "1" ]; then echo "creating $RUNDIRECTORY"; fi; mkdir -p $RUNDIRECTORY; chown root:nlvmi -R $RUNDIRECTORY; fi
|
||||||
|
|
||||||
#checking database
|
#checking database
|
||||||
function checkdb {
|
function checkdb {
|
||||||
|
@ -35,14 +45,6 @@ echo "sqlite ready to use";
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#check if we are root and wrap if we are not
|
|
||||||
U=`/usr/bin/whoami`
|
|
||||||
if [ $U != "root" ]; then
|
|
||||||
if [ ! -z $1 ]; then A=$1; else A="bla"; fi
|
|
||||||
if [ ! -z $2 ]; then B=$2; else B="bla"; fi
|
|
||||||
if [ ! -z $3 ]; then C=$3; else C="bla"; fi
|
|
||||||
/usr/bin/wrap-nlvmi $A $B $C && exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
#creating database
|
#creating database
|
||||||
function createdb {
|
function createdb {
|
||||||
|
@ -80,7 +82,7 @@ function createdb {
|
||||||
brdev3 VARCHAR(50),
|
brdev3 VARCHAR(50),
|
||||||
vncport INTEGER,
|
vncport INTEGER,
|
||||||
websocket INTEGER,
|
websocket INTEGER,
|
||||||
vncpasswort VARCHAR(50)
|
vncpassword VARCHAR(50)
|
||||||
);"
|
);"
|
||||||
sqlite3 $SQLITEFILE "CREATE TABLE users (
|
sqlite3 $SQLITEFILE "CREATE TABLE users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
@ -88,6 +90,14 @@ function createdb {
|
||||||
password VARCHAR(255),
|
password VARCHAR(255),
|
||||||
admin INTEGER
|
admin INTEGER
|
||||||
);"
|
);"
|
||||||
|
sqlite3 $SQLITEFILE "CREATE TABLE servers (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
hostname VARCHAR(50) NOT NULL,
|
||||||
|
connectstring VARCHAR(50),
|
||||||
|
vmdirectory VARCHAR(255),
|
||||||
|
isodirectory VARCHAR(255)
|
||||||
|
);"
|
||||||
|
|
||||||
chown -R nobody $SQLITEFILE
|
chown -R nobody $SQLITEFILE
|
||||||
fi
|
fi
|
||||||
checkdb && echo "DB creation successful!" || (echo "Failed to create the DB"; exit 1)
|
checkdb && echo "DB creation successful!" || (echo "Failed to create the DB"; exit 1)
|
||||||
|
@ -108,44 +118,49 @@ function vmautostart {
|
||||||
function vmstart {
|
function vmstart {
|
||||||
if [ -z $1 ]; then echo "function start needs an id!"; exit 1; fi
|
if [ -z $1 ]; then echo "function start needs an id!"; exit 1; fi
|
||||||
if [ $LOGLEVEL -gt "1" ]; then echo "startvm function entered for vmid $1"; fi
|
if [ $LOGLEVEL -gt "1" ]; then echo "startvm function entered for vmid $1"; fi
|
||||||
sqlite3 $SQLITEFILE "SELECT * FROM vms WHERE id=$1" | while read line; do
|
sqlite3 $SQLITEFILE "SELECT * FROM vms LEFT JOIN servers on vms.server = servers.hostname WHERE vms.id=$1" | while read line; do
|
||||||
IFS='|' read -r -a array <<< "$line"
|
IFS='|' read -r -a array <<< "$line"
|
||||||
if ! `id -u ${array[2]} &>/dev/null`; then
|
#prepare tmpfile
|
||||||
useradd ${array[2]} -d /run/nlvmi -g nlvmi -M -s /bin/false -G kvm;
|
TMPF=/home/nlvmi/${array[1]}.tmp
|
||||||
if [ $LOGLEVEL -gt "1" ]; then echo "user ${array[2]} created"; fi
|
rm $TMPF &>/dev/null
|
||||||
fi
|
#add user if necessary
|
||||||
if [ -e $RUNDIRECTORY/${array[1]}.* ]; then
|
echo "if ! \`id -u ${array[2]} &>/dev/null\`; then useradd ${array[2]} -d /run/nlvmi -g nlvmi -M -s /bin/false -G kvm; fi" >>$TMPF
|
||||||
if [ $LOGLEVEL -gt "1" ]; then echo "chowning pid and monfiles "; fi
|
#chown mon and pid files
|
||||||
chown ${array[2]}:nlvmi $RUNDIRECTORY/${array[1]}.*
|
echo "if [ -e $RUNDIRECTORY/${array[1]}.mon ] || [ -e $RUNDIRECTORY/${array[1]}.pid ]; then chown ${array[2]}:nlvmi $RUNDIRECTORY/${array[1]}.*; fi" >>$TMPF
|
||||||
fi
|
|
||||||
if [ ! -z ${array[5]} ]; then CPUTYPE="-cpu ${array[5]}"; fi
|
if [ ! -z ${array[5]} ]; then CPUTYPE="-cpu ${array[5]}"; fi
|
||||||
if [ ! -z ${array[6]} ]; then SMP="-smp ${array[6]}"; fi
|
if [ ! -z ${array[6]} ]; then SMP="-smp ${array[6]}"; fi
|
||||||
if [ ! -z ${array[7]} ]; then MEMORY="-m ${array[7]}"; fi
|
if [ ! -z ${array[7]} ]; then MEMORY="-m ${array[7]}"; fi
|
||||||
if [ ! -z ${array[8]} ]; then USBDEV="-usb -device usb-ehci,id=ehci -device usb-${array[8]},bus=usb-bus.0"; fi
|
if [ ! -z ${array[8]} ]; then USBDEV="-usb -device usb-ehci,id=ehci -device usb-${array[8]},bus=usb-bus.0"; fi
|
||||||
if [ ! -z ${array[10]} ]; then CUSTOM="${array[10]}"; fi
|
if [ ! -z ${array[10]} ]; then CUSTOM="${array[10]}"; fi
|
||||||
if [ ! -z ${array[13]} ]; then DRIVE1="-drive file=${array[13]}"; chown ${array[2]}:nlvmi ${array[13]}; fi
|
if [ ! -z ${array[13]} ]; then DRIVE1="-drive file=${array[13]}"; echo "chown ${array[2]}:nlvmi ${array[13]}" >>$TMPF; fi
|
||||||
if [ ! -z ${array[14]} ]; then FORMAT1=",format=${array[14]},if=virtio"; fi
|
if [ ! -z ${array[14]} ]; then FORMAT1=",format=${array[14]},if=virtio"; fi
|
||||||
if [ ! -z ${array[15]} ]; then DRIVE2="-drive file=${array[15]}"; chown ${array[2]}:nlvmi ${array[15]}; fi
|
if [ ! -z ${array[15]} ]; then DRIVE2="-drive file=${array[15]}"; echo "chown ${array[2]}:nlvmi ${array[15]}" >>$TMPF; fi
|
||||||
if [ ! -z ${array[16]} ]; then FORMAT2=",format=${array[16]},if=virtio"; fi
|
if [ ! -z ${array[16]} ]; then FORMAT2=",format=${array[16]},if=virtio"; fi
|
||||||
if [ ! -z ${array[17]} ]; then DRIVE3="-drive file=${array[17]}"; chown ${array[2]}:nlvmi ${array[17]}; fi
|
if [ ! -z ${array[17]} ]; then DRIVE3="-drive file=${array[17]}"; echo "chown ${array[2]}:nlvmi ${array[17]}" >>$TMPF; fi
|
||||||
if [ ! -z ${array[18]} ]; then FORMAT3=",format=${array[18]},if=virtio"; fi
|
if [ ! -z ${array[18]} ]; then FORMAT3=",format=${array[18]},if=virtio"; fi
|
||||||
if [ ! -z ${array[19]} ]; then CDROM="-cdrom ${array[19]}"; fi
|
if [ ! -z ${array[19]} ]; then CDROM="-cdrom ${array[19]}"; fi
|
||||||
if [ ! -z ${array[20]} ]; then TAPDEV1="-netdev tap,ifname=${array[20]},script=no,id=net0"; tunctl -t ${array[20]} -u ${array[2]} && ifconfig ${array[20]} up; fi
|
if [ ! -z ${array[20]} ]; then TAPDEV1="-netdev tap,ifname=${array[20]},script=no,id=net0"; echo "tunctl -t ${array[20]} -u ${array[2]} && ifconfig ${array[20]} up" >>$TMPF; fi
|
||||||
if [ ! -z ${array[21]} ]; then MACADDR1="-net nic,macaddr=${array[21]},model=virtio,netdev=net0"; fi
|
if [ ! -z ${array[21]} ]; then MACADDR1="-net nic,macaddr=${array[21]},model=virtio,netdev=net0"; fi
|
||||||
if [ ! -z ${array[22]} ]; then BRDEV1="${array[22]}"; brctl addif ${array[22]} ${array[20]}; fi
|
if [ ! -z ${array[22]} ]; then BRDEV1="${array[22]}"; echo "brctl addif ${array[22]} ${array[20]}" >>$TMPF; fi
|
||||||
if [ ! -z ${array[23]} ]; then TAPDEV2="-netdev tap,ifname=${array[23]},script=no,id=net0"; tunctl -t ${array[23]} -u ${array[2]} && ifconfig ${array[23]} up; fi
|
if [ ! -z ${array[23]} ]; then TAPDEV2="-netdev tap,ifname=${array[23]},script=no,id=net0"; echo "tunctl -t ${array[23]} -u ${array[2]} && ifconfig ${array[23]} up" >>$TMPF; fi
|
||||||
if [ ! -z ${array[24]} ]; then MACADDR2="-net nic,macaddr=${array[24]},model=virtio,netdev=net0"; fi
|
if [ ! -z ${array[24]} ]; then MACADDR2="-net nic,macaddr=${array[24]},model=virtio,netdev=net0"; fi
|
||||||
if [ ! -z ${array[25]} ]; then BRDEV2="${array[25]}"; brctl addif ${array[25]} ${array[23]}; fi
|
if [ ! -z ${array[25]} ]; then BRDEV2="${array[25]}"; echo "brctl addif ${array[25]} ${array[23]}" >>$TMPF; fi
|
||||||
if [ ! -z ${array[26]} ]; then TAPDEV3="-netdev tap,ifname=${array[26]},script=no,id=net0"; tunctl -t ${array[26]} -u ${array[2]} && ifconfig ${array[26]} up; fi
|
if [ ! -z ${array[26]} ]; then TAPDEV3="-netdev tap,ifname=${array[26]},script=no,id=net0"; echo "tunctl -t ${array[26]} -u ${array[2]} && ifconfig ${array[26]} up" >>$TMPF; fi
|
||||||
if [ ! -z ${array[27]} ]; then MACADDR3="-net nic,macaddr=${array[27]},model=virtio,netdev=net0"; fi
|
if [ ! -z ${array[27]} ]; then MACADDR3="-net nic,macaddr=${array[27]},model=virtio,netdev=net0"; fi
|
||||||
if [ ! -z ${array[28]} ]; then BRDEV3="${array[28]}"; brctl addif ${array[28]} ${array[26]}; fi
|
if [ ! -z ${array[28]} ]; then BRDEV3="${array[28]}"; echo "brctl addif ${array[28]} ${array[26]}" >>$TMPF; fi
|
||||||
if [ ! -z ${array[30]} ]; then WEBSOCK=",websocket=${array[30]}"; else WEBSOCK=""; fi
|
if [ ! -z ${array[30]} ]; then WEBSOCK=",websocket=${array[30]}"; else WEBSOCK=""; fi
|
||||||
if [ ! -z ${array[29]} ]; then VNCPORT="-vnc :${array[29]}$WEBSOCK,password"; fi
|
if [ ! -z ${array[29]} ]; then VNCPORT="-vnc :${array[29]}$WEBSOCK,password"; fi
|
||||||
COMMAND=(su - ${array[2]} -s /bin/bash -c "${array[4]} -enable-kvm $CPUTYPE $MEMORY $SMP -boot ${array[11]} $USBDEV -k ${array[9]} -daemonize $DRIVE1$FORMAT1 $DRIVE2$FORMAT2 $DRIVE3$FORMAT3 $CDROM $MACADDR1 $TAPDEV1 $MACADDR2 $TAPDEV2 $MACADDR3 $TAPDEV3 $VNCPORT $CUSTOM -pidfile $RUNDIRECTORY/${array[1]}.pid -monitor unix:$RUNDIRECTORY/${array[1]}.mon,server,nowait")
|
COMMAND=(su - ${array[2]} -s /bin/bash -c \"${array[4]} -enable-kvm $CPUTYPE $MEMORY $SMP -boot ${array[11]} $USBDEV -k ${array[9]} -daemonize $DRIVE1$FORMAT1 $DRIVE2$FORMAT2 $DRIVE3$FORMAT3 $CDROM $MACADDR1 $TAPDEV1 $MACADDR2 $TAPDEV2 $MACADDR3 $TAPDEV3 $VNCPORT $CUSTOM -pidfile $RUNDIRECTORY/${array[1]}.pid -monitor unix:$RUNDIRECTORY/${array[1]}.mon,server,nowait\")
|
||||||
if [ $LOGLEVEL -gt "1" ]; then echo ${COMMAND[@]}; fi
|
if [ $LOGLEVEL -gt "1" ]; then echo ${COMMAND[@]}; fi
|
||||||
`"${COMMAND[@]}"`
|
echo "${COMMAND[@]}" >>$TMPF
|
||||||
#Set VNC Password
|
#Set VNC Password
|
||||||
echo "change vnc password ${array[31]}" | socat - unix-connect:$RUNDIRECTORY/${array[1]}.mon >/dev/null
|
echo "echo \"change vnc password ${array[31]}\" | socat - unix-connect:$RUNDIRECTORY/${array[1]}.mon >/dev/null" >>$TMPF
|
||||||
|
if [ ! -z "${array[34]}" ]; then
|
||||||
|
su nlvmi -c "scp $TMPF ${array[34]}:/home/nlvmi/"
|
||||||
|
else
|
||||||
|
/bin/bash $TMPF
|
||||||
|
rm $TMPF
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
export VMFOUND="yes"
|
export VMFOUND="yes"
|
||||||
}
|
}
|
||||||
|
@ -187,9 +202,28 @@ function checkvm {
|
||||||
ps -ef | grep `cat $RUNDIRECTORY/$1.pid` | grep -v grep >/dev/null && echo "VM is running" || echo "VM is not running"
|
ps -ef | grep `cat $RUNDIRECTORY/$1.pid` | grep -v grep >/dev/null && echo "VM is running" || echo "VM is not running"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function listdir {
|
||||||
|
#echo $1 $2
|
||||||
|
sqlite3 $SQLITEFILE "SELECT $2,connectstring FROM servers WHERE hostname='$1'" | while read line; do
|
||||||
|
IFS='|' read -r -a array <<< "$line"
|
||||||
|
IFS=';' read -r -a dirs <<< "${array[0]}"
|
||||||
|
# echo ${dirs[1]}
|
||||||
|
# echo ${array[0]}
|
||||||
|
#echo $line
|
||||||
|
for di in ${dirs[@]}; do
|
||||||
|
# echo $di
|
||||||
|
if [ -z ${array[1]} ]; then
|
||||||
|
ls -lrt -d -1 $di/{*,.*}
|
||||||
|
else
|
||||||
|
su nlvmi -c "ssh ${array[1]} \"ls -lrt -d -1 $di/{*,.*}\""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
#mainloop
|
#mainloop
|
||||||
if [ $# -gt 0 ]; then
|
if [ $# -gt 0 ]; then
|
||||||
|
echo $1 $2 $3
|
||||||
if [ $1 == "createdb" ]; then
|
if [ $1 == "createdb" ]; then
|
||||||
createdb
|
createdb
|
||||||
elif [ $1 == "autostart" ]; then
|
elif [ $1 == "autostart" ]; then
|
||||||
|
@ -216,7 +250,6 @@ if [ $# -gt 0 ]; then
|
||||||
IFS='|' read -r -a arrays <<< "$line"
|
IFS='|' read -r -a arrays <<< "$line"
|
||||||
declare VMFOUND="yes"
|
declare VMFOUND="yes"
|
||||||
export "$VMFOUND"
|
export "$VMFOUND"
|
||||||
echo "nana"
|
|
||||||
vmstop $2
|
vmstop $2
|
||||||
done
|
done
|
||||||
if [[ $VMFOUND == "no" ]]; then echo "no VM with that name found!"; exit 1; fi)
|
if [[ $VMFOUND == "no" ]]; then echo "no VM with that name found!"; exit 1; fi)
|
||||||
|
@ -225,6 +258,10 @@ echo "nana"
|
||||||
elif [ $1 == "checkvm" ]; then
|
elif [ $1 == "checkvm" ]; then
|
||||||
if [ -z $2 ]; then echo "checkvm needs a vmname!"; exit 1; fi
|
if [ -z $2 ]; then echo "checkvm needs a vmname!"; exit 1; fi
|
||||||
if [ -e $RUNDIRECTORY/$2.mon ]; then echo $2 running; else echo $2 stopped; fi
|
if [ -e $RUNDIRECTORY/$2.mon ]; then echo $2 running; else echo $2 stopped; fi
|
||||||
|
elif [ $1 == "listdir" ]; then
|
||||||
|
if [ -z $2 ] || [ -z $3 ]; then echo listdir needs two more arguments; exit 1; fi
|
||||||
|
listdir $2 $3
|
||||||
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
checkdb
|
checkdb
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
</div>
|
</div>
|
||||||
<script src="nlvmi.js?3"></script>
|
<script src="nlvmi.js?3"></script>
|
||||||
<div class=container-fluid><div class="row" style="background-color:lightgreen;"><div class="col-sm"><h1><a href="?" style=color:white;>nlvmi</a><a href="?" style="color:black;font-size:10px;">@<?php echo gethostname();?></a></h1></div><div class=col-sm style=text-align:right>
|
<div class=container-fluid><div class="row" style="background-color:lightgreen;"><div class="col-sm"><h1><a href="?" style=color:white;>nlvmi</a><a href="?" style="color:black;font-size:10px;">@<?php echo gethostname();?></a></h1></div><div class=col-sm style=text-align:right>
|
||||||
<?php if($_SESSION['isadmin']==1){ echo "<a style=color:black href=# onclick=\"javascript:post('?', {'usermgmt': 'show'});\">usermanagement</a></br>"; } ?><a style=color:black href=# onclick="javascript:post('?', {'logout': 'logout'});">logout</a></div></div>
|
<?php if($_SESSION['isadmin']==1){ echo "<a style=color:black href=# onclick=\"javascript:post('?', {'usermgmt': 'show'});\">usermanagement</a></br><a style=color:black href=# onclick=\"javascript:post('?', {'servermgmt': 'show'});\">servers</a></br>";} ?>
|
||||||
|
<a style=color:black href=# onclick="javascript:post('?', {'logout': 'logout'});">logout</a></div></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -375,7 +375,7 @@ if (isset($_SESSION['username'])){
|
||||||
echo "<div class=dropdown-menu aria-labelledby=bootoptionbutton>";
|
echo "<div class=dropdown-menu aria-labelledby=bootoptionbutton>";
|
||||||
echo "<a class=dropdown-item href=\"javascript:dropdown('bootoptionbutton','c')\">c</a>";
|
echo "<a class=dropdown-item href=\"javascript:dropdown('bootoptionbutton','c')\">c</a>";
|
||||||
echo "<a class=dropdown-item href=\"javascript:dropdown('bootoptionbutton','d')\">d</a>";
|
echo "<a class=dropdown-item href=\"javascript:dropdown('bootoptionbutton','d')\">d</a>";
|
||||||
echo "</div></div></div></div><input type=hidden id=bootoptionbuttonh name=bootoption value=c>";
|
echo "</div></div></div></div><input type=hidden id=bootoptionbuttonh name=bootoption value=$val>";
|
||||||
// echo "$arrColnames[$col] <select name=bootoption><option value=c>C</option><option value=d>D</option></select></br>";
|
// echo "$arrColnames[$col] <select name=bootoption><option value=c>C</option><option value=d>D</option></select></br>";
|
||||||
} elseif ($arrColnames[$col] == "user"){
|
} elseif ($arrColnames[$col] == "user"){
|
||||||
if ($val=="") {
|
if ($val=="") {
|
||||||
|
@ -388,7 +388,7 @@ if (isset($_SESSION['username'])){
|
||||||
while ($rowusers = $resusers->fetchArray(SQLITE3_ASSOC)){
|
while ($rowusers = $resusers->fetchArray(SQLITE3_ASSOC)){
|
||||||
echo "<a class=dropdown-item href=\"javascript:dropdown('userbutton','$rowusers[username]')\">$rowusers[username]</a>";
|
echo "<a class=dropdown-item href=\"javascript:dropdown('userbutton','$rowusers[username]')\">$rowusers[username]</a>";
|
||||||
}
|
}
|
||||||
echo "</div></div></div><input type=hidden id=userbuttonh name=user value=$_SESSION[username]></div>";
|
echo "</div></div></div><input type=hidden id=userbuttonh name=user value=$val></div>";
|
||||||
} elseif ($arrColnames[$col] == "arch"){
|
} elseif ($arrColnames[$col] == "arch"){
|
||||||
echo "<div class=row><div class=col-md-1 style=text-align:right>arch</div><div class=col-md-2><div class=dropdown><button class=\"btn btn-secondary dropdown-toggle\" type=button id=archbutton data-toggle=dropdown aria-haspopup=true aria-expanded=false>x86_64</button>";
|
echo "<div class=row><div class=col-md-1 style=text-align:right>arch</div><div class=col-md-2><div class=dropdown><button class=\"btn btn-secondary dropdown-toggle\" type=button id=archbutton data-toggle=dropdown aria-haspopup=true aria-expanded=false>x86_64</button>";
|
||||||
echo "<div class=dropdown-menu aria-labelledby=archbutton>";
|
echo "<div class=dropdown-menu aria-labelledby=archbutton>";
|
||||||
|
|
Loading…
Reference in New Issue