The StratusLab distribution is able to customize machine image from a base image for a later use.
This base image has to follow some rules in order to be use to build custom image. As this base image will be booted on the cloud, contextualization needs to take place such that we can SSH into the machine with a public/private key pair.
The SSH server is installed by default in many Linux distribution but make sure the server is started at boot time.
The StratusLab distribution uses the OpenNebula cloud system, so the base images need to include the contextualization compatible with OpenNebula.
The installation of this contextualization mechanism is very simple, only a bash script has to be executed during the boot sequence.
The reference to this script can be placed in /etc/rc.local.
For example you can add at the end of the file (before the exit 0 if any):
bash /usr/bin/onecontext
In this example, the contextualization script to execute is /usr/bin/onecontext
You will find below the script /usr/bin/onecontext referred to in the previous example.
#!/bin/sh -e
[ -e /dev/hdc ] && DEVICE=hdc || DEVICE=sr0
mount -t iso9660 /dev/$DEVICE /mnt
if [ -f /mnt/context.sh ]; then
. /mnt/init.sh
fi
umount /mnt
exit 0
Note that by convention the contextualization disk has to be mapped to the device /dev/hdc. If you are using the stratus-run-instance command this mapping is automatic but if you create your own template, the target option of the disk has to follow this convention.
The reference to sr0 is a work around. On some operating system, like Ubuntu, the contextualization disk doesn't seem to map correctly on the device specified (e.g. /dev/hdc) in the template. In this case, the mapping seems to default to sr0, hence this hack.
Further, CentOS doesn't support SCSI drives, we therefore default to /dev/hdc (i.e. IDE drive) for the contextualization drive.
The standard init.sh shipped with StratusLab and used by commands such as stratus-run-instance and stratus-create-instance is:
#!/bin/sh -e
source /mnt/context.sh
source /mnt/configuration.sh
ifconfig eth0 ${IP_PRIVATE}${NETMASK_PRIVATE}
route add -net ${GLOBAL_NETWORK}/${GLOBAL_NETMASK} dev eth0
route add default gw ${DEFAULT_GATEWAY} dev eth0
if [ -n "$IP_PUBLIC" ]; then
ifconfig eth1 ${IP_PUBLIC}${NETMASK_PUBLIC}
route add default gw ${DEFAULT_GATEWAY} dev eth1
fi
if [ -n "$IP_EXTRA" ]; then
ifconfig eth2 ${IP_EXTRA}${NETMASK_EXTRA}
route add default gw ${DEFAULT_GATEWAY} dev eth2
fi
mkdir -p /root/.ssh
echo "$PUBLIC_KEY" >> /root/.ssh/authorized_keys
chmod -R 600 /root/.ssh/
if [ -n "$STRATUSLAB_REMOTE_KEY" ]; then
echo "$STRATUSLAB_REMOTE_KEY" >> /root/.ssh/authorized_keys
fi
# OpenDNS server
echo "nameserver 208.67.222.222" > /etc/resolv.conf
echo "nameserver 208.67.220.220" >> /etc/resolv.conf
Therefore, the network setup of the physical host (node) must comply with the expectations set by this above script.