Ok all...

This is my 3rd piece.  It's "my script" that runs with "my setup" to
start up containers at boot with systemd on Fedora.

I don't want to step on the valuable work that Stéphane is doing in this
area but I hope this provides him with ideas.  Installed
in /usr/libexec/lxc/lxc-startup, it provides the additional
functionality to start containers when Fedora restarts.

Out of respect for other people's work right now, I'm not offering this
as a patch to the source tree.  It's just a suggestion how I would do
this.  There are a lot of things in this script that is very maliable
and it depends on a couple of things that need to be refined (such as
LXC_PATH).

In this script, a formalized way of obtaining a list of containers (and
configuration files) qualified to be autobooted would be good.  I
currently use the output of lxc-ls in combination of an arbitrary
LCM_PATH of /var/lib/lxc, neither of which may be optimal

Offered with the proviso that "it works for me"...  Attached below the
jump.

Regards,
Mike
-- 
Michael H. Warfield (AI4NB) | (770) 978-7061 |  m...@wittsend.com
   /\/\|=mhw=|\/\/          | (678) 463-0932 |  http://www.wittsend.com/mhw/
   NIC whois: MHW9          | An optimist believes we live in the best of all
 PGP Key: 0x674627FF        | possible worlds.  A pessimist is sure of it!


-- 
#!/bin/sh -

# lxc-startup
#       Start up a list of containers...

# lxc-run [-b] [-f] [-h] [vm list]

# Wrapper script to run a bunch of containers optionally at boot time
#
#    -l n    : Boot all stopped containers with bootlevel >= n
#            :   default 0
#    -b      : Only start the container if onboot is true
#            :   equivalent to "-l 1" (also sets -q)
#    -F      : Force boot a container even if disabled is true
#            :   equivalent to "-l -1"
#    -h      : Print this message and exit
#    -q      : Quiet (disable ECHO)
#    -v      : Enable debug prints (enable ECHO)
#    -n      : Optional individual VM (maybe be used multiple times)
# [vm list] - list of VM's to start.  Default is any that are not disabled.
#

# Authors:
# Michael H. Warfield <m...@wittsend.com>

#  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

declare -i VERBOSITY=1
START_LEVEL=0
LASTCONFIG=undefined

# Not sure what the deal is but it seems to be a problem if we
# start kicking off containers too soon and this is non-blocking
# anyways, so let's just give the system a little time to catch
# it's breath before kicking these babies off...

# This is a variable to start next delay and is fed from the configuration
# files...
#
# This sets the initial delay...
DELAY=5
DELAY_DEFAULT=2

# A few generic ECHO commands for verbosity...
# Most of these are not currently used...

ECHO_OFF=": echo"
ECHO=": echo"
ECHO1=": echo"
ECHO2=": echo"
ECHO3=": echo"
ECHO4=": echo"

# BOOTLIST will be a newline delimited prioritized list of our
# containers to be processed.
#
# Currently, this list is space delimited.  This is not good if
# we allow white space in container names or paths.  A '/' may
# be better as a delimiter just because it screws up pathnames
# and nobody in their right mind would use it in a name.
#
# Fields:
#       Priority
#       Post Start Delay
#       Container Name
#       Container Config file

BOOTLIST=

function usage() {
        echo "usage: $0 [-b] [-F] [-h] [-q] [-v] [-l n] [-n VM] [--] [VM list]"
}


function help() {
        usage
        echo "

Run one or more containers with a halt monitor
Register a new container if necessary

Options:
    -b      : Only start the container if lxc.onboot is true
    -F      : Force boot a container even if lxc.disabled is true
    -l n    : Boot containers with bootlevel >= n
    -h      : Print this message and exit
    -q      : Quiet (disable ECHO)
    -v      : Enable debug prints (enable ECHO)
    -n      : Optional individual VM (maybe be used multiple times)
    VM list : Optional list of VM's to start

        If the list of VM names is empty, it defaults to all available
        subject to boot and force options.
"
}

# Rotate log based on date
#       argvs == logfile to rotate...

function log_rotate() {
        local STAMP=$(date +%F-%T)

        while [[ ${1} != "" ]]
        do
                local FNAME=$1

                if [[ ${FNAME} != "" && -f ${FNAME} && ! -f ${FNAME}-${STAMP} ]]
                then
                        mv ${FNAME} ${FNAME}-${STAMP}
                fi
                shift
        done
}

# Checks the boot order priority in a config file and
# returns it plus the post start delay befoer starting
# the next container...

# This is my own convention...  These are options in the config
# file under lxc-boot.* to control higher level boot options.

# For "legacy" reasons (my past efforts) this honors lxc-boot.disabled
# and lxc-boot.onboot, even though most of the functionality is
# subsumed under lxc-boot.autoboot.  All of these parameters are,
# of course, maliable and adaptable to what ever we want.

CCG_GROUP=lxc-boot

# Function is called with the realpath to the configuration file.
# Function returns echoing the value of "priority delay" where
# pritority is the positive value boot order priority of the
# container and the delay to wait before starting another container.

function check_boot_level() {
        local CNAME
        local AUTOBOOT
        local DISABLED
        local ONBOOT
        local MY_DELAY
        local ret

        CNAME=$1
        ret=$2

        DISABLED=`sed -e "/$CFG_GROUP\.disabled\s*=\s*/!d" -e 's/.*=\s*//' -e q 
${CNAME}`
        ONBOOT=`sed -e "/$CFG_GROUP\.onboot\s*=\s*/!d" -e 's/.*=\s*//' -e q 
${CNAME}`
        AUTOBOOT=`sed -e "/$CFG_GROUP\.autoboot\s*=\s*/!d" -e 's/.*=\s*//' -e q 
 ${CNAME}`
        MY_DELAY=`sed -e "/$CFG_GROUP\.delay\s*=\s*/!d" -e 's/.*=\s*//' -e q  
${CNAME}`

        # If disabled is true, then override everything...
        # More severe disables can be applied more negative numbers.
        if [[ "${DISABLED}" == true || "${DISABLED}" == yes ]]
        then
                AUTOBOOT=-1;
        fi

        # If onboot is set and autoboot is not set, set autoboot to 1
        if [[ "${ONBOOT}" == true || "${ONBOOT}" == yes ]]
        then
                if [[ ${AUTOBOOT} == "" ]]
                then
                        AUTOBOOT=1;
                fi
        fi

        if [[ "${AUTOBOOT}" != "" ]]
        then
                ret=${AUTOBOOT}
        fi

        if [[ "${MY_DELAY}" == "" ]]
        then
                MY_DELAY=${DELAY_DEFAULT}
        fi
 
        echo "${ret} ${MY_DELAY}"
        return 0
}

#
# Need to process our command line options
#

# We'll take a couple of shortcuts first.
# If there are no other parameters other than "start", "stop", or "restart",
# then we'll take that...  That makes this compatible with System V init
# and Upstart.

if [[ ${1} == "start" ]]
then
        shift
        # This is an exect out of init.  Make ssshhh...
        VERBOSITY=0
        START_LEVEL=1
fi

if [[ ${1} == "stop" ]]
then
        echo "Stop is not currently implimented"
        VERBOSITY=0
        exit 0
fi

if [[ ${1} == "restart" ]]
then
        echo "Restart is not currently implimented"
        VERBOSITY=0
        exit 0
fi

shortoptions='vqhl:n:Fb'
longoptions='verbose,quiet,help,level:,name:,force,boot'

getopt=$(getopt -o $shortoptions --longoptions  $longoptions -- "$@")
if [[ $? != 0 ]]
then
    usage
    exit 1;
fi

eval set -- "$getopt"

while true; do
        case "$1" in
            -h|--help)
                help
                exit 1
                ;;
            -n|--name)
                shift
                VM_LIST="$VM_LIST $1"
                shift
                ;;
            -F|--force)
                shift
                START_LEVEL=-1
                ;;
            -v|--verbose)
                shift
                VERBOSITY=$(( $VERBOSITY + 1 ))
                ECHO="echo"
                ;;
            -q|--quiet)
                shift
                VERBOSITY=0
                ECHO=": echo"
                ;;
            -b|--boot)
                VERBOSITY=0
                shift
                START_LEVEL=1
                ;;
            -l|--level)
                shift
                START_LEVEL=$1
                shift
                ;;
            --)
                shift
                break
                ;;
            -*)
                echo $1
                usage
                exit 1
                ;;
            *)
                break
                ;;
        esac
done

if [[ ${VERBOSITY} -gt 0 ]]
then
        ECHO="echo"
else
        ECHO=": echo"
fi

# What ever is left should be a list of VM's or NULL

if [[ "$*" ]]
then
        VM_LIST="$VM_LIST $*"
        for CNAME in $VM_LIST
        do
                if [[ -f /var/lib/lxc/${CNAME}/config ]]
                then
                        STATUS=$(lxc-info -n ${CNAME} 2> /dev/null | sed -e 
'/[Ss]tate:/!d' -e 's/[Ss]tate:.*\s//')
                        FNAME=$(realpath /var/lib/lxc/${CNAME}/config)
                        BOOT=$(check_boot_level "${FNAME}" 0)
                        ${ECHO_OFF} "${BOOT} ${CNAME} ${FNAME}"
                        BOOTLIST="${BOOTLIST}
${BOOT} ${CNAME} ${FNAME}"
                fi
        done
fi

if [[ ! "$VM_LIST" ]]
then
        # Ubuntu convention...
        # These should be links to conf files
        # name format "container_name{.conf}
        if [[ -d /etc/lxc/auto ]]
        then
                for f in $( ls /etc/lxc/auto )
                do
                        if [[ -s /etc/lxc/auto/$f ]]
                        then
                                FNAME=$( realpath -e "/etc/lxc/auto/$f" )
                                CNAME="$(basename $f .conf)"
                                # Ok...  Just for giggles, let's do a
                                # little comparison...  The config file
                                # SHOULD be in a directory which matches
                                # the container name or maymhem may follow.
                                DIRNAME=$(dirname ${FNAME})
                                CDIR=$(basename ${DIRNAME})
                                STATUS=$(lxc-info -n ${CNAME} 2> /dev/null | 
sed -e '/[Ss]tate:/!d' -e 's/[Ss]tate:.*\s//')
                                if [[ "${CNAME}" != "${CDIR}" ]]
                                then
                                        ${ECHO} "Warning!  Container directory 
does not match autoboot name - ${CNAME} != ${CDIR}"
                                        NSTATUS=$(lxc-info -n ${CDIR} 2> 
/dev/null | sed -e '/[Ss]tate:/!d' -e 's/[Ss]tate:.*\s//')

                                        if [[ ${STATUS} == "" && ${NSTATUS} != 
"" ]]
                                        then
                                                ${ECHO} "Switching to $CDIR for 
container name"
                                                # This is a bit of a heuristic 
but, if it fails,
                                                # some chump is doing something 
stupid that they
                                                # need to manually correct.
                                                CNAME=$CDIR
                                                STATUS=${NSTATUS}
                                        fi
                                fi
                                if [[ ${STATUS} == "STOPPED" ]]
                                then
                                        BOOT=$(check_boot_level "${FNAME}" 1)
                                        ${ECHO} "${BOOT} ${CNAME} ${FNAME}"
                                        BOOTLIST="${BOOTLIST}
${BOOT} ${CNAME} ${FNAME}"
                                else
                                        ${ECHO} "Container ${CNAME} is 
${STATUS} and not in state STOPPED, skipping"
                                fi
                        else
                                ${ECHO} "/etc/lxc/auto/$f not a symlink"
                        fi
                done
        fi

        VM_LIST=$(lxc-ls)
        for CNAME in $VM_LIST
        do
                if [[ -f /var/lib/lxc/${CNAME}/config ]]
                then
                        STATUS=$(lxc-info -n ${CNAME} 2> /dev/null | sed -e 
'/[Ss]tate:/!d' -e 's/[Ss]tate:.*\s//')
                        FNAME=$(realpath /var/lib/lxc/${CNAME}/config)
                        BOOT=$(check_boot_level "${FNAME}" 0)
                        ${ECHO_OFF} "${BOOT} ${CNAME} ${FNAME}"
                        BOOTLIST="${BOOTLIST}
${BOOT} ${CNAME} ${FNAME}"
                fi
        done
fi

# Need to deal with the condition where VMLIST is not NULL...

SORTBOOT=$( echo -n "$BOOTLIST" | sort --key=1nr,4  )

${ECHO} "START_LEVEL = ${START_LEVEL} ${DELAY}"

echo "$SORTBOOT" | while read PRIORITY POST_DELAY CNAME CONFIG
do

        if [[ ${PRIORITY} = "" ]]
        then
                continue;
        fi

        # Only one startup per config!
        # We sorted on this but this is only good if
        # it's within the same priority!  Not robust!

        if [[ "${CONFIG}" == "${LASTCONFIG}" ]]
        then
                continue
        fi
        LASTCONFIG="${CONFIG}"

        if [[ ${PRIORITY} -ge ${START_LEVEL} ]]
        then
                STATUS=$(lxc-info -n ${CNAME} 2> /dev/null | sed -e 
'/[Ss]tate:/!d' -e 's/[Ss]tate:.*\s//')
                if [[ ${STATUS} == "" ]]
                then
                        ${ECHO} "Unknown container:     ${PRIORITY} 
${POST_DELAY}       \"${CNAME}\"    \"${CONFIG}\""
                elif [[ ${STATUS} != "STOPPED" ]]
                then
                        ${ECHO} "Not Stopped:   ${PRIORITY} ${POST_DELAY}       
\"${CNAME}\"    \"${CONFIG}\""
                else
                        ${ECHO} "Will boot:     ${PRIORITY} ${POST_DELAY}       
\"${CNAME}\"    \"${CONFIG}\""
                        LXC_LOGDIR=$(dirname "${CONFIG}")

                        log_rotate ${LXC_LOGDIR}/console_out.log 
${LXC_LOGDIR}/console_log.log ${LXC_LOGDIR}/logfile.log
                        if [[ ${DELAY} != "" && ${DELAY} -gt 0 ]]
                        then
                                sleep ${DELAY}
                        fi
                        lxc-start -d -c ${LXC_LOGDIR}/console_out.log -L 
${LXC_LOGDIR}/console_log.log -o ${LXC_LOGDIR}/logfile.log -n ${CNAME}

                        # Now set the delay to this container's delay...
                        DELAY=${POST_DELAY}
                fi
        else
                ${ECHO} "Won't boot:    ${PRIORITY} ${POST_DELAY}       
\"${CNAME}\"    \"${CONFIG}\""
        fi
done


Attachment: signature.asc
Description: This is a digitally signed message part

------------------------------------------------------------------------------
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to