blob: f9cbc30cf2f334999b9c1a8d048d509a52472209 [file] [log] [blame] [raw]
#!/bin/bash
# Copyright (C) 2000-2009, Parallels, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Set the sane umask
umask 022
CP='/bin/cp -fp'
# overwrite copy arguments as a workaround for FC5 bug #190601 (ovz bug #297)
[ -f /etc/fedora-release ] && CP='/bin/cp -f --preserve=mode,ownership'
# Error codes
VZ_INVALID_PARAMETER_SYNTAX=20
VZ_FS_NO_DISK_SPACE=46
VZ_FS_BAD_TMPL=47
VZ_FS_NEW_VE_PRVT=48
VZ_CHANGEPASS=74
VZ_CANT_ADDIP=34
VZ_IP_INUSE=78
FAKEGATEWAY=192.0.2.1
FAKEGATEWAYNET=192.0.2.0
# Prints error message and exits
# Parameters:
# $1 - error message
# $2 - exit code
# Example of usage:
# error "Fatal error" 1
function error()
{
# print errors to stdout too
ERR=$?
echo "$SELFNAME ERROR: $1"
exit $2
}
# Puts line
# NAME="value"
# to config file. If NAME is found, line gets replaced,
# otherwise it is added to the end of file.
# Parameters:
# $1 - config file
# $2 - NAME
# $3 - value
function put_param()
{
local file="$1"
local name="$2"
local value="$3"
local path
path=${file%/*}
if [ ! -d "${path}" ]; then
mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE
fi
if grep -E "^$name=.*" $file>/dev/null 2>&1; then
${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE
/bin/sed -e "s|^$name=.*|$name=\"$value\"|" < ${file} > ${file}.$$
if [ $? -ne 0 ]; then
rm -f ${file}.$$ 2>/dev/null
error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
mv -f ${file}.$$ ${file}
else
echo "$name=\"$value\"" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
}
# Adds value to variable NAME
# in config file. If NAME is found, value gets added,
# otherwise it is added to the end of file.
# Parameters:
# $1 - config file
# $2 - NAME
# $3 - value
function add_param()
{
local file=$1
local name=$2
local value=$3
local path
path=${file%/*}
if [ ! -d "${path}" ]; then
mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE
fi
if grep -qe "^$name=" $file >/dev/null 2>&1; then
${CP} ${file} ${file}.$$ ||
error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE
/bin/sed -e "s|^$name=\"\(.*\)\"|$name=\"\1 $value \"|" < ${file} > ${file}.$$
if [ $? -ne 0 ]; then
rm -f ${file}.$$ 2>/dev/null
error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
mv -f ${file}.$$ ${file}
else
echo "$name=\"$value\"" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
}
function del_param()
{
local file=$1
local name=$2
local value=$3
local path
path=${file%/*}
if [ ! -d "${path}" ]; then
mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE
fi
if grep -qe "^$name=" $file >/dev/null 2>&1; then
${CP} ${file} ${file}.$$ ||
error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE
if [ -z "${value}" ]; then
/bin/sed -e "/^${name}=.*/d" < ${file} > ${file}.$$
else
sed -e "s|^${name}=\(.*\)${value}\(.*\)|${name}=\1\2|" <${file} > ${file}.$$
fi
if [ $? -ne 0 ]; then
rm -f ${file}.$$ 2>/dev/null
error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
mv -f ${file}.$$ ${file}
fi
}
# Puts line
# NAME value
# to config file. If NAME is found, line gets replaced,
# otherwise it is added to the end of file.
# Parameters:
# $1 - config file
# $2 - NAME
# $3 - value
function put_param2()
{
local file="$1"
local name="$2"
local value="$3"
local path;
path=${file%/*}
if [ ! -d "${path}" ]; then
mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE
fi
if grep -E "^\<$name\>" $file>/dev/null 2>&1; then
${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE
/bin/sed -e "s|^\<$name\>.*|$name $value|" < ${file} > ${file}.$$
if [ $? -ne 0 ]; then
rm -f ${file}.$$ 2>/dev/null
error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
mv -f ${file}.$$ ${file}
else
echo "$name $value" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
}
# Puts line
# NAME=( value )
# to config file. If NAME is found, line gets replaced,
# otherwise it is added to the end of file.
# Parameters:
# $1 - config file
# $2 - NAME
# $3 - value
function put_param3() {
local file=$1
local name=$2
local value=$3
local path
path=${file%/*}
if [ ! -d "${path}" ]; then
mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE
fi
if grep -E "^$name=\(.*\)" $file>/dev/null 2>&1; then
${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE
if [ -z "${value}" ]; then
/bin/sed -e "s|^$name=\(.*\)|$name=\( \)|" < ${file} > ${file}.$$
else
/bin/sed -e "s|^$name=\(.*\)|$name=\( \"$value\" \)|" < ${file} > ${file}.$$
fi
if [ $? -ne 0 ]; then
rm -f ${file}.$$ 2>/dev/null
error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
mv -f ${file}.$$ ${file}
else
if [ -z "${value}" ]; then
echo "$name=( )" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
else
echo "$name=( \"$value\" )" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
fi
}
# Adds value to array NAME
# in config file. If NAME is found, value gets added,
# otherwise it is added to the end of file.
# Parameters:
# $1 - config file
# $2 - NAME
# $3 - value
function add_param3() {
local file=$1
local name=$2
local value=$3
local path
path=${file%/*}
if [ ! -d "${path}" ]; then
mkdir -p ${path} || error "Unable to create dir ${path}" $VZ_FS_NO_DISK_SPACE
fi
if grep -E "^$name=\(.*\)" $file>/dev/null 2>&1; then
${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE
/bin/sed -r "s|^$name=\((.*)\)|$name=\( \1 \"$value\" \)|" < ${file} > ${file}.$$
if [ $? -ne 0 ]; then
rm -f ${file}.$$ 2>/dev/null
error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
mv -f ${file}.$$ ${file}
else
echo "$name=( \"$value\" )" >> $file || error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
}
# Removes value from array NAME
# in config file. If NAME is found, value gets removed,
# otherwise this is a noop function.
# Parameters:
# $1 - config file
# $2 - NAME
# $3 - value
function del_param3() {
local file=$1
local name=$2
local value=$3
[ ! -f $file ] && return
if grep -E "^$name=\(.*\)" $file>/dev/null 2>&1; then
${CP} ${file} ${file}.$$ || error "Can't copy file $file" $VZ_FS_NO_DISK_SPACE
/bin/sed -r "s|^($name=\( .*)\"$value\"(.* \))|\1\2|" < ${file} > ${file}.$$
if [ $? -ne 0 ]; then
rm -f ${file}.$$ 2>/dev/null
error "Can't change file $file" $VZ_FS_NO_DISK_SPACE
fi
mv -f ${file}.$$ ${file}
else
return
fi
}
function remove_debian_interface()
{
local dev="$1"
local cfg="$2"
${CP} ${cfg} ${cfg}.$$ ||
error "Can't copy file ${cfg}" $VZ_FS_NO_DISK_SPACE
awk '
NF == 0 {next}
$1 == "auto" && $2 ~/'${dev}'$/ {next}
$1 == "iface" && $2 ~/'${dev}'$/ {skip = 1; next}
/^\t/ && skip {next}
{skip = 0; print}
' < ${cfg} > ${cfg}.$$ && mv -f ${cfg}.$$ ${cfg}
rm -f ${cfg}.$$ 2>/dev/null
}
function change_hostname()
{
local cfg="$1"
local host="$2"
local ip="$3"
local comm='# Auto-generated hostname. Please do not remove this comment.'
[ -f "${cfg}" ] || touch ${cfg}
if [ "${host}" = "localhost" -o "${host}" = "localhost.localdomain" ];
then
put_param2 ${cfg} "127.0.0.1" "localhost.localdomain localhost"
return
fi
${CP} ${cfg} ${cfg}.$$ ||
error "Can't copy file ${cfg}" $VZ_FS_NO_DISK_SPACE
awk -v ip="${ip}" -v host="${host}" -v comm="${comm}" '
BEGIN { found = 0; extranames = ""; alias=""; }
$0 == comm {found = 1; next}
found || ($2 == host && (ip == "" || ip == $1)) {
if (ip == "") {ip = $1}
for (i=3; i <= NF; i++) {
if ((j=index($2, ".")) > 1) {
origalias= substr($2, 1, j - 1);
if (origalias != $i) {
EXTRANAMES[$i] = 1;
}
} else {
EXTRANAMES[$i] = 1;
}
}
found = 0;
next;
}
ip != "" && $1 == ip && $2 != host {
for (i=2; i <= NF; i++) { EXTRANAMES[$i] = 1 }
next;
}
$1 == "127.0.0.1" {
for (i=2; i <= NF; i++) { if ($i != "localhost" && $i != "localhost.localdomain") { LOCALHOST_ALIASES[$i] = 1 } }
for (localhost_alias in LOCALHOST_ALIASES) { localhost_aliases = localhost_aliases " " localhost_alias }
ate_localhost = 1;
next;
}
{print}
END {
if (ip == "") { ip ="127.0.0.1" }
if (ate_localhost && ip != "127.0.0.1") {
print "127.0.0.1 localhost.localdomain localhost" localhost_aliases;
}
print comm;
if ((i=index(host, ".")) > 1) {
alias= " " substr(host, 1, i - 1);
if (! (alias in EXTRANAMES)) {
EXTRANAMES[alias] = 1;
}
}
if (ip == "127.0.0.1") {
if (! ("localhost" in EXTRANAMES)) {
EXTRANAMES["localhost"] = 1;
}
if (! ("localhost.localdomain" in EXTRANAMES)) {
EXTRANAMES["localhost.localdomain"] = 1;
}
extranames = localhost_aliases;
}
for (extraname in EXTRANAMES) { extranames = extranames " " extraname }
print ip " " host extranames;
}
' < ${cfg} > ${cfg}.$$
if [ $? -ne 0 ]; then
rm -f ${cfg}.$$ 2>/dev/null
error "Can't change file ${cfg}" $VZ_FS_NO_DISK_SPACE
fi
mv -f ${cfg}.$$ ${cfg}
}
function cidr2mask() {
local i mask=""
local full_octets=$(($1/8))
local partial_octet=$(($1%8))
for i in 0 1 2 3; do
if [ $i -lt $full_octets ]; then
mask="${mask}255"
elif [ $i -eq $full_octets ]; then
mask="${mask}$((256 - (1 << (8 - $partial_octet))))"
else
mask="${mask}0"
fi
test $i -lt 3 && mask="${mask}."
done
echo $mask
}
function ip_conv() {
local ipm=$1
_IP=${ipm%%/*}
_MASK=''
_NETMASK=''
_IPV6ADDR=''
if [ "${_IP#*:}" != "${_IP}" ]; then
_IPV6_ADDR=yes
fi
if echo "${ipm}" | grep -q '/'; then
_MASK=${ipm##*/}
else
if [ -z "$IPV6_ADDR" ]; then
_MASK=24
else
_MASK=128
fi
fi
echo $ipm | grep -q ':' && return
_NETMASK=$(cidr2mask $_MASK)
}