We currently migrate to MediaWiki from our old installation, but not all content has been migrated yet. Take a look at the Wiki Team page for instructions how to help or browse through our new wiki at wiki.linux-vserver.org to find the information already migrated.

Configuration conversion script

Below is the result of half an hour of shell-scripting and modifications by Dirk Ruediger. The code was written for my specific environment, but was found usefull by at least two other vserver users.

The resulting code is supposed to convert the legacy configuration files (.conf and .sh files in /etc/vservers) to the new directory layout as described in detail on [The Great Flower Page].

The changes by Dirk consist of being able to handle multiple network devices and setting the flag /apps/init/mark to "default" so that the vserver is started via /etc/init.d/vserver-default (under debain at least ;-))

vscfg-convert.sh

The full script:

#!/bin/bash
###########

do_usage() {
        echo "Usage: $0 [NAME] <-f>"
        echo
        echo "Where NAME is the name of the Linux-VServer"
        echo "Optionally use -f to remove an already present config directory"
        echo " More info on the directory layout can be found at the 'flower page'"
        echo " http://www.nongnu.org/util-vserver/doc/conf/configuration.html"
}


do_parsecfg() {
        echo -n "Parsing old configfile"
        # Obtain all settings from the Linux-VServer using old configfile
        source ${OLD_CONF_DIR}/${VSNAME}.conf
        echo " [DONE]"
        echo
}


do_parsesh() {
        echo -n "Parsing old shellscript: "
        TYPE=0
        SKIP=0

        if [ -f ${VSBDIR}/scripts/generic.sh ]; then
                rm ${VSBDIR}/scripts/generic.sh
        fi

        echo "#!/bin/bash" > ${VSBDIR}/scripts/pre-start
#       echo "source ${VSBDIR}/scripts/generic.sh" >> ${VSBDIR}/scripts/pre-start
        echo >> ${VSBDIR}/scripts/pre-start

        echo "#!/bin/bash" > ${VSBDIR}/scripts/post-start
#       echo "source ${VSBDIR}/scripts/generic.sh" >> ${VSBDIR}/scripts/post-start
        echo >> ${VSBDIR}/scripts/post-start

        echo "#!/bin/bash" > ${VSBDIR}/scripts/pre-stop
#       echo "source ${VSBDIR}/scripts/generic.sh" >> ${VSBDIR}/scripts/pre-stop
        echo >> ${VSBDIR}/scripts/pre-stop

        echo "#!/bin/bash" > ${VSBDIR}/scripts/post-stop
#       echo "source ${VSBDIR}/scripts/generic.sh" >> ${VSBDIR}/scripts/post-stop
        echo >> ${VSBDIR}/scripts/post-stop

    if [ -f ${OLD_CONF_DIR}/$VSNAME.sh ]
    then
        while read SHELLSCRIPT ; do
            case $SHELLSCRIPT in
                pre-sta*)
                    echo -n " pre-start"
                    TYPE=1
                    SKIP=1
                    ;;
                post-sta*)
                    echo -n " post-start"
                    TYPE=2
                    SKIP=1
                    ;;
                pre-sto*)
                    echo -n " pre-stop"
                    TYPE=3
                    SKIP=1
                    ;;
                post-sto*)
                    echo -n " post-stop"
                    TYPE=4
                    SKIP=1
                    ;;
                "case $1 in")
                    SKIP=1
                    ;;
                "esac")
                    SKIP=1
                    ;;
                ";;")
                    SKIP=1
                    ;;
            esac

            if [ "${SKIP}" != "1" ]; then
                case $TYPE in
                    0)
                        echo $SHELLSCRIPT >> ${VSBDIR}/scripts/generic.sh
                        ;;
                    1)
                        echo $SHELLSCRIPT >> ${VSBDIR}/scripts/pre-start
                        ;;
                    2)
                        echo $SHELLSCRIPT >> ${VSBDIR}/scripts/post-start
                        ;;
                    3)
                        echo $SHELLSCRIPT >> ${VSBDIR}/scripts/pre-stop
                        ;;
                    4)
                        echo $SHELLSCRIPT >> ${VSBDIR}/scripts/post-stop
                        ;;
                esac
            else
                SKIP=0
            fi
        done < ${OLD_CONF_DIR}/$VSNAME.sh
    fi
        echo " [DONE]"
        echo
}


do_gencfgdir() {
        echo "Creating new configdirectory"
        # Create new vserver configuration directories
        # and create some sane defaults
        # - like `vserver [NAME] build -m skeleton` would do
        mkdir -p ${VSBDIR}/apps/init
        mkdir -p ${VSBDIR}/interfaces/0/
        mkdir -p ${VSBDIR}/uts
        mkdir -p ${VSBDIR}/scripts

        ln -s /var/run/vservers/${VSNAME} ${VSBDIR}/run
        ln -s /etc/vservers/.defaults/run.rev ${VSBDIR}/run.rev
        ln -s /etc/vservers/.defaults/vdirbase/${VSNAME} ${VSBDIR}/vdir

        #
        # Create the new configuration based on the [NAME].conf file
        #

        # Fill the System capabilities file (2.6 kernel)
        echo -n " * Setting Bcapabilities:"
        if [ -f ${VSBDIR}/bcapabilities ]; then
                rm -f ${VSBDIR}/bcapabilities
        fi
        for CAPA in ${S_CAPS}; do
                echo -n " ${CAPA}"
                echo "${CAPA}" >> ${VSBDIR}/bcapabilities
        done
        echo " [OK]"

        # Fill the System capabilities file (2.4 kernel)
#       echo -n " * Setting capabilities:"
#       if [ -f ${VSBDIR}/capabilities ]; then
#               rm -f ${VSBDIR}/capabilities
#       fi
#       for CAPA in ${S_CAPS}; do
#               echo -n " ${CAPA}"
#               echo "${CAPA}" >> ${VSBDIR}/capabilities
#       done
#       echo " [OK]"

        # Fill the Context capabilities file
#       echo -n " * Setting Ccapabilities:"
#       if [ -f ${VSBDIR}/ccapabilities ]; then
#               rm -f ${VSBDIR}/ccapabilities
#       fi
#       for CAPA in ${S_CAPS}; do
#               echo -n " ${CAPA}"
#               echo "${CAPA}" >> ${VSBDIR}/ccapabilities
#       done
#       echo " [OK]"

        # Set the flags for this Linux-VServer
        echo -n " * Setting flags:"
        if [ -f ${VSBDIR}/flags ]; then
                rm -f ${VSBDIR}/flags
        fi
        if [ "${S_FLAGS}" == "" ]; then
                S_FLAGS="lock nproc"
        fi

        for FLAG in ${S_FLAGS}; do
                echo -n " ${FLAG}"
                echo "${FLAG}" >> ${VSBDIR}/flags
        done
        echo " [OK]"

        # Setup the fstab file (Using sane defaults)
        # - There was no way to specify this in the
        #   old style config file
        echo -n " * Setting the fstab(s):"
        echo "none      /proc           proc    defaults                0 0" > ${VSBDIR}/fstab
        echo "none      /dev/pts        devpts  gid=5,mode=620          0 0" >> ${VSBDIR}/fstab
        echo "#none     /tmp            tmpfs   size=16m,mode=1777      0 0" >> ${VSBDIR}/fstab

        # Define, but don't use, a local fstab entry
#       echo "# The fstab file for the vserver." > ${VSBDIR}/fstab.local
#       echo "#" >> ${VSBDIR}/fstab.local
#       echo "# In opposite to the normal 'fstab' file, the mounting happens in the local network context." >> ${VSBDIR}/fstab.local
#       echo "# Currently there is no way to mix entries of both files; 'fstab' will be always processed" >> ${VSBDIR}/fstab.local
#       echo "# before 'fstab.local'." >> ${VSBDIR}/fstab.local
#       echo " [OK]"

        # Init based configuration
#       echo -n " * Setting the INIT configuration:"
#       if [ "${S_START}" != "" ]; then
#               echo "${S_START}" > ${VSBDIR}/apps/init/cmd.start
#       fi
#       if [ "${S_STOP}" != "" ]; then
#               echo "${S_STOP}" > ${VSBDIR}/apps/init/cmd.stop
#       fi
        echo "plain" > ${VSBDIR}/apps/init/style
        if [ "x${ONBOOT}" == "xyes" ]; then
                 echo "default" > ${VSBDIR}/apps/init/mark
        fi
        echo " [OK]"

        # Set the vserver name / context
        echo -n " * Setting Linux VServer specifics (contextid, etc):"
        echo "${VSNAME}" > ${VSBDIR}/name
        echo "${S_CONTEXT}" > ${VSBDIR}/context

        # Change the `uname` output for the Linux-VServer
        echo "${S_HOSTNAME}" > ${VSBDIR}/uts/nodename
        echo "`uname -r | cut -d - -f 1`" > ${VSBDIR}/uts/release
        echo " [OK]"

        # IP Configuration
        echo " * Setting up network configuration..."
        NETID=0
        for VSNET in ${IPROOT}; do
                echo "  - Interface ${NETID} -"
                VSNETDEV="`echo ${VSNET} | cut -d : -f 1 | egrep \"^[[:alpha:]]\" `"
                VSNETADDR="`echo ${VSNET} | cut -d : -f 2 | cut -d / -f 1`"
                VSNETMASK="`echo ${VSNET} | cut -d : -f 2 | cut -d / -f 2 -s`"
                mkdir -p ${VSBDIR}/interfaces/${NETID}/

                if [ "${VSNETBCAST}" != "" ]; then
                        echo "   Broadcast: ${VSNETBCAST}"
                        echo "${VSNETBCAST}" > ${VSBDIR}/interfaces/${NETID}/bcast
                fi
                if [ "${VSNETDEV}" != "" ]; then
                        echo "   Device: ${VSNETDEV}"
                        echo "${VSNETDEV}" > ${VSBDIR}/interfaces/${NETID}/dev
                fi
#               touch ${VSBDIR}/interfaces/${NETID}/disabled
                if [ "${VSNETADDR}" != "" ]; then
                        echo "   Address: ${VSNETADDR}"
                        echo "${VSNETADDR}" > ${VSBDIR}/interfaces/${NETID}/ip
                fi
                if [ "${VSNETMASK}" != "" ]; then
                        echo "   Netmask: ${VSNETMASK}"
                        echo "${VSNETMASK}" > ${VSBDIR}/interfaces/${NETID}/mask
                fi
                echo "   Alias name: ${NETID}${VSNAME}"
                echo "${NETID}${VSNAME}" > ${VSBDIR}/interfaces/${NETID}/name
#               touch ${VSBDIR}/interfaces/${NETID}/nodev
#               echo "${IPROOTBCAST}" > ${VSBDIR}/interfaces/${NETID}/prefix
#               echo "${IPROOTBCAST}" > ${VSBDIR}/interfaces/${NETID}/scope
                let NETID++
        done
        echo
}

do_updatevserver() {
        rm -rf ${VSROOT}/${VSNAME}/dev \
                ${VSROOT}/${VSNAME}/proc

        mkdir -p ${VSROOT}/${VSNAME}/proc
        mkdir -p ${VSROOT}/${VSNAME}/dev/pts

        mknod -m 666 ${VSROOT}/${VSNAME}/dev/full c 1 7
        mknod -m 666 ${VSROOT}/${VSNAME}/dev/null c 1 3
        mknod -m 666 ${VSROOT}/${VSNAME}/dev/ptmx c 5 2
        mknod -m 644 ${VSROOT}/${VSNAME}/dev/random c 1 8
        mknod -m 666 ${VSROOT}/${VSNAME}/dev/tty c 5 0
        mknod -m 644 ${VSROOT}/${VSNAME}/dev/urandom c 1 9
        mknod -m 666 ${VSROOT}/${VSNAME}/dev/zero c 1 5

        echo "Update of proc/dev tree [DONE]"
}


### Main
if [ "$1" == "" ]; then
  do_usage
  exit 1
fi

### Settings
VSNAME=$1
VSROOT=/var/lib/vservers
VSBDIR=/etc/vservers/${VSNAME}
OLD_CONF_DIR=/etc/vservers

### Clean up if wanted
if [ "$2" == "-f" -a -d ${VSBDIR} ]; then
        echo -n "Forcing removal of previous configuration directory: ${VSBDIR}"
        rm -rf ${VSBDIR}
        echo " [DONE]"
        echo
fi

if [ -f ${OLD_CONF_DIR}/${VSNAME}.conf ]; then
        do_parsecfg     ;# Read the [NAME].conf file
        do_gencfgdir    ;# Convert the [NAME].conf file
        do_parsesh  ;# Convert the [NAME].sh file
        # In case only config should be converted
        # Check for /etc (in vserver) to be sure that there's really a vserver present (i.e. LVM mounted)
        if [ -d ${VSROOT}/${VSNAME}/etc ]; then
                do_updatevserver;# Convert proc/dev tree
        else
                echo "Update of proc/dev tree [FAILED]"
                echo "    VServer directory not found or LVM not mounted on ${VSROOT}/${VSNAME}."
                echo "    So no update of proc/dev tree."
        fi
else
        echo "VServer configuration not found!"
        exit 1
fi

See also [Step-by-Step Guide 2.6] under "Migration" for info on how to manually migrate to the new config style.

Ulimits are currently not converted by the script.