Recipe¶
Kameleon reads YAML files, named recipes, that describes how you will build your appliance. A recipe is a hierarchical structure of Section, Step, Microstep and Commands. Here is an overview of this structure:
recipe
`-- section
`-- step
`-- microstep
`-- command
The recipe also contains a set of Global variables declaration and some imports such as Aliases and Checkpoint.
Here is an example of a recipe:
#==============================================================================
# vim: softtabstop=2 shiftwidth=2 expandtab fenc=utf-8 cc=81 tw=80
#==============================================================================
#
# DESCRIPTION: Base template for Kameleon appliance.
#
#==============================================================================
---
extend: ../steps/backend/$${backend}.yaml
# Loads some helpful aliases (this files are located in steps/aliases/ directory)
aliases: defaults.yaml
# Custom shell environement (this files are located in steps/env/ directory)
env:
- bashrc
- functions.sh
# Global variables use by Kameleon engine and the steps
global:
## Select backend for in context isolation
backend: qemu
## User varibales : used by the recipe
user_name: kameleon
user_password: $${user_name}
root_password: $${user_name}
user_groups: sudo
default_keyboard_layout: "us,fr,de"
default_locales: POSIX C en_US fr_FR de_DE
default_lang: en_US.UTF-8
default_timezone: UTC
appliance_tar_compression_level: "9"
## Initial rootfs archive built with kameleon
## See https://github.com/oar-team/kameleon-bootstrap-recipes.git
rootfs_archive_url: http://kameleon.imag.fr/rootfs/$${arch}/$${distrib}$${release_number}.tar.xz
rootfs_archive_download_path: $${kameleon_cwd}/rootfs.tar.xz
# rootfs options
rootfs: $${kameleon_cwd}/rootfs
# Distribution
arch: x86_64
hostname: kameleon-$${distrib}
# output appliance options
filesystem_type: ext4
image_size: 10G
image_disk: $${kameleon_cwd}/base_$${kameleon_recipe_name}
# Allowed formats are: tar.gz, tar.bz2, tar.xz, tar.lzo, qcow, qcow2, qed, vdi, raw, vmdk
appliance_formats: qcow2 tar.gz
appliance_filename: "$${kameleon_cwd}/$${kameleon_recipe_name}"
appliance_tar_excludes: >-
./etc/fstab ./root/.bash_history ./root/kameleon_workdir ./root/.ssh
./var/tmp/* ./tmp/* ./var/log/* ./dev/* ./proc/* ./run/*
./sys/*
## System variables. Required by kameleon engine
# Include specific steps
include_steps:
- $${distrib}/$${release}
- $${distrib}
# E.g: net.ifnames=0 console=tty0 console=ttyS0,115200n8
kernel_args: "quiet net.ifnames=0 biosdevname=0"
bootstrap:
- "@base"
# Install and configuration steps
setup:
# Install
- upgrade_system
- install_software:
- packages: $${setup_packages}
# Configuration
- configure_system:
- locales: $${default_locales}
- lang: $${default_lang}
- timezone: $${default_timezone}
- configure_keyboard:
# set to english keyboard use 'localectl list-keymaps' to see available list
- layout: $${default_keyboard_layout}
- configure_network
- kameleon_customization
- create_user:
- name: $${user_name}
- groups: $${user_groups}
- password: $${user_name}
- clean_system
export:
- "@base"
Section¶
Each section is a group of steps. Currently, there are 3 sections:
- bootstrap
This section contains the bootstrap of the new system and create the in context (see Context).
- setup
Installs and configures steps.
- export
Exports the generated appliance in the desired format.
Step and microstep¶
Each step contains a list of microsteps itself containing a list of Commands
written in one YAML file. To be found by Kameleon, this file must be named
by the step name plus the YAML extension .yaml
. For example the
software_install.yaml
step file looks like this:
# Software Install
- add_contribs_source:
- exec_in: perl -pi -e "s/main$/main contrib non-free/" /etc/apt/sources.list
- update_repositories:
- exec_in: apt-get -y --force-yes update
- upgrade_system:
- exec_in: apt-get -y --force-yes dist-upgrade
- clean:
- on_export_init:
- exec_in: apt-get -y --force-yes autoclean
- exec_in: apt-get -y --force-yes clean
- exec_in: apt-get -y --force-yes autoremove
# default packages
- packages: "ntp sudo"
- install_extra_packages:
- exec_in: apt-get -y --force-yes install $${packages}
A step will be called like a function in the recipe. You should provide a set of local variables if needed by the step or to override default variables (see Variables). Optionally, you can select only some microsteps to execute. Here is an example of step call:
- software_install:
- packages: "debian-keyring ntp zip unzip rsync sudo"
- add_contribs_source
- update_repositories
- clean
- install_extra_packages
Steps path¶
The steps are YAML formated files stored in the steps
directory which is
located in the same directory as the recipe. To enable a better recipe reuse
and ease of write, the steps are stored by default in specific folders
depending on the sections.
Kameleon is looking for the steps files using the include_steps
list value,
if it is set in the recipe (NOT mandatory). For example, if you are building an
ubuntu based distribution you can use:
include_steps:
- ubuntu
- debian/wheezy
- debian
It also searches uppermost within the current section folder. In the previous example, in the bootstrap section, the search paths are scanned in this order:
steps/bootstrap/ubuntu
steps/ubuntu
steps/bootstrap/debian/wheezy
steps/debian/wheezy
steps/bootstrap/debian
steps/debian
steps/bootstrap/
steps/
Variables¶
Kameleon is using preprocessed variables. You can define it with the YAML
key/value syntax my_var: my_value
.To access these variables, you have to
use the two dollar ($$
) prefix. Like in a Shell you can also use
$${var_name}
to include your variables in string like this
my-$${variable_name}-templated
. It is also possible to use nested variables
like:
my_var: foo
my_nested_var: $${my_var}-bar
Be careful, in YAML you cannot mix dictionary and list on the same level.
That’s why, in the global dictionary, you can define your variables as
indicated in the example above but, in the recipe or the steps, you must prefix
your variable with a -
like this - my_var: foo
.
Global variables¶
Global variables are defined in the global
dictionary of the recipe.
Kameleon use some global variables to enable the appliance build. See
Context and Steps path for more details.
You can also override a variable using inheritance mechanism or CLI
--global
option with one or more key:values. For Example:
kameleon build --global my_package:'vim git' user_name:myself myrecipe.yaml
Or in your recipe:
global:
# kameleon is too long to type!
user_name: myself
New in version 2.7.0.
You can even overload variable (adding content to existing value) using the same syntax as bash:
kameleon build --global setup_packages:'$${setup_packages} git emacs' myrecipe.yaml
Or in your recipe:
global:
# I need these tools
setup_packages: $${setup_packages} git emacs
For more information about inheritance variable see here: Inheritance and variables
Step local variables¶
In the recipe, you can provide some variables when you call a step. This variable override the global and the default variables.
setup:
- add_user:
- name: foo
- add_user:
- name: bar
Step default variables¶
In the step file, you can define some default variables for your microsteps. Be careful, to avoid some mistakes, these variables can be overridden by the step local variables but not by the global ones. If this is the behavior you expected, just add a step local variable that can be assigned by the global variable value:
global:
foo: bar
setup:
- my_step:
- foo: $${foo}
Kameleon variables¶
It is possible to access some variables created by Kameleon from the recipe. They are used to contextualize the execution of a recipe in a given environment.
- kameleon_recipe_name
The recipe name (eg. my_debian8)
- kameleon_recipe_dir
Directory where the recipe is located (eg. ~/recipes)
- kameleon_data_dir
Directory the is watch by the cache mechanism: Each local file that is used during the build should be located here. See Data for more information.
- kameleon_cwd
Current recipe of Kameleon during the build (eg. ~/recipes/build/my_debian8)
- kameleon_uuid
Unique identifier of a Kameleon build. (eg. 33fb8999-bbd3-4bc5-badd-93983b14555d)
- kameleon_short_uuid
Shorter version of the identifier, basically the end of the uuid. (eg. 93983b14555d)
- checkpointing_enabled
‘true’ if the checkpointing mechanism is enabled for the build, otherwise ‘false’.
- persistent_cache
‘true’ if the cache mechanism is enabled for the build, otherwise ‘false’.
Data¶
File that are stored in steps/data/
of your recipe, or of a recipe
it extends, can be access with the built-in variable
$${kameleon_data_dir}
. The advantage of this mechanism over a simple copy
from one context to an other is twofold:
All the artefact used to produce your recipe are stored inside you Kameleon workspace and the persistent cache is caching everything that is located on these directories.
You can override any artifacts inherited from a parent recipe by providing an other file that as the same name in the
steps/data/
folder of the child recipe.
Warning
You MUST use this directory if you want to cache any data that is not coming from the web.
An example is better than long sentences, so here is an example:
By default, some Kameleon recipes gives you a .bashrc
file that
customize you prompt and add some aliases, but you have your own
built-over-the-years bash configuration file and you want all your images
to have it. To do so, just override the skel/.bashrc
that is used by
the kameleon_customization.yaml
step in your data folder:
# where your recipe is:
mkdir -p steps/data/skel
cp ~/.bashrc steps/data/skel
And that’s it! When you will build your recipe all your aliases and pretty prompt colors will be there :)