kameleon-builder 2.0.0.dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/.editorconfig +23 -0
  2. data/.env +51 -0
  3. data/.gitignore +22 -0
  4. data/AUTHORS +19 -0
  5. data/CHANGELOG +36 -0
  6. data/COPYING +340 -0
  7. data/Gemfile +4 -0
  8. data/README.md +53 -0
  9. data/Rakefile +24 -0
  10. data/Vagrantfile +68 -0
  11. data/bin/kameleon +16 -0
  12. data/contrib/kameleon_bashrc.sh +138 -0
  13. data/contrib/scripts/VirtualBox_deploy.sh +12 -0
  14. data/contrib/scripts/chroot_env +9 -0
  15. data/contrib/scripts/create_passwd.py +17 -0
  16. data/contrib/scripts/umount-chroot.sh +290 -0
  17. data/contrib/steps/bootstrap/debian/bootstrap_if_needed.yaml +47 -0
  18. data/contrib/steps/bootstrap/debian/bootstrap_static.yaml +38 -0
  19. data/contrib/steps/setup/add_timestamp.yaml +6 -0
  20. data/contrib/steps/setup/autologin.yaml +16 -0
  21. data/contrib/steps/setup/copy_ssh_auth_file.yaml +10 -0
  22. data/contrib/steps/setup/debian/add_network_interface.yaml +7 -0
  23. data/contrib/steps/setup/debian/cluster_tools_install.yaml +16 -0
  24. data/contrib/steps/setup/debian/network_config_static.yaml +17 -0
  25. data/contrib/steps/setup/generate_user_ssh_key.yaml +15 -0
  26. data/contrib/steps/setup/install_my_ssh_key.yaml +26 -0
  27. data/contrib/steps/setup/make_swap_file.yaml +9 -0
  28. data/contrib/steps/setup/root_ssh_config.yaml +18 -0
  29. data/contrib/steps/setup/set_user_password.yaml +7 -0
  30. data/contrib/steps/setup/system_optimization.yaml +8 -0
  31. data/docs/.gitignore +1 -0
  32. data/docs/Makefile +177 -0
  33. data/docs/make.bat +242 -0
  34. data/docs/source/_static/.gitignore +0 -0
  35. data/docs/source/aliases.rst +29 -0
  36. data/docs/source/checkpoint.rst +28 -0
  37. data/docs/source/cli.rst +3 -0
  38. data/docs/source/commands.rst +62 -0
  39. data/docs/source/conf.py +254 -0
  40. data/docs/source/context.rst +42 -0
  41. data/docs/source/faq.rst +3 -0
  42. data/docs/source/getting_started.rst +3 -0
  43. data/docs/source/index.rst +38 -0
  44. data/docs/source/installation.rst +3 -0
  45. data/docs/source/recipe.rst +256 -0
  46. data/docs/source/why.rst +3 -0
  47. data/docs/source/workspace.rst +11 -0
  48. data/kameleon-builder.gemspec +37 -0
  49. data/lib/kameleon.rb +75 -0
  50. data/lib/kameleon/cli.rb +176 -0
  51. data/lib/kameleon/context.rb +83 -0
  52. data/lib/kameleon/engine.rb +357 -0
  53. data/lib/kameleon/environment.rb +38 -0
  54. data/lib/kameleon/error.rb +51 -0
  55. data/lib/kameleon/logger.rb +53 -0
  56. data/lib/kameleon/recipe.rb +474 -0
  57. data/lib/kameleon/shell.rb +290 -0
  58. data/lib/kameleon/step.rb +213 -0
  59. data/lib/kameleon/utils.rb +45 -0
  60. data/lib/kameleon/version.rb +3 -0
  61. data/templates/COPYRIGHT +21 -0
  62. data/templates/aliases/defaults.yaml +83 -0
  63. data/templates/checkpoints/docker.yaml +14 -0
  64. data/templates/checkpoints/qcow2.yaml +44 -0
  65. data/templates/debian-wheezy-chroot.yaml +98 -0
  66. data/templates/debian-wheezy-docker.yaml +97 -0
  67. data/templates/fedora-docker.yaml +96 -0
  68. data/templates/steps/bootstrap/debian/debootstrap.yaml +13 -0
  69. data/templates/steps/bootstrap/fedora/docker_bootstrap.yaml +25 -0
  70. data/templates/steps/bootstrap/fedora/yum_bootstrap.yaml +22 -0
  71. data/templates/steps/bootstrap/prepare_appliance_with_nbd.yaml +93 -0
  72. data/templates/steps/bootstrap/prepare_docker.yaml +38 -0
  73. data/templates/steps/bootstrap/start_chroot.yaml +53 -0
  74. data/templates/steps/bootstrap/start_docker.yaml +12 -0
  75. data/templates/steps/export/build_appliance_from_docker.yaml +105 -0
  76. data/templates/steps/export/clean_appliance.yaml +3 -0
  77. data/templates/steps/export/save_appliance_from_nbd.yaml +54 -0
  78. data/templates/steps/setup/create_user.yaml +12 -0
  79. data/templates/steps/setup/debian/kernel_install.yaml +20 -0
  80. data/templates/steps/setup/debian/keyboard_config.yaml +10 -0
  81. data/templates/steps/setup/debian/network_config.yaml +30 -0
  82. data/templates/steps/setup/debian/software_install.yaml +15 -0
  83. data/templates/steps/setup/debian/system_config.yaml +12 -0
  84. data/templates/steps/setup/fedora/kernel_install.yaml +27 -0
  85. data/templates/steps/setup/fedora/software_install.yaml +10 -0
  86. data/tests/helper.rb +22 -0
  87. data/tests/recipes/dummy_recipe.yaml +48 -0
  88. data/tests/recipes/steps/bootstrap/dummy_distro/dummy_bootstrap_static.yaml +4 -0
  89. data/tests/recipes/steps/export/dummy_save_appliance.yaml +9 -0
  90. data/tests/recipes/steps/setup/default/dummy_root_passwd.yaml +8 -0
  91. data/tests/recipes/steps/setup/dummy_distro/dummy_software_install.yaml +7 -0
  92. data/tests/test_context.rb +16 -0
  93. data/tests/test_recipe.rb +15 -0
  94. data/tests/test_version.rb +9 -0
  95. metadata +300 -0
@@ -0,0 +1,42 @@
1
+ -------
2
+ Context
3
+ -------
4
+
5
+ To understand how Kameleon work you have to get the *context* notion. A context
6
+ is an execution environnement with his variables (like $PATH, $TERM,...), his
7
+ tools (debootstrap, yum, ...) and all his specifics (filesystem, local/remote,
8
+ ...). When you build an appliance you deal with 3 contexts:
9
+
10
+ - The *local* context which is the Kameleon execution environnement
11
+ - The *out* context where you will bootstrap the appliance
12
+ - The *in* context which is inside the newly created appliance
13
+
14
+ These context are setup using the two globals variables: ``out_context``
15
+ and ``in_context``. They both takes 3 arguments:
16
+
17
+ cmd
18
+ The command to initialize the context
19
+ workdir (optional)
20
+ The working directory to tell to Kameleon where to execute the command
21
+ exec_prefix (optional)
22
+ The command to execute before every Kameleon command in this context
23
+
24
+ For example, you are building an appliance on your laptop and you run Kameleon
25
+ in a bash shell with this configuration:
26
+
27
+ .. code-block:: yaml
28
+
29
+ out_context:
30
+ cmd: bash
31
+ workdir: $$kameleon_cwd
32
+
33
+ in_context:
34
+ cmd: chroot $$rootfs bash
35
+ workdir: /
36
+
37
+
38
+ Your *local* context is this shell where you launch Kameleon on your laptop,
39
+ the *out* is a child bash of this context, and the *in* is inside the new
40
+ environnement accessed by the chroot. As you can see the local and the out
41
+ context are often very similar but sometimes it could be useful for the out
42
+ context to be elsewhere (in a VM for example).
@@ -0,0 +1,3 @@
1
+ ---
2
+ FAQ
3
+ ---
@@ -0,0 +1,3 @@
1
+ ---------------
2
+ Getting Started
3
+ ---------------
@@ -0,0 +1,38 @@
1
+ .. Kameleon documentation master file, created by
2
+ sphinx-quickstart on Thu Feb 13 19:01:14 2014.
3
+ You can adapt this file completely to your liking, but it should at least
4
+ contain the root `toctree` directive.
5
+
6
+ Welcome to Kameleon's documentation!
7
+ ====================================
8
+
9
+ Kameleon should be seen as a simple but powerful tool to generate customized
10
+ appliances. With Kameleon, you make your recipe that describes how to create
11
+ step by step your own distribution. At start Kameleon is used to create custom
12
+ kvm, LXC, VirtualBox, iso images, ..., but as it is designed to be very generic
13
+ you can probably do a lot more than that.
14
+
15
+
16
+ .. toctree::
17
+ :maxdepth: 2
18
+
19
+ why.rst
20
+ installation.rst
21
+ getting_started.rst
22
+ cli.rst
23
+ recipe.rst
24
+ context.rst
25
+ commands.rst
26
+ workspace.rst
27
+ checkpoint.rst
28
+ aliases.rst
29
+ faq.rst
30
+
31
+
32
+ Indices and tables
33
+ ==================
34
+
35
+ * :ref:`genindex`
36
+ * :ref:`modindex`
37
+ * :ref:`search`
38
+
@@ -0,0 +1,3 @@
1
+ ------------
2
+ Installation
3
+ ------------
@@ -0,0 +1,256 @@
1
+ ------
2
+ Recipe
3
+ ------
4
+
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 `Workspace`_.
7
+ A recipe is a hierarchical structure of `Sections`_, `Steps`_, `Microsteps`_ and
8
+ `Commands`_. Here is an overview of this structure:
9
+
10
+ .. code-block:: yaml
11
+
12
+ recipe
13
+ └── section
14
+ └── step
15
+ └── microstep
16
+ └──command
17
+
18
+ The recipe also contains set of `Global variables`_ declaration and some
19
+ imports like `Aliases`_ and `Checkpoint`_.
20
+
21
+ This is an example of a recipe:
22
+
23
+ .. code-block:: yaml
24
+
25
+ ---
26
+ # Loads some helpful aliases
27
+ aliases: defaults.yaml
28
+ # Enables qcow2 checkpoint
29
+ checkpoint: qcow2.yaml
30
+ #== Global variables use by Kameleon engine and the steps
31
+ global:
32
+ ## User varibales : used by the recipe
33
+ cachedir: /var/cache/kameleon
34
+ rootfs: $$kameleon_cwd/rootfs
35
+ user_name: kameleon
36
+ arch: amd64
37
+
38
+ nbd_device: /dev/nbd10
39
+ container: "$${kameleon_recipe_name}_temp.qcow2"
40
+
41
+ distrib: debian
42
+ release: wheezy
43
+
44
+ ## System variables. Required by kameleon engine
45
+ # Include specific steps
46
+ include_steps: [$$distrib/$$release, $$distrib]
47
+
48
+ # Shell session from where we launch exec_out commands. There is often a
49
+ # local bash session, but it can be a remote shell on other machines or on
50
+ # any shell. (eg. bash, chroot, fakechroot, ssh, tmux, lxc...)
51
+ out_context:
52
+ cmd: bash
53
+ workdir: $$kameleon_cwd
54
+
55
+ # Shell session that allows us to connect to the building machine in order to
56
+ # configure it and setup additional programs
57
+ default_env: "USER=root HOME=/root LC_ALL=POSIX"
58
+ in_context:
59
+ cmd: $$default_env chroot $$rootfs bash
60
+ workdir: /
61
+
62
+ #== Bootstrap the new system and create the 'in_context'
63
+ bootstrap:
64
+ - debootstrap:
65
+ - release: $$release
66
+ - arch: $$arch
67
+ - repository: http://ftp.fr.debian.org/debian/
68
+ - rootfs_archive: $$cachedir/$$distrib/$$release/$$arch/debootstrap.tar.gz
69
+ - prepare_appliance_with_nbd:
70
+ - mountdir: $$rootfs
71
+ - image_size: 2G
72
+ - filesystem_type: ext4
73
+ - rootfs_archive: $$cachedir/$$distrib/$$release/$$arch/debootstrap.tar.gz
74
+ - start_chroot:
75
+ - rootfs: $$rootfs
76
+
77
+
78
+ #== Install and configuration steps
79
+ # WARNING: this part should be independante from the build context (whenever
80
+ # possible...)
81
+ setup:
82
+ # Install
83
+ - software_install:
84
+ - packages: >
85
+ debian-keyring ntp zip unzip rsync sudo less vim bash-completion
86
+ - kernel_install:
87
+ - arch: $$arch
88
+ # Configuration
89
+ - system_config:
90
+ - locales: fr_FR en_US
91
+ - lang: fr_FR.UTF-8
92
+ - timezone: Europe/Paris
93
+ - keyboard_config:
94
+ - layout: "fr,us"
95
+ - network_config:
96
+ - hostname: kameleon-$$distrib
97
+ - create_user:
98
+ - name: $$user_name
99
+ - group: admin
100
+ - password: $$user_name
101
+
102
+ #== Export the generated appliance in the format of your choice
103
+ export:
104
+ - save_appliance_from_nbd:
105
+ - filename: "$${kameleon_recipe_name}"
106
+ - save_as_qcow2
107
+ # - save_as_tgz
108
+ # - save_as_raw
109
+ # - save_as_vmdk
110
+ # - save_as_vdi
111
+
112
+ Section
113
+ -------
114
+
115
+ Each section is a list of `Steps`_. Currently, there is 3 sections:
116
+
117
+ bootstrap
118
+ This section contains the bootstrap of the new system and create the *in*
119
+ context (see `Contexts`_).
120
+
121
+ setup
122
+ This one is dedicated to the install and configuration steps.
123
+
124
+ export
125
+ Export the generated appliance in the format of your choice.
126
+
127
+
128
+ Step
129
+ ----
130
+
131
+ Each *step* contains a list of microsteps that contains a list of Commands_
132
+ written in one YAML file. To be found by Kameleon this file must be named by
133
+ with the step name plus the YAML extension ``.yaml``. For example the
134
+ ``software_install.yaml`` step file looks like this:
135
+
136
+ .. code-block:: yaml
137
+
138
+ # Software Install
139
+ - add_contribs_source:
140
+ - exec_in: perl -pi -e "s/main$/main contrib non-free/" /etc/apt/sources.list
141
+ - update_repositories:
142
+ - exec_in: apt-get -y --force-yes update
143
+ - upgrade_system:
144
+ - exec_in: apt-get -y --force-yes dist-upgrade
145
+ - clean:
146
+ - on_export_init:
147
+ - exec_in: apt-get -y --force-yes autoclean
148
+ - exec_in: apt-get -y --force-yes clean
149
+ - exec_in: apt-get -y --force-yes autoremove
150
+ # default packages
151
+ - packages: "ntp sudo"
152
+ - extra_packages:
153
+ - exec_in: apt-get -y --force-yes install $$packages
154
+
155
+
156
+ A step will be called like a function in the recipe. You should provide a set
157
+ of local variables if needed by the step or to override default variables (see
158
+ Variables_). Optionally, you can select only some microsteps to execute. Here
159
+ is an example of step call:
160
+
161
+ .. code-block:: yaml
162
+
163
+ - software_install:
164
+ - update_repositories
165
+ - add_contribs_source
166
+ - clean
167
+ - extra_packages
168
+ - packages: "debian-keyring ntp zip unzip rsync sudo"
169
+
170
+ Steps path
171
+ ~~~~~~~~~~
172
+
173
+ The steps are YAML formated files stored in the ``recipe/steps`` directory of
174
+ the Workspace_. To enable a better recipe reuse and ease of write the steps
175
+ are stored by default in specific folders depending on the sections.
176
+
177
+ Kameleon is looking for the steps files using the ``include_steps`` list value,
178
+ if it is set in the recipe (NOT mandatory). These includes are often the
179
+ distribution steps. For example if you are building an ubuntu based
180
+ distribution you can use:
181
+
182
+ .. code-block:: yaml
183
+
184
+ include_steps:
185
+ - ubuntu
186
+ - debian/wheezy
187
+ - debian
188
+
189
+ It also search uppermost within the current section folder. For the previous
190
+ example, in the bootstrap section, the search paths are scanned in this
191
+ order:
192
+
193
+ .. code-block:: yaml
194
+
195
+ steps/bootstrap/ubuntu
196
+ steps/ubuntu
197
+ steps/bootstrap/debian/wheezy
198
+ steps/debian/wheezy
199
+ steps/bootstrap/debian
200
+ steps/debian
201
+ steps/bootstrap/
202
+ steps/
203
+
204
+
205
+ Variables
206
+ ---------
207
+
208
+ Kameleon is using preprocessed variables. You can define it with the YAML
209
+ key/value syntax ``my_var: my_value``.To access these variables you have to use
210
+ the two dollars (``$$``) prefix. Like in a Shell you can also use
211
+ ``$${var_name}`` to include your variables in string like this
212
+ ``my-$${variable_name}-templated``. It's also possible to use nested variables
213
+ like:
214
+
215
+ .. code-block:: yaml
216
+
217
+ my_var: foo
218
+ my_nested_var: $${my_var}-bar
219
+
220
+ Be careful, in YAML you cannot mix dictionary and list on the same level.
221
+ That's why, in the global dictionary, you can define your variables like in the
222
+ example above but, in the recipe or the steps, you must prefix your variable
223
+ with a ``-`` like this ``- my_var: foo``.
224
+
225
+
226
+ Global variables
227
+ ~~~~~~~~~~~~~~~~~
228
+
229
+ Global variables are defined in the ``global`` dictionary of the recipe.
230
+ Kameleon use some global variable to enable the appliance build. See Context_
231
+ and `Steps path`_ for more details
232
+
233
+
234
+ Step local variables
235
+ ~~~~~~~~~~~~~~~~~~~~
236
+
237
+ In the recipe, you can provide some variables when you call a step. This
238
+ variable override the global and the default variables.
239
+
240
+
241
+ Step default variables
242
+ ~~~~~~~~~~~~~~~~~~~~~~
243
+
244
+ In the step file, you can define some default variables for your microsteps. Be
245
+ careful, to avoid some mistakes, these variables can be override by the step
246
+ local variables but not by the global ones. If this is the behavior you
247
+ expected just add a step local variable that take the global variable value
248
+ like this:
249
+
250
+ .. code-block:: yaml
251
+
252
+ global:
253
+ foo: bar
254
+ setup:
255
+ - my_step:
256
+ - foo: $$foo
@@ -0,0 +1,3 @@
1
+ --------------
2
+ Why Kameleon ?
3
+ --------------
@@ -0,0 +1,11 @@
1
+ ---------
2
+ Workspace
3
+ ---------
4
+
5
+ The workspaces are the folders containing your Kameleon recipes and builds. When
6
+ you use ``kameleon new`` a workspace is created if it does not exists. A
7
+ workspace may contains several recipes.
8
+
9
+ *Be careful*: All the *steps are shared between recipes within a workspace*. So
10
+ if you do NOT want to share steps between different recipes you MUST use
11
+ different workspace.
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kameleon/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "kameleon-builder"
8
+ s.version = Kameleon::VERSION
9
+ s.authors = ["Salem Harrache",
10
+ "Michael Mercier",
11
+ "Cristan Ruiz",
12
+ "Bruno Bzeznik"]
13
+ s.email = ["salem.harrache@inria.fr",
14
+ "michael.mercier@inria.fr",
15
+ "cristian.ruiz@imag.fr",
16
+ "bruno.bzeznik@imag.fr"]
17
+ s.description = %q{The mindful appliance builder}
18
+ s.summary = %q{Kameleon is a tool to build virtual machines from scratch}
19
+ s.homepage = "http://kameleon.readthedocs.org/"
20
+ s.license = "GPL-2"
21
+
22
+ s.files = `git ls-files`.split($/)
23
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
+ s.test_files = s.files.grep(%r{^(tests|s|features)/})
25
+ s.require_paths = ["lib"]
26
+
27
+ s.add_dependency 'childprocess', '~> 0.3'
28
+ s.add_dependency 'thor', '~> 0.15'
29
+ s.add_dependency 'table_print', '~> 1.5'
30
+ s.add_dependency 'log4r-color', '~> 1.2'
31
+
32
+ s.add_development_dependency 'pry', '~> 0.9'
33
+ s.add_development_dependency 'pry-debugger', '~> 0.2'
34
+ s.add_development_dependency 'rake', '~> 10.1'
35
+ s.add_development_dependency 'minitest', '~> 4.7'
36
+ s.add_development_dependency 'coveralls', '~> 0.7'
37
+ end
data/lib/kameleon.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'securerandom'
2
+ require 'yaml'
3
+ require 'fileutils'
4
+ require 'optparse'
5
+ require 'erb'
6
+ require 'ostruct'
7
+ require 'tempfile'
8
+ require 'pp'
9
+ require 'thor'
10
+ require 'childprocess'
11
+ require 'log4r-color'
12
+ require 'log4r-color/configurator'
13
+ require 'pathname'
14
+ require 'table_print'
15
+
16
+ module Kameleon
17
+ # to force yaml to dump ASCII-8Bit strings as strings
18
+ YAML::ENGINE.yamler='syck'
19
+
20
+ # add a PROGRESS and NOTICE level
21
+ Log4r::Configurator.custom_levels(:DEBUG, :INFO, :NOTICE,
22
+ :PROGRESS, :WARN, :ERROR,
23
+ :FATAL)
24
+
25
+ class << self
26
+ attr_writer :logger, :env, :source_root, :templates_path, :templates_names,
27
+ :templates_files
28
+
29
+ # The source root is the path to the root directory of the kameleon gem.
30
+ def source_root
31
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
32
+ end
33
+
34
+ def templates_path
35
+ @templates_path ||= Pathname.new(File.join(source_root, 'templates'))
36
+ end
37
+
38
+ def templates_files
39
+ if @templates.nil?
40
+ files = Dir.foreach(templates_path).map do |f|
41
+ Pathname.new(File.join(templates_path, f)) if f.include?(".yaml")
42
+ end
43
+ @templates = files.compact
44
+ end
45
+ @templates
46
+ end
47
+
48
+ def templates_names
49
+ if @templates_names.nil?
50
+ names = templates_files.map do |f|
51
+ f.basename(f.extname).to_s
52
+ end
53
+ @templates_names = names
54
+ end
55
+ @templates_names
56
+ end
57
+
58
+ def logger
59
+ @logger ||= Log4r::Logger.new("kameleon::[global]")
60
+ end
61
+
62
+ def env
63
+ @env ||= Environment.new
64
+ end
65
+
66
+ end
67
+ end
68
+
69
+ # Load the things which must be loaded before anything else
70
+ require 'kameleon/utils'
71
+ require 'kameleon/error'
72
+ require 'kameleon/cli'
73
+ require 'kameleon/environment'
74
+ require 'kameleon/version'
75
+ require 'kameleon/logger'