kameleon-builder 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.editorconfig +0 -0
- data/.env +63 -15
- data/.gitignore +1 -0
- data/README.rst +4 -2
- data/Vagrantfile +13 -52
- data/bin/kameleon +5 -0
- data/completion/_kameleon.zsh +18 -0
- data/completion/kameleon.bash +13 -0
- data/completion/kameleon.fish +10 -0
- data/contrib/polipo_env.sh +2 -0
- data/contrib/steps/export/save_as_g5k.yaml +63 -0
- data/contrib/steps/setup/add_to_sudoers.yaml +5 -0
- data/docs/Makefile +10 -6
- data/docs/README.md +17 -0
- data/docs/source/_static/kameleon-logo.png +0 -0
- data/docs/source/_static/kameleon-logo.xcf +0 -0
- data/docs/source/_static/kameleon-long.png +0 -0
- data/docs/source/aliases.rst +4 -2
- data/docs/source/checkpoint.rst +2 -0
- data/docs/source/commands.rst +4 -3
- data/docs/source/conf.py +15 -7
- data/docs/source/context.rst +7 -4
- data/docs/source/faq.rst +39 -1
- data/docs/source/getting_started.rst +227 -1
- data/docs/source/grid5000_tutorial.rst +110 -0
- data/docs/source/index.rst +7 -2
- data/docs/source/installation.rst +12 -4
- data/docs/source/persistent_cache.rst +34 -0
- data/docs/source/recipe.rst +23 -16
- data/docs/source/use_cases.rst +93 -0
- data/docs/source/workspace.rst +2 -0
- data/kameleon-builder.gemspec +7 -1
- data/lib/kameleon.rb +3 -6
- data/lib/kameleon/cli.rb +104 -50
- data/lib/kameleon/compat.rb +39 -0
- data/lib/kameleon/context.rb +43 -13
- data/lib/kameleon/engine.rb +118 -77
- data/lib/kameleon/environment.rb +3 -5
- data/lib/kameleon/error.rb +15 -9
- data/lib/kameleon/logger.rb +7 -4
- data/lib/kameleon/persistent_cache.rb +139 -0
- data/lib/kameleon/recipe.rb +200 -81
- data/lib/kameleon/shell.rb +51 -16
- data/omnibus/.gitignore +11 -0
- data/omnibus/.kitchen.yml +25 -0
- data/omnibus/Berksfile +9 -0
- data/omnibus/Berksfile.lock +25 -0
- data/omnibus/Gemfile +12 -0
- data/omnibus/README.md +94 -0
- data/omnibus/config/projects/kameleon.rb +23 -0
- data/omnibus/config/software/kameleon.rb +24 -0
- data/omnibus/config/software/polipo.rb +30 -0
- data/omnibus/config/software/ruby.rb +158 -0
- data/omnibus/files/mac_dmg/Resources/background.png +0 -0
- data/omnibus/files/mac_dmg/Resources/icon.png +0 -0
- data/omnibus/files/mac_pkg/Resources/background.png +0 -0
- data/omnibus/files/mac_pkg/Resources/license.html +1 -0
- data/omnibus/files/mac_pkg/Resources/welcome.html +9 -0
- data/omnibus/omnibus.rb +27 -0
- data/omnibus/package-scripts/kameleon/makeselfinst +27 -0
- data/omnibus/package-scripts/kameleon/postrm +9 -0
- data/templates/archlinux-desktop.yaml +25 -0
- data/templates/archlinux.yaml +106 -0
- data/templates/debian-testing.yaml +25 -0
- data/templates/debian7-desktop.yaml +25 -0
- data/templates/{debian-wheezy-docker.yaml → debian7-docker.yaml} +30 -16
- data/templates/debian7-g5k.yaml +97 -0
- data/templates/debian7-oar-dev.yaml +51 -0
- data/templates/debian7.yaml +128 -0
- data/templates/extend.erb +23 -0
- data/templates/fedora-rawhide.yaml +30 -0
- data/templates/fedora20-desktop.yaml +21 -0
- data/templates/fedora20.yaml +105 -0
- data/templates/{debian-wheezy-chroot.yaml → old-debian7.yaml} +51 -38
- data/templates/{aliases → steps/aliases}/defaults.yaml +37 -12
- data/templates/steps/bootstrap/archlinux/arch_bootstrap.yaml +219 -0
- data/templates/steps/bootstrap/archlinux/install_bootloader.yaml +46 -0
- data/templates/steps/bootstrap/archlinux/populate_disk.yaml +39 -0
- data/templates/steps/bootstrap/debian/debootstrap.yaml +18 -10
- data/templates/steps/bootstrap/debian/debootstrap_arm.yaml +31 -0
- data/templates/steps/bootstrap/fedora/liveos_bootstrap.yaml +123 -0
- data/templates/steps/bootstrap/g5k_reserv.yaml +70 -0
- data/templates/steps/bootstrap/initialize_disk_chroot.yaml +84 -0
- data/templates/steps/bootstrap/initialize_disk_qemu.yaml +72 -0
- data/templates/steps/bootstrap/install_bootloader.yaml +42 -0
- data/templates/steps/bootstrap/prepare_chroot.yaml +126 -0
- data/templates/steps/bootstrap/prepare_docker.yaml +19 -8
- data/templates/steps/bootstrap/prepare_qemu.yaml +47 -0
- data/templates/steps/bootstrap/start_chroot.yaml +11 -2
- data/templates/steps/bootstrap/start_docker.yaml +2 -2
- data/templates/steps/bootstrap/start_qemu.yaml +75 -0
- data/templates/steps/bootstrap/ubuntu/debootstrap.yaml +27 -0
- data/templates/steps/breakpoint.yaml +2 -0
- data/templates/{checkpoints → steps/checkpoints}/docker.yaml +0 -0
- data/templates/steps/checkpoints/qcow2.yaml +38 -0
- data/templates/steps/checkpoints/qemu.yaml +39 -0
- data/templates/steps/export/clean_appliance.yaml +7 -1
- data/templates/steps/export/compact_qcow_img.yaml +12 -0
- data/templates/steps/export/save_appliance.yaml +58 -0
- data/templates/steps/export/save_appliance_from_g5k.yaml +47 -0
- data/templates/steps/export/save_vagrant_box.yaml +29 -0
- data/templates/steps/setup/archlinux/configure_keyboard.yaml +9 -0
- data/templates/steps/setup/archlinux/configure_network.yaml +9 -0
- data/templates/steps/setup/archlinux/configure_ruby.yaml +7 -0
- data/templates/steps/setup/archlinux/configure_system.yaml +20 -0
- data/templates/steps/setup/archlinux/install_dev_tools.yaml +18 -0
- data/templates/steps/setup/archlinux/install_gnome.yaml +27 -0
- data/templates/steps/setup/archlinux/install_software.yaml +9 -0
- data/templates/steps/setup/archlinux/install_yaourt.yaml +29 -0
- data/templates/steps/setup/autologin.yaml +16 -0
- data/templates/steps/setup/create_group.yaml +12 -0
- data/templates/steps/setup/create_user.yaml +9 -10
- data/templates/steps/setup/debian/configure_apt.yaml +65 -0
- data/templates/steps/setup/debian/configure_kernel.yaml +18 -0
- data/templates/steps/setup/debian/{keyboard_config.yaml → configure_keyboard.yaml} +1 -1
- data/templates/steps/setup/debian/{network_config.yaml → configure_network.yaml} +0 -0
- data/templates/steps/setup/debian/{system_config.yaml → configure_system.yaml} +0 -0
- data/templates/steps/setup/debian/install_gnome.yaml +13 -0
- data/templates/steps/setup/debian/install_kde.yaml +13 -0
- data/templates/steps/setup/debian/install_software.yaml +2 -0
- data/templates/steps/setup/debian/oar/oar_debian_config_frontend.yaml +8 -0
- data/templates/steps/setup/debian/oar/oar_debian_config_node.yaml +5 -0
- data/templates/steps/setup/debian/oar/oar_debian_config_server.yaml +5 -0
- data/templates/steps/setup/debian/oar/oar_prereq_install.yaml +16 -0
- data/templates/steps/setup/debian/setup_vagrant_box.yaml +52 -0
- data/templates/steps/setup/debian/upgrade_system.yaml +15 -0
- data/templates/steps/setup/fedora/configure_network.yaml +30 -0
- data/templates/steps/setup/fedora/configure_system.yaml +59 -0
- data/templates/steps/setup/fedora/install_software.yaml +3 -0
- data/templates/steps/setup/fedora/update_system.yaml +10 -0
- data/templates/steps/setup/oar/oar_config_devel.yaml +21 -0
- data/templates/steps/setup/oar/oar_config_frontend.yaml +38 -0
- data/templates/steps/setup/oar/oar_config_node.yaml +4 -0
- data/templates/steps/setup/oar/oar_config_server.yaml +25 -0
- data/templates/steps/setup/oar/oar_config_system.yaml +34 -0
- data/templates/steps/setup/oar/oar_devel_prereq_install.yaml +5 -0
- data/templates/steps/setup/oar/oar_git_install.yaml +21 -0
- data/templates/steps/setup/ubuntu/configure_apt.yaml +67 -0
- data/templates/ubuntu-12.04-desktop.yaml +25 -0
- data/templates/ubuntu-12.04.yaml +128 -0
- data/templates/ubuntu-14.04-desktop.yaml +27 -0
- data/templates/ubuntu-14.04.yaml +25 -0
- data/templates/vagrant-debian7.yaml +31 -0
- data/version.txt +1 -1
- metadata +155 -28
- checksums.yaml +0 -7
- data/templates/checkpoints/qcow2.yaml +0 -44
- data/templates/fedora-docker.yaml +0 -96
- data/templates/steps/bootstrap/fedora/docker_bootstrap.yaml +0 -25
- data/templates/steps/bootstrap/fedora/yum_bootstrap.yaml +0 -22
- data/templates/steps/bootstrap/prepare_appliance_with_nbd.yaml +0 -93
- data/templates/steps/export/build_appliance_from_docker.yaml +0 -105
- data/templates/steps/export/save_appliance_from_nbd.yaml +0 -54
- data/templates/steps/setup/debian/kernel_install.yaml +0 -20
- data/templates/steps/setup/debian/software_install.yaml +0 -15
- data/templates/steps/setup/fedora/kernel_install.yaml +0 -27
- data/templates/steps/setup/fedora/software_install.yaml +0 -10
data/docs/source/index.rst
CHANGED
@@ -10,6 +10,9 @@ Welcome to Kameleon's documentation!
|
|
10
10
|
.. note::
|
11
11
|
This documentation is currently being written...
|
12
12
|
|
13
|
+
.. image:: _static/kameleon-long.png
|
14
|
+
:align: right
|
15
|
+
|
13
16
|
-----
|
14
17
|
About
|
15
18
|
-----
|
@@ -17,7 +20,7 @@ About
|
|
17
20
|
Kameleon should be seen as a simple but powerful tool to generate customized
|
18
21
|
appliances. With Kameleon, you make your recipe that describes how to create
|
19
22
|
step by step your own distribution. At start Kameleon is used to create custom
|
20
|
-
kvm,
|
23
|
+
kvm, docker, VirtualBox, ..., but as it is designed to be very generic
|
21
24
|
you can probably do a lot more than that.
|
22
25
|
|
23
26
|
|
@@ -31,13 +34,16 @@ User Documentation
|
|
31
34
|
|
32
35
|
installation.rst
|
33
36
|
getting_started.rst
|
37
|
+
use_cases.rst
|
34
38
|
recipe.rst
|
35
39
|
context.rst
|
36
40
|
commands.rst
|
37
41
|
workspace.rst
|
38
42
|
checkpoint.rst
|
43
|
+
persistent_cache.rst
|
39
44
|
aliases.rst
|
40
45
|
faq.rst
|
46
|
+
grid5000_tutorial.rst
|
41
47
|
|
42
48
|
Indices and tables
|
43
49
|
==================
|
@@ -45,4 +51,3 @@ Indices and tables
|
|
45
51
|
* :ref:`genindex`
|
46
52
|
* :ref:`modindex`
|
47
53
|
* :ref:`search`
|
48
|
-
|
@@ -1,7 +1,8 @@
|
|
1
1
|
------------
|
2
2
|
Installation
|
3
3
|
------------
|
4
|
-
|
4
|
+
.. note::
|
5
|
+
On debian based distribution be sure to install the ``ruby-dev`` package first
|
5
6
|
|
6
7
|
To install the latest release from `RubyGems`_:
|
7
8
|
|
@@ -11,11 +12,18 @@ To install the latest release from `RubyGems`_:
|
|
11
12
|
|
12
13
|
gem install kameleon-builder --pre
|
13
14
|
|
14
|
-
Or from source
|
15
|
-
|
16
|
-
::
|
15
|
+
Or from source::
|
17
16
|
|
18
17
|
git clone https://github.com/oar-team/kameleon.git
|
19
18
|
cd kameleon
|
20
19
|
gem build kameleon-builder.gemspec
|
21
20
|
gem install kameleon-builder-<version>.gem
|
21
|
+
|
22
|
+
|
23
|
+
Any troubles?
|
24
|
+
~~~~~~~~~~~~~
|
25
|
+
If you got an error message like this one::
|
26
|
+
|
27
|
+
``/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- mkmf (LoadError)``
|
28
|
+
|
29
|
+
It's because you need the ``ruby-dev`` package to fit the dependancies.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
.. _`persistent_cache`:
|
2
|
+
|
3
|
+
----------------
|
4
|
+
Persistent Cache
|
5
|
+
----------------
|
6
|
+
|
7
|
+
.. versionadded:: 2.0.1
|
8
|
+
|
9
|
+
In order to exactly reconstruct a software appliance with the same exact
|
10
|
+
version of packages. Kameleon offer the option of creating a persistent cache
|
11
|
+
that will catch all the software packages during the building of the software
|
12
|
+
appliance. Enabling other to reconstruct the same exact software appliance
|
13
|
+
with the right package versions. Kameleon uses Polipo [1]_ which is a tiny and
|
14
|
+
lightweight web proxy to cache most of the packages that comes form the
|
15
|
+
network. First of all, you have to install Polipo on your system. If you are
|
16
|
+
under a debian distribution you can install it using the package manager::
|
17
|
+
|
18
|
+
sudo apt-get install polipo
|
19
|
+
|
20
|
+
You can as well build it from sources and then specify the path of the
|
21
|
+
generated binary using the option ``--proxy_path``. To use, you just have to
|
22
|
+
add the option ``--cache`` as an argument of the build command.
|
23
|
+
For example::
|
24
|
+
|
25
|
+
kameleon build debian_test -b /tmp/kameleon/ --cache
|
26
|
+
|
27
|
+
This will create a tar file in the build directory ``/tmp/kameleon`` called
|
28
|
+
``debian_test-cache.tar``. In order to use this generated cache file in
|
29
|
+
another build, we have just to use the options ``--from_cache`` as follows::
|
30
|
+
|
31
|
+
kameleon build debian_test -b /tmp/kameleon/ --from_cache /tmp/debian_test-cache.tar
|
32
|
+
|
33
|
+
|
34
|
+
.. [1] http://www.pps.univ-paris-diderot.fr/~jch/software/polipo/
|
data/docs/source/recipe.rst
CHANGED
@@ -3,20 +3,24 @@ Recipe
|
|
3
3
|
------
|
4
4
|
|
5
5
|
Kameleon compute YAML files, named *recipes*, that describes how you will
|
6
|
-
build your appliance. These files are stored in the root of your
|
7
|
-
A recipe is a hierarchical structure of `
|
8
|
-
|
6
|
+
build your appliance. These files are stored in the root of your :ref:`workspace`.
|
7
|
+
A recipe is a hierarchical structure of `Section`_, `Step`_, `Microstep`_ and
|
8
|
+
:ref:`commands`. Here is an overview of this structure:
|
9
9
|
|
10
10
|
.. code-block:: yaml
|
11
11
|
|
12
12
|
recipe
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
|
|
14
|
+
`-- section
|
15
|
+
|
|
16
|
+
`-- step
|
17
|
+
|
|
18
|
+
`-- microstep
|
19
|
+
|
|
20
|
+
`-- command
|
17
21
|
|
18
22
|
The recipe also contains set of `Global variables`_ declaration and some
|
19
|
-
imports like `
|
23
|
+
imports like :ref:`aliases` and :ref:`checkpoint`.
|
20
24
|
|
21
25
|
This is an example of a recipe:
|
22
26
|
|
@@ -89,7 +93,7 @@ This is an example of a recipe:
|
|
89
93
|
- system_config:
|
90
94
|
- locales: fr_FR en_US
|
91
95
|
- lang: fr_FR.UTF-8
|
92
|
-
- timezone:
|
96
|
+
- timezone: UTC
|
93
97
|
- keyboard_config:
|
94
98
|
- layout: "fr,us"
|
95
99
|
- network_config:
|
@@ -112,11 +116,11 @@ This is an example of a recipe:
|
|
112
116
|
Section
|
113
117
|
-------
|
114
118
|
|
115
|
-
Each section is a list of
|
119
|
+
Each section is a list of steps. Currently, there is 3 sections:
|
116
120
|
|
117
121
|
bootstrap
|
118
122
|
This section contains the bootstrap of the new system and create the *in*
|
119
|
-
context (see `
|
123
|
+
context (see :ref:`context`).
|
120
124
|
|
121
125
|
setup
|
122
126
|
This one is dedicated to the install and configuration steps.
|
@@ -125,10 +129,13 @@ export
|
|
125
129
|
Export the generated appliance in the format of your choice.
|
126
130
|
|
127
131
|
|
128
|
-
|
129
|
-
|
132
|
+
.. _`step`:
|
133
|
+
.. _`microstep`:
|
130
134
|
|
131
|
-
|
135
|
+
Step and microstep
|
136
|
+
-------------------
|
137
|
+
|
138
|
+
Each *step* contains a list of *microsteps* that contains a list of :ref:`commands`
|
132
139
|
written in one YAML file. To be found by Kameleon this file must be named by
|
133
140
|
with the step name plus the YAML extension ``.yaml``. For example the
|
134
141
|
``software_install.yaml`` step file looks like this:
|
@@ -171,7 +178,7 @@ Steps path
|
|
171
178
|
~~~~~~~~~~
|
172
179
|
|
173
180
|
The steps are YAML formated files stored in the ``recipe/steps`` directory of
|
174
|
-
the
|
181
|
+
the :ref:`workspace`. To enable a better recipe reuse and ease of write the steps
|
175
182
|
are stored by default in specific folders depending on the sections.
|
176
183
|
|
177
184
|
Kameleon is looking for the steps files using the ``include_steps`` list value,
|
@@ -227,7 +234,7 @@ Global variables
|
|
227
234
|
~~~~~~~~~~~~~~~~~
|
228
235
|
|
229
236
|
Global variables are defined in the ``global`` dictionary of the recipe.
|
230
|
-
Kameleon use some global variable to enable the appliance build. See
|
237
|
+
Kameleon use some global variable to enable the appliance build. See :ref:`context`
|
231
238
|
and `Steps path`_ for more details
|
232
239
|
|
233
240
|
|
@@ -0,0 +1,93 @@
|
|
1
|
+
.. _`use cases`:
|
2
|
+
|
3
|
+
---------
|
4
|
+
Use Cases
|
5
|
+
---------
|
6
|
+
|
7
|
+
Here it is described different use cases for Kameleon. It should give you a better
|
8
|
+
idea, through examples, of how Kameleon is useful for.
|
9
|
+
|
10
|
+
Distribute an environnement to your co-workers/students/friends/...
|
11
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
12
|
+
Whit Kameleon you can easily export your environnement in any format. The
|
13
|
+
export section of the recipe is made for this. For example, if you would like
|
14
|
+
to export your image in vdi format to use VirtualBox you just have to uncomment
|
15
|
+
the right line. Like in the debian7 template::
|
16
|
+
|
17
|
+
#== Export the generated appliance in the format of your choice
|
18
|
+
export:
|
19
|
+
- save_appliance_from_nbd:
|
20
|
+
- mountdir: $$rootfs
|
21
|
+
- filename: "$${kameleon_recipe_name}"
|
22
|
+
- save_as_qcow2
|
23
|
+
# - save_as_qed
|
24
|
+
# - save_as_tgz
|
25
|
+
# - save_as_raw
|
26
|
+
# - save_as_vmdk
|
27
|
+
- save_as_vdi
|
28
|
+
|
29
|
+
Make a Linux virtual machine with graphical support
|
30
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
31
|
+
You can directly use the templates that provide a desktop. However, here is an
|
32
|
+
example of adding desktop capability to the ``debian8`` template. First create
|
33
|
+
a new recipe from this template::
|
34
|
+
|
35
|
+
kameleon new debian8-dektop -t debian8
|
36
|
+
|
37
|
+
Then edit the recipe file ``debian8-dektop.yaml`` and add ``gnome-core`` and ``xorg``
|
38
|
+
packages to the install list::
|
39
|
+
|
40
|
+
setup:
|
41
|
+
# Install
|
42
|
+
- software_install:
|
43
|
+
- packages: >
|
44
|
+
debian-keyring ntp zip unzip rsync sudo less vim bash-completion
|
45
|
+
gnome-core xorg
|
46
|
+
|
47
|
+
These packages take some extra space, so add some space on the disk. 4G should
|
48
|
+
be enough::
|
49
|
+
|
50
|
+
bootstrap:
|
51
|
+
...
|
52
|
+
- create_disk_nbd:
|
53
|
+
- image_size: 4G
|
54
|
+
|
55
|
+
Build your recipe::
|
56
|
+
|
57
|
+
sudo kameleon build debian8-desktop
|
58
|
+
|
59
|
+
When the build has finished, you can try you image with Qemu::
|
60
|
+
|
61
|
+
sudo qemu-system-x86_64 -m 1024 --enable-kvm -vga std \
|
62
|
+
builds/debian8-desktop/debian8-desktop.qcow2
|
63
|
+
|
64
|
+
Alternatively, you could use ``virt-manager`` that provide a good GUI to manage
|
65
|
+
your virtual machines.
|
66
|
+
|
67
|
+
.. note::
|
68
|
+
If you want a better integration between the host and the guest like
|
69
|
+
copy/paste use ``spice`` (http://www.linux-kvm.org/page/SPICE)
|
70
|
+
|
71
|
+
|
72
|
+
Create a fully reproducible experimental environement
|
73
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
74
|
+
You should use the :ref:`persistent_cache` feature.
|
75
|
+
|
76
|
+
.. todo::
|
77
|
+
Give a complete use case.
|
78
|
+
|
79
|
+
Create a persistent live USB key
|
80
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
81
|
+
A dirty but reliable method to do this is to cat the entire raw disk on the USB
|
82
|
+
key. First be sure that the disk size is equal or smaller then your
|
83
|
+
Then, export you image in raw format (this is the disk content bit by bit) and
|
84
|
+
dump it to your USB key. Once your image is built, if your USB key is the
|
85
|
+
``/dev/sdb`` device, be sure that it is not mounted and just do this::
|
86
|
+
|
87
|
+
cat my_image.raw > /dev/my_key
|
88
|
+
|
89
|
+
.. warning::
|
90
|
+
This is a dangerous operation, you usb key will erase without
|
91
|
+
warning! Be sure that you pick the right device (use lsblk): it should be
|
92
|
+
``/dev/sdX`` where X is a letter. Do NOT use the ``dev/sdXY``. unmount it
|
93
|
+
and use the root device instead.
|
data/docs/source/workspace.rst
CHANGED
data/kameleon-builder.gemspec
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
RUBYONEX = RUBY_VERSION < "2.0"
|
3
|
+
|
2
4
|
lib = File.expand_path('../lib', __FILE__)
|
3
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
6
|
require 'kameleon/version'
|
@@ -24,10 +26,14 @@ Gem::Specification.new do |s|
|
|
24
26
|
s.test_files = s.files.grep(%r{^(tests|s|features)/})
|
25
27
|
s.require_paths = ["lib"]
|
26
28
|
|
27
|
-
s.
|
29
|
+
s.required_ruby_version = RUBYONEX ? '>= 1.9.3' : '>= 2.0.0'
|
30
|
+
|
31
|
+
s.add_dependency 'childprocess', '~> 0.5'
|
28
32
|
s.add_dependency 'thor', '~> 0.15'
|
29
33
|
s.add_dependency 'table_print', '~> 1.5'
|
30
34
|
s.add_dependency 'log4r-color', '~> 1.2'
|
35
|
+
s.add_dependency 'syck', '~> 1.0.0' unless RUBYONEX
|
36
|
+
s.add_dependency 'diffy', '~> 3.0.4'
|
31
37
|
|
32
38
|
s.add_development_dependency 'pry', '~> 0.9'
|
33
39
|
s.add_development_dependency 'pry-debugger', '~> 0.2'
|
data/lib/kameleon.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'securerandom'
|
2
|
-
require 'yaml'
|
3
1
|
require 'fileutils'
|
4
2
|
require 'optparse'
|
5
3
|
require 'erb'
|
@@ -12,11 +10,9 @@ require 'log4r-color'
|
|
12
10
|
require 'log4r-color/configurator'
|
13
11
|
require 'pathname'
|
14
12
|
require 'table_print'
|
13
|
+
require 'diffy'
|
15
14
|
|
16
15
|
module Kameleon
|
17
|
-
# to force yaml to dump ASCII-8Bit strings as strings
|
18
|
-
YAML::ENGINE.yamler='syck'
|
19
|
-
|
20
16
|
# add a PROGRESS and NOTICE level
|
21
17
|
Log4r::Configurator.custom_levels(:DEBUG, :INFO, :NOTICE,
|
22
18
|
:PROGRESS, :WARN, :ERROR,
|
@@ -56,7 +52,7 @@ module Kameleon
|
|
56
52
|
end
|
57
53
|
|
58
54
|
def logger
|
59
|
-
@logger ||= Log4r::Logger.new("kameleon::[
|
55
|
+
@logger ||= Log4r::Logger.new("kameleon::[kameleon]")
|
60
56
|
end
|
61
57
|
|
62
58
|
def env
|
@@ -67,6 +63,7 @@ module Kameleon
|
|
67
63
|
end
|
68
64
|
|
69
65
|
# Load the things which must be loaded before anything else
|
66
|
+
require 'kameleon/compat'
|
70
67
|
require 'kameleon/utils'
|
71
68
|
require 'kameleon/error'
|
72
69
|
require 'kameleon/cli'
|
data/lib/kameleon/cli.rb
CHANGED
@@ -5,40 +5,62 @@ require 'kameleon/utils'
|
|
5
5
|
module Kameleon
|
6
6
|
class CLI < Thor
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
class_option :color, :type => :boolean, :default => true,
|
10
|
+
:desc => "Enable colorization in output"
|
10
11
|
class_option :debug, :type => :boolean, :default => false,
|
11
12
|
:desc => "Enable debug output"
|
12
|
-
|
13
|
-
|
14
|
-
'(The folder containing your recipes folder).' \
|
15
|
-
' Default : ./'
|
13
|
+
map %w(-h --help) => :help
|
14
|
+
|
16
15
|
no_commands do
|
17
16
|
def logger
|
18
|
-
@logger ||= Log4r::Logger.new("kameleon::[
|
17
|
+
@logger ||= Log4r::Logger.new("kameleon::[kameleon]")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
method_option :force,:type => :boolean,
|
22
|
+
:default => false, :aliases => "-f",
|
23
|
+
:desc => "Overwrite all existing files"
|
24
|
+
desc "import [TEMPLATE_NAME]", "Imports the given template"
|
25
|
+
def import(template_name)
|
26
|
+
templates_path = Kameleon.env.templates_path
|
27
|
+
template_path = File.join(templates_path, template_name) + '.yaml'
|
28
|
+
begin
|
29
|
+
template_recipe = RecipeTemplate.new(template_path)
|
30
|
+
rescue
|
31
|
+
raise TemplateNotFound, "Template '#{template_name}' not found. " \
|
32
|
+
"To see all templates, run the command "\
|
33
|
+
"`kameleon templates`"
|
34
|
+
else
|
35
|
+
logger.notice("Importing template '#{template_name}'...")
|
36
|
+
template_recipe.copy_template(options[:force])
|
37
|
+
logger.notice("done")
|
19
38
|
end
|
20
39
|
end
|
21
40
|
|
22
|
-
method_option :template, :aliases => "-t",
|
23
|
-
:desc => "Starting from a template", :required => true,
|
24
|
-
:enum => Kameleon.templates_names
|
25
41
|
method_option :force,:type => :boolean,
|
26
42
|
:default => false, :aliases => "-f",
|
27
|
-
:desc => "
|
28
|
-
desc "new [RECIPE_NAME]", "Creates a new recipe"
|
29
|
-
def new(recipe_name)
|
30
|
-
|
43
|
+
:desc => "Overwrite all existing files"
|
44
|
+
desc "new [RECIPE_NAME] [TEMPLATE_NAME]", "Creates a new recipe"
|
45
|
+
def new(recipe_name, template_name)
|
46
|
+
if recipe_name == template_name
|
47
|
+
fail RecipeError, "Recipe name should be different from template name"
|
48
|
+
end
|
31
49
|
templates_path = Kameleon.env.templates_path
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
50
|
+
template_path = File.join(templates_path, template_name) + '.yaml'
|
51
|
+
begin
|
52
|
+
template_recipe = RecipeTemplate.new(template_path)
|
53
|
+
rescue
|
54
|
+
raise TemplateNotFound, "Template '#{template_name}' not found. " \
|
55
|
+
"To see all templates, run the command "\
|
56
|
+
"`kameleon templates`"
|
57
|
+
else
|
58
|
+
logger.notice("Cloning template '#{template_name}'...")
|
59
|
+
template_recipe.copy_template(options[:force])
|
60
|
+
logger.notice("Creating extended recipe from template '#{template_name}'...")
|
61
|
+
template_recipe.copy_extended_recipe(recipe_name, options[:force])
|
62
|
+
logger.notice("done")
|
63
|
+
end
|
42
64
|
end
|
43
65
|
|
44
66
|
desc "templates", "Lists all defined templates"
|
@@ -58,6 +80,7 @@ module Kameleon
|
|
58
80
|
raise e if Kameleon.env.debug
|
59
81
|
end
|
60
82
|
end
|
83
|
+
templates_hash = templates_hash.sort_by{ |k| k["name"] }
|
61
84
|
tp templates_hash, {"name" => {:width => 30}}, { "description" => {:width => 60}}
|
62
85
|
end
|
63
86
|
|
@@ -68,61 +91,80 @@ module Kameleon
|
|
68
91
|
end
|
69
92
|
map %w(-v --version) => :version
|
70
93
|
|
71
|
-
|
72
|
-
desc "build [RECIPE_NAME]", "Builds the appliance from the recipe"
|
94
|
+
desc "build [RECIPE_PATH]", "Builds the appliance from the given recipe"
|
73
95
|
method_option :build_path, :type => :string ,
|
74
96
|
:default => nil, :aliases => "-b",
|
75
97
|
:desc => "Set the build directory path"
|
98
|
+
method_option :clean, :type => :boolean ,
|
99
|
+
:default => false,
|
100
|
+
:desc => "Run the command `kameleon clean` first"
|
76
101
|
method_option :from_checkpoint, :type => :string ,
|
77
102
|
:default => nil,
|
78
103
|
:desc => "Using specific checkpoint to build the image. " \
|
79
104
|
"Default value is the last checkpoint."
|
80
|
-
method_option :
|
81
|
-
:default =>
|
105
|
+
method_option :checkpoint, :type => :boolean ,
|
106
|
+
:default => true,
|
82
107
|
:desc => "Do not use checkpoints"
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
108
|
+
method_option :cache, :type => :boolean,
|
109
|
+
:default => false,
|
110
|
+
:desc => "Generate a persistent cache for the appliance."
|
111
|
+
method_option :from_cache, :type => :string ,
|
112
|
+
:default => nil,
|
113
|
+
:desc => "Using a persistent cache tar file to build the image."
|
114
|
+
method_option :proxy_path, :type => :string ,
|
115
|
+
:default => nil,
|
116
|
+
:desc => "Full path of the proxy binary to use for the persistent cache."
|
117
|
+
|
118
|
+
def build(recipe_path)
|
119
|
+
clean(recipe_path) if options[:clean]
|
87
120
|
engine = Kameleon::Engine.new(Recipe.new(recipe_path), options)
|
121
|
+
logger.notice("Starting build recipe '#{recipe_path}'")
|
122
|
+
start_time = Time.now.to_i
|
88
123
|
engine.build
|
89
124
|
total_time = Time.now.to_i - start_time
|
90
125
|
logger.notice("")
|
91
|
-
logger.notice("Build recipe '#{
|
126
|
+
logger.notice("Build recipe '#{recipe_path}' is completed !")
|
92
127
|
logger.notice("Build total duration : #{total_time} secs")
|
93
128
|
logger.notice("Build directory : #{engine.cwd}")
|
94
129
|
logger.notice("Build recipe file : #{engine.build_recipe_path}")
|
95
130
|
logger.notice("Log file : #{Kameleon.env.log_file}")
|
96
131
|
end
|
97
132
|
|
98
|
-
desc "checkpoints [
|
133
|
+
desc "checkpoints [RECIPE_PATH]", "Lists all availables checkpoints"
|
99
134
|
method_option :build_path, :type => :string ,
|
100
135
|
:default => nil, :aliases => "-b",
|
101
136
|
:desc => "Set the build directory path"
|
102
|
-
def checkpoints(
|
137
|
+
def checkpoints(recipe_path)
|
103
138
|
Log4r::Outputter['console'].level = Log4r::ERROR unless Kameleon.env.debug
|
104
|
-
recipe_path = File.join(Kameleon.env.recipes_path, recipe_name) + '.yaml'
|
105
139
|
engine = Kameleon::Engine.new(Recipe.new(recipe_path), options)
|
106
140
|
engine.pretty_checkpoints_list
|
107
141
|
end
|
108
142
|
|
109
|
-
desc "
|
143
|
+
desc "clean [RECIPE_PATH]", "Cleaning 'out' and 'local' contexts and removing all checkpoints"
|
110
144
|
method_option :build_path, :type => :string ,
|
111
145
|
:default => nil, :aliases => "-b",
|
112
146
|
:desc => "Set the build directory path"
|
113
|
-
def
|
147
|
+
def clean(recipe_path)
|
114
148
|
Log4r::Outputter['console'].level = Log4r::INFO
|
115
|
-
recipe_path = File.join(Kameleon.env.recipes_path, recipe_name) + '.yaml'
|
116
149
|
engine = Kameleon::Engine.new(Recipe.new(recipe_path), options)
|
117
150
|
engine.clear
|
118
151
|
end
|
152
|
+
map %w(clear) => :clean
|
153
|
+
|
154
|
+
desc "commands", "Lists all available commands", :hide => true
|
155
|
+
def commands
|
156
|
+
puts CLI.all_commands.keys - ["commands", "completions"]
|
157
|
+
end
|
158
|
+
|
159
|
+
desc "source_root", "Prints the kameleon directory path", :hide => true
|
160
|
+
def source_root
|
161
|
+
puts Kameleon.source_root
|
162
|
+
end
|
119
163
|
|
120
164
|
# Hack Thor to init Kameleon env soon
|
121
165
|
def self.init(base_config)
|
122
|
-
|
123
|
-
|
124
|
-
env_options = options.merge({:workspace => workspace})
|
125
|
-
FileUtils.mkdir_p workspace
|
166
|
+
env_options = Hash.new
|
167
|
+
env_options.merge! base_config[:shell].base.options.clone
|
126
168
|
# configure logger
|
127
169
|
env_options["debug"] = true if ENV["KAMELEON_LOG"] == "debug"
|
128
170
|
ENV["KAMELEON_LOG"] = "debug" if env_options["debug"]
|
@@ -138,34 +180,46 @@ module Kameleon
|
|
138
180
|
begin
|
139
181
|
level = Log4r.const_get(level_name.upcase)
|
140
182
|
rescue NameError
|
141
|
-
|
142
|
-
|
143
|
-
|
183
|
+
level = Log4r.const_get("INFO")
|
184
|
+
$stderr << "Invalid KAMELEON_LOG level is set: #{level_name}.\n" \
|
185
|
+
"Please use one of the standard log levels: debug," \
|
186
|
+
" info, warn, or error\n"
|
187
|
+
raise KameleonError
|
144
188
|
end
|
145
189
|
format = ConsoleFormatter.new
|
146
190
|
# format = Log4r::PatternFormatter.new(:pattern => '%11c: %M')
|
147
|
-
if !$stdout.tty? or env_options["
|
191
|
+
if !$stdout.tty? or !env_options["color"]
|
148
192
|
console_output = Log4r::StdoutOutputter.new('console',
|
149
193
|
:formatter => format)
|
194
|
+
Diffy::Diff.default_format = :text
|
150
195
|
else
|
151
196
|
console_output = Log4r::ColorOutputter.new 'console', {
|
152
197
|
:colors => { :debug => :light_black,
|
153
198
|
:info => :green,
|
199
|
+
:progress_info => :green,
|
154
200
|
:notice => :light_blue,
|
155
|
-
:
|
201
|
+
:progress_notice => :light_blue,
|
156
202
|
:warn => :yellow,
|
157
203
|
:error => :red,
|
204
|
+
:progress_error => :red,
|
158
205
|
:fatal => :red,
|
159
206
|
},
|
160
207
|
:formatter => format,
|
161
208
|
}
|
209
|
+
Diffy::Diff.default_format = :color
|
162
210
|
end
|
163
211
|
logger = Log4r::Logger.new('kameleon')
|
164
|
-
logger.outputters << console_output
|
165
212
|
logger.level = level
|
166
|
-
logger
|
213
|
+
logger.outputters << console_output
|
214
|
+
format_file = FileFormatter.new
|
167
215
|
Kameleon.logger.debug("`kameleon` invoked: #{ARGV.inspect}")
|
168
216
|
Kameleon.env = Kameleon::Environment.new(env_options)
|
217
|
+
filelog = Log4r::FileOutputter.new('logfile',
|
218
|
+
:trunc=>false,
|
219
|
+
:filename => Kameleon.env.log_file.to_s,
|
220
|
+
:formatter => format_file)
|
221
|
+
logger.outputters << filelog
|
222
|
+
logger = nil
|
169
223
|
end
|
170
224
|
|
171
225
|
def self.start(given_args=ARGV, config={})
|