Kameleon is a very simple tool to create appliances, vm or cd images, or what you want… Actually, it is a bash script generator using YAML as an imput format. But it has been designed mainly to create initial images from scratch as we haven't found a tool for doing this and only this, for whatever linux distribution and without a client/server architecture, without features to maintain a living system or other “heavy” features. It is written in Ruby and have a very few dependencies.
With Kameleon, you can use provided or self-written recipes using provided or self-written macrosteps and microsteps. Provided examples are self-explanatory so that you can quickly start to create your own recipes to generate customized images. Our provided recipes are part of Kameleon and allow you to obtain, for example, a bootable Debian Linux system (etch, lenny, squeeze,…) in qcow2 format in less than 3 minutes!
The use of the YAML format makes the bash pieces of code very easy to read and maintain. As an example, when you write into a file using “cat” and “«EOF” you generally break the indentation of your meta-code and it becomes uggly and hard to maintain. But kameleon files are always clean with a nice YAML indentation
Warning: kameleon must be run as root and as it constructs a system image into a chroot directory, it may start/stop some services. this may have unpredictable effects on your running system. so, don't use it on a production server. if you want to experiment kameleon with no risk, we recommend you to use the kameleon appliance.
> sudo su - > mkdir -p kameleon/recipes > mkdir kameleon/steps > cp /usr/share/kameleon/recipes/debian.yaml kameleon/recipes/my_debian.yaml > # or if you installed from sources: > # cp /usr/local/share/kameleon/recipes/debian.yaml kameleon/recipes/my_debian.yaml > vi kameleon/recipes/my_debian.yaml # customize the recipe if needed > cd kameleon > kameleon my_debian # wait... > sudo kvm -hda /var/tmp/kameleon/2010-04-22-16-27-27/image.qcow
Recipe | |---> Kameleon Engine ---> Appliance (tgz, qcow, iso,...) Steps
At any microstep, kameleon can escape to a shell, either by a specific “breakpoint” microstep command or when an error occurs.
For more commands, see the Documentation.rst file of the kameleon distribution.
Sample recipe (debian.yaml):
global: workdir_base: /var/tmp/kameleon distrib: debian debian_version_name: squeeze distrib_repository: http://ftp.fr.debian.org/debian/ arch: amd64 kernel_arch: "amd64" steps: - debian_check_deps - check_deps: - rsync - building_appliance - building_kvm_images # - oar/oar_precheck # - checkpoint_resume - bootstrap - system_config # - network_config_static - root_passwd - mount_proc - software_install: - extra_packages - kernel_install # - checkpoint # - oar/oar_debian_install # - oar/oar_system_config - strip - umount_proc # - xen_domu # - oar/oar_build_tgz - build_appliance: - clean_udev - save_as_tgz - create_raw_image - create_nbd_device - mkfs - mount_image - copy_system_tree # - grub_197_workaround - install_grub - umount_image - save_as_raw # - save_as_vmdk - save_as_qcow2 # - save_as_vdi - clea
Sample macrostep file (debian/kernel_install.yaml):
kernel_install: - kernel-img_conf: - write_file: - /etc/kernel-img.conf - | do_symlinks = yes relative_links = yes do_bootloader = yes do_bootfloppy = no do_initrd = yes link_in_boot = no - kernel_install: - exec_chroot: apt-get -y --force-yes install linux-image-$$kernel_arc
Kameleon is distributed under the GPL licence, copyright LIG <http://lig.imag.fr> and can be downloaded from the INRIA sourceforge here: https://gforge.inria.fr/projects/kameleon.
The development sources are hosted by the OAR project: https://gforge.inria.fr/scm/?group_id=2308
The debian packages are build with squeeze. Currently, they will also work for lenny and wheezy. According to your needs, put on of these repositories into your /etc/apt/sources.list:
# snapshots (automatically builded) deb http://oar-ftp.imag.fr/kameleon/debian squeeze-snapshots main # unstable/testing deb http://oar-ftp.imag.fr/kameleon/debian squeeze-proposed-updates main # stable deb http://oar-ftp.imag.fr/kameleon/debian squeeze mai
Add the following gpg key to the apt keyring:
curl http://oar-ftp.imag.fr/kameleon/debian/oar-archive-keyring.asc | sudo apt-key add
And do:
apt-get update apt-get install kameleon rubygems gem install sessio
Download the lastest .tgz source files:
# last sources http://oar-ftp.imag.fr/kameleon/sources/ # old sources https://gforge.inria.fr/frs/?group_id=230
Untar and do “make install”
In any case, it can be easily installed by Rubygems:
gem install sessio
A KVM/QEMU appliance is available as a Debian/squeeze system with Kameleon already installed. This allows you to test kameleon without risks. You just have to download the following compressed qcow2 image file:
# 64bits: # stable http://oar-ftp.imag.fr/kameleon/appliances/kameleon-appliance_1.2.8-1_squeeze_amd64.qcow2 # 32bits: # stable: http://oar-ftp.imag.fr/kameleon/appliances/kameleon-appliance_1.2.8-1_squeeze_i386.qcow
and start KVM:
# kvm -m 512 -hda kameleon-appliance_1.2.8-1_squeeze_amd64.qcow
To make a basic debian system, you can directly type into your running appliance:
# kameleon debia
Of course, as building an image requires a lot of I/Os, this appliance runs slower than a real system. Also be sure that you have enough free disk space on the partition where you store the image as it will grow (up to 5GB).
The appliance is also available as a vmdk (Vmware) image, but not tested (feedback welcome!):
# 64bits: http://oar-ftp.imag.fr/kameleon/appliances/kameleon-appliance_1.2.8-1_squeeze_amd64.vmdk.gz http://oar-ftp.imag.fr/kameleon/appliances/kameleon-appliance_1.2.8-1_squeeze_amd64.vmx # 32bits: http://oar-ftp.imag.fr/kameleon/appliances/kameleon-appliance_1.2.8-1_squeeze_i386.vmdk.gz http://oar-ftp.imag.fr/kameleon/appliances/kameleon-appliance_1.2.8-1_squeeze_i386.vm
You can find recipes and steps into 3 locations:
Finally, in every of those 3 locations, the steps directory contains subdirectories in which kameleon will search for the macrosteps yaml definitions. If you specify a my_step macrostep into a recipe, it is firstly searched into the steps/<distrib> subdirectory (where <distrib> is the value of the distrib global variable , then, if not found, into the steps/default subdirectory. You can use the dir/my_step notation into recipes to load a macrostep from another distrib.
The simplest way is to take a look at all the steps of the debian.yaml recipe. This recipe (including commented steps) uses almost every capability of kameleon and the code is self explanatory. You can also find a documentation into /usr/share/doc/kameleon/Documentation.rst.
“kameleon”. There may also be a “kameleon” user, with “kameleon” password that is in the sudo group.
Add more memory to your KVM instance (“kvm -m 512” should be enough)
We have 2 methods:
sudo modprobe nbd max_part=8 sudo qemu-nbd --connect=/dev/nbd0 kameleon1.0b-appliance-0.1-squeeze.qcow2 mount /dev/nbd0p1 /mnt sudo kvm -hda /mnt/var/tmp/kameleon/2010-xx-xx-xx-xx-xx/debian.qcow
# from the appliance: scp /var/tmp/kameleon/2010-xx-xx-xx-xx-xx/debian.qcow2 <user>@`ip route show|grep default|cut -d " " -f3`
No. Don't worry. We are not going to destroy your system This is just because we run sfdisk on an image file that is not a block device and we haven't find a way to prevent sfdisk to output such errors in spite it does the job.
The provided recipes require Grub2 version 1.98 or above on your host system (the one that you run kameleon on). We tried a fix for Grub2 1.97 (activate the grub_197_workaround microstep of the build_appliance macrostep) but it was not efficient for us. Tell us if you have more luck!
You can use our checkpoint/checkpoint_resume macrosteps. Do a first recipe that runs a checkpoint step where you want (you can uncomment the one we have already set into our provided recipes). It will create the file referenced by the global variable checkpoint_file. Then, on the next run, you can add the checkpoint_resume step in place of the bootstrap step and comment every step that should already have been done into your checkpoint file, except mount_proc and such steps that are required for other steps started later into your recipe. Here is an example of the step part of the debian.yaml recipe when using a checkpoint:
steps: - debian_check_deps - check_deps: - rsync - building_appliance - building_kvm_images # - oar/oar_precheck - checkpoint_resume # - bootstrap # - system_config # - network_config_static # - root_passwd - mount_proc # - software_install: # - extra_packages # - kernel_install # - checkpoint # - oar/oar_debian_install # - oar/oar_system_config - kameleon/kameleon_debian_install - strip - umount_proc [...]
It means that you are using a 32 bit system and your recipe is for 64 bit. Unfortunately, you can't build a 64 bits system from a 32 bits one. You probably have to set arch: i386 and kernel_arch: “686” into your recipe.
Some kameleon steps can mount or create special devices that may be left in an inconsistent state in case of an error or a break in the middle of an appliance generation. To prevent as much as possible from this, there's a special cleaning script that is automatically executed on exit. This script is automatically generated by using the exec_on_clean microstep commands. For example, if you have a microstep that creates a loopback device using:
- exec_chroot: losetup /dev/loop10 image.raw
you can add just after, the following microstep command:
- exec_on_clean: losetup -d /dev/loop1
On exit (normal exit, or on a failure), kameleon will execute all the exec_on_clean commands in the reverse order.
You can use the -redir option of KVM. Example:
kvm /var/tmp/kameleon/2010-05-03-13-23-52/debian.raw -redir tcp:2222::22 -redir tcp:8080::8
Then you can:
$ ssh -p 2222 kameleon@localhost # Or: $ wget -O - http://localhost:8080/oarapi/resources.yam
You just have to make a raw appliance (save_as_raw microstep of the build_appliance macrostep) and copy it to your LVM device:
dd bs=1M if=/var/tmp/kameleon/2010-05-04-14-15-06/debian.raw of=/dev/vg-noraid/kvm-idjant
Then, if your LVM device is bigger than the raw image (it should at least be the same size) boot your appliance, and from it, use fdisk to recreate the partitions, keeping the same order. Don't be afraid, your system should still boot. Reboot it, and from the appliance again, now, make:
resize2fs /dev/hda
so that the appliance filesystem will use all the space you gave to him in the new partitions scheme.
A context allows you to extend the microsteps commands. It may be used, for example, if you want to develop the steps from the inside of a running appliance, and then be able to switch to the appliance generation from a host just by changing your context. To define a new context, you have to create a contexts hash into the recipe. Here is an example:
contexts: root: cmd: chroot $$chroot %
This defines one context named “root”. The ** symbol will be replaced by the argument from the microstep at execution time. The context is used, in a microstep, as follow:
<code>
test_context:
- pwd:
- **exec_context: root** pw
</code>
For this example, it will exactly have the same effect as the following microstep:
<code>
test_context:
- pwd:
- **exec_chroot** pw
</code>
Both result in the following bash example command:
<code>
chroot /var/tmp/kameleon/2011-02-24-09-20-11/chroot pw
</code>
So, now, you can change for example, the root context with:
<code>
root:
cmd: ssh -T -n my-host "“
escape: \\
</code>
The pwd microstep will now result into:
<code>
ssh -T -n my-host “pwd
</code>
The escape field allows you to define a specific character to be escaped. Here, it will allow such microstep to work:
<code>
- exec_context: root echo “Hello World
</code>
You can define several contexts into the contexts** hash of the recipe. More examples may be found into the debian.yaml default recipe.
since the version 1.2.9, kameleon provides a two variables $$step_dir and $$recipe_dir. These variables contains the folder associated to the step/recipe.
For example, if you need to embed data associated the step '/home/user/kameleon/steps/config_my_software.yaml', you can put you data in the folder '/home/user/kameleon/steps/config_my_software/'. During the kameleon execution the variable $$step_dir will contain the path '/home/user/kameleon/steps/config_my_software/'.
You can process in the same way for the recipe: the data content associated to the recipe '/home/user/kameleon/recipes/my_recipe.yaml' can be put in the folder '/home/user/kameleon/recipes/my_recipe/' and during the kameleon execution the variuable $$recipe_dir will contain the path '/home/user/kameleon/recipes/my_recipe/'.
This mechanism is needed because, since kameleon supports potentially different source folder for recipe and step, the associated data path depends on the source folder path which is unknown before running kameleon.
Subscribe to the kameleon-users mailing list and feel free to ask your questions: http://lists.gforge.inria.fr/mailman/listinfo/kameleon-users
Initially developped by Darko Ilic during 2009 Google Summer of Code mentored by Yiannis Georgiou and Bruno Bzeznik (see http://wiki-oar.imag.fr/index.php/Kameleon_Page), it is now maintained by Bruno Bzeznik and the OAR team in general.