#summary How to build a core-root filesystem template for use with CORE

= About OpenVZ and CORE OS templates =

OpenVZ uses [http://wiki.openvz.org/OS_template operating system templates] to supply the virtual containers with a root filesystem. "An OS template is basically a set of packages from some Linux distribution used to populate a container." (OpenVZ wiki) 

By default, CORE uses a single OS template cache for all of its nodes, located in `/vz/private/core-root`. This is a convenience so you can install a binary in one place and then use it on all nodes, and it saves a lot of disk space.

 * CORE nodes share the `/vz/private/core-root` filesystem through a symlink
{{{
# ls -al /vz/private
total 12
drwx------  3 root root 4096 Jun  9 11:03 .
drwxr-xr-x  8 root root 4096 Feb 18 14:39 ..
lrwxrwxrwx  1 root root   21 Jun  9 11:01 1000 -> /vz/private/core-root
lrwxrwxrwx  1 root root   21 Jun  9 11:01 1001 -> /vz/private/core-root
lrwxrwxrwx  1 root root   21 Jun  9 11:01 1002 -> /vz/private/core-root
drwxr-xr-x 20 root root 4096 Jun  1 09:33 core-root
}}}
 * each CORE node has its `/root` directory bind mounted to `/tmp/n0` (where `n0` corresponds to the node number)
 * some state directories are symlinked to this `/root` directory, allowing for per-node state
{{{
lrwxrwxrwx  1 root root    13 Jun  2 13:27 var/log -> /root/var/log
lrwxrwxrwx  1 root root    13 Jun  2 13:27 var/run -> /root/var/run
lrwxrwxrwx  1 root root 15 Jun  2 13:27 etc/quagga/Quagga.conf -> /root/boot.conf
}}}
 * you can create and destroy these symlinked containers with the `vzcreate.sh` and `vzdestroy.sh` scripts
 * you can create your own containers based off of other templates (e.g. one debian-5.0 and one suse-11.1) and CORE will try to use them as-is (container 1001 corresponds to n1, etc.)


= How to make a core-root template =
This is how the `core-root` template was made.

 # start with the precreated template *`centos-5-x86-devel.tar.gz`* available [http://download.openvz.org/template/precreated/centos-5-x86-devel.tar.gz here] (download this to your `/vz/template/cache` directory, *do not unpack it!*)
 # create a staging container the normal OpenVZ way; this properly sets up devices nodes, etc.
{{{
vzctl create 101 --ostemplate centos-5-x86-devel --config core
}}}
 # start and enter the container, turn off unnecessary services
{{{
vzctl start 101
vzctl enter 101
chkconfig --list | grep 5:on
for i in iptables lm_sensors mcstrans netfs portmap restorecond sendmail sshd; do chkconfig $i off; done
}}}
 # install the software you need on the virtual nodes
   * you can make a NAT connection (see also [LinuxOpenVZNetworkAccess]) in order to use `yum` from within the container. 
{{{
vznat.sh 101
vzctl enter 101
yum install autoconf automake libtool texinfo readline-devel
}}}
   * cleanup after you are finished with yum with 
{{{
# within container
yum clean all
# from host
rm /vz/private/101/etc/resolv.conf
echo 127.0.0.1 localhost localhost.localdomain > /vz/private/101/etc/hosts
}}}
   * CORE may be particular about which version of Quagga you use. The Quagga included with the CORE release is from [http://www.quagga.net Quagga.net] with the [http://hipserver.mct.phantomworks.org/ietf/ospf/ OSPFv3 MANET patch]. CORE uses the OSPFv3 MANET feature for wireless networks. If you only want wired networks or use custom configurations, you can use another version of Quagga. An RPM package for Quagga-manetmdr is installed in the `core-root` by default.
   * [http://cs.itd.nrl.navy.mil/products/ NRL]'s protolib, nrlsmf, and mgen are installed in `core-root` by default
 # move the staging area to core-root and create symlinks
{{{
cd /vz/private
mv 101 core-root
cd /vz/private/core-root/var
rm -rf log run
ln -s /root/var/run run
ln -s /root/var/log log
cd /vz/private/core-root/etc/quagga
ln -s /root/boot.conf Quagga.conf
}}}
   * note that the symbolic link targets `/root/var/run` etc. do not exist on the host, the links will appear broken; that is normal. Once the container is started by CORE, the `/root` directory will be mounted from `/tmp/n0` as described above
   * if you have other applications that require per-node state or configuration, modify the `core-root` with the appropriate symbolic links. You can update the `vzprep.sh` script to build the appropriate directories in `/tmp/n0` as needed.
 # Now that you are done building the core-root, you may want to tar up your work to have a snapshot to fall back to, or to copy to other CORE machines. Read the next section about building an RPM for these reasons.

= How to setup a per-node directory =
The `core-root` filesystem is shared, but some directories unique to each node, as described above. Suppose you want to add a new directory that is different on each node, for storing configuration files for example:
{{{
# EXAMPLE: /usr/local/etc
# host symbolic link
/vz/private/core-root/usr/local/etc -> /root/usr/local/etc
# view from inside container 
/usr/local/etc -> /root/usr/local/etc
# mounted view for container 1001
/root -> /tmp/n1
}}}

*Note:* all of these commands are performed on the host node, *not* from within the virtual container.

 # Remove the real directory from `core-root` if it already exists
{{{
# rm -rf /vz/private/core-root/usr/local/etc
}}}
 # Create a symbolic link for the directory in the `core-root`. Note that it does not really exist on the host node so the link appears broken.
{{{
# ln -s /root/usr/local/etc /vz/private/core-root/usr/local/etc
}}}
 # Add the new per-node directory to the `vzprep.sh` script (which is executed by CORE upon node creation), located in `/etc/core/vzprep.sh` or `cored/linux/scripts/vzprep.sh` if installing from source.
{{{
...
# edit the below line to include your own per-node directory
DIRS="/var/run/quagga /var/run/dbus /var/log /usr/local/etc /usr/local/var/log \
      /usr/local/var/run /etc/avahi/services /etc/avahi/etc"
}}}
 
= How to make the core-root RPM =
The core-root RPM is maintained separately from the CORE program RPM, due to its large size and to allow experimenting with different core-root environments. Once you have created a `/vz/private/core-root` directory tree using the steps above, follow these steps for making an RPM:
 # first follow steps above for making a `/vz/private/core-root`; once that is ready and tested you can build this RPM
 # the CORE source has the Makefile needed to easily build an RPM, along with the spec file; prepare the source first with
{{{
./bootstrap.sh
./configure
}}}
 # as root, from the CORE source directory, issue the command:
{{{
make core-root-rpm
}}}
 # the successful rpmbuild should result in `/usr/src/redhat/RPMS/core-root-n.n-1.i386.rpm`