kameleon-builder 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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={})
|