albanpeignier-gepetto 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-01-18
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,33 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ app_generators/gepetto/USAGE
6
+ app_generators/gepetto/gepetto_generator.rb
7
+ app_generators/gepetto/templates/Rakefile
8
+ app_generators/gepetto/templates/config/fileserver.conf
9
+ app_generators/gepetto/templates/config/puppet.conf
10
+ app_generators/gepetto/templates/manifests/nodes.pp
11
+ app_generators/gepetto/templates/manifests/site.pp
12
+ app_generators/gepetto/templates/manifests/templates.pp
13
+ app_generators/gepetto/templates/script/module
14
+ app_generators/gepetto/templates/script/puppetca
15
+ app_generators/gepetto/templates/script/puppetmasterd
16
+ app_generators/gepetto/templates/script/puppetrun
17
+ bin/gepetto
18
+ gepetto.gemspec
19
+ lib/gepetto.rb
20
+ lib/gepetto/module.rb
21
+ lib/gepetto/tasks.rb
22
+ puppet_generators/module/USAGE
23
+ puppet_generators/module/module_generator.rb
24
+ puppet_generators/module/templates/README
25
+ puppet_generators/module/templates/manifests/init.pp
26
+ script/destroy
27
+ script/generate
28
+ tasks/log.rake
29
+ tasks/puppet.rake
30
+ tasks/sandbox.pp
31
+ tasks/sandbox.rake
32
+ tasks/tmp.rake
33
+ tasks/utils.rake
data/README.rdoc ADDED
@@ -0,0 +1,211 @@
1
+ = Gepetto
2
+
3
+ * http://github.com/albanpeignier/gepetto/
4
+
5
+ == DESCRIPTION:
6
+
7
+ A helper suite for Puppet projects to create, manage and help daily development
8
+
9
+ More information about Puppet: http://reductivelabs.com/trac/puppet/
10
+
11
+ == FEATURES:
12
+
13
+ Creates base project:
14
+
15
+ * create Puppet File Hierarchy
16
+ * create default manifests files
17
+
18
+ Provides helper tools:
19
+
20
+ * script/puppetmasterd: to start a local puppetmasterd
21
+ * script/puppetca: to manage local ssl directory
22
+ * script/puppetrun: request a puppet run
23
+ * script/module: to install external module
24
+
25
+ * script/generate: generate puppet code (for module, ...)
26
+
27
+ Provides rake tasks:
28
+
29
+ * sandbox tasks: to create, start and control sandbox for development
30
+ * puppet tasks: to check syntax
31
+ * clean temporary or log files
32
+
33
+ == SYNOPSIS:
34
+
35
+ Create a new puppet project
36
+
37
+ gepetto /path/to/new/puppet/project
38
+
39
+ create
40
+ create script
41
+ create config
42
+ create manifests
43
+ create files
44
+ create templates
45
+ create tasks
46
+ create Rakefile
47
+ create manifests/site.pp
48
+ create manifests/templates.pp
49
+ create manifests/nodes.pp
50
+ create config/puppet.conf
51
+ create config/fileserver.conf
52
+ create script/puppetmasterd
53
+ create script/puppetca
54
+ create script/puppetrun
55
+ create script/module
56
+ dependency install_rubigen_scripts
57
+ exists script
58
+ create script/generate
59
+ create script/destroy
60
+
61
+ Start a puppetmasterd with project files:
62
+
63
+ ./script/puppetmasterd &
64
+
65
+ notice: Starting Puppet server version 0.24.5
66
+
67
+ Create and start a sandbox:
68
+
69
+ rake sandbox:setup sandbox:create sandbox:start
70
+
71
+ Follow sandbox console/syslog:
72
+
73
+ tail -f log/sandbox.log
74
+
75
+ List waiting client certificates:
76
+
77
+ ./script/puppetca --list
78
+ sandbox
79
+
80
+ Sign the sandbox certificate:
81
+
82
+ rake sandbox:puppet:sign
83
+
84
+ Request a puppet run in sandbox:
85
+
86
+ rake sandbox:puppet:run
87
+
88
+ Install an external module:
89
+
90
+ ./script/module install git://git.black.co.at/module-common
91
+
92
+ install module common in modules/common
93
+
94
+ Initialized empty Git repository in modules/common/.git/
95
+ remote: Counting objects: 322, done.
96
+ remote: Compressing objects: 100% (217/217), done.
97
+ remote: Total 322 (delta 110), reused 210 (delta 70)
98
+ Receiving objects: 100% (322/322), 37.75 KiB, done.
99
+ Resolving deltas: 100% (110/110), done.
100
+
101
+ Create a new Puppet module
102
+
103
+ ./script/generate module private
104
+
105
+ create
106
+ create manifests
107
+ create files
108
+ create templates
109
+ create README
110
+ create manifests/init.pp
111
+
112
+ == SANDBOX
113
+
114
+ For the moment, the sandbox tasks use qemu to create and run a virtual machine
115
+ with a ready puppetd.
116
+
117
+ Define a sandbox in your rakefile:
118
+
119
+ Sandbox.new do |s|
120
+ s.bootstraper = DebianBoostraper.new do |d|
121
+ d.version = 'lenny'
122
+ d.mirror = 'http://ftp.fr.debian.org/debian'
123
+ end
124
+
125
+ s.disk_size = '1G'
126
+ s.memory_size = '128M'
127
+ end
128
+
129
+ Setup your host to create and start sandbox:
130
+
131
+ rake sandbox:setup
132
+
133
+ It installs qemu, kqemu module and uml-utilities
134
+
135
+ Create a fresh image for sandbox:
136
+
137
+ rake sandbox:create
138
+
139
+ By default, it will create a disk of 512M with a debian lenny.
140
+
141
+ Start a qemu instance with the sandbox image:
142
+
143
+ rake sandbox:start
144
+
145
+ Follow the console (and syslog) output of the sandbox:
146
+
147
+ tail -f log/sandbox.log
148
+
149
+ [...]
150
+ Starting puppet configuration management tool
151
+
152
+ Debian GNU/Linux 5.0 sandbox ttyS0
153
+ sandbox login:
154
+
155
+ Jan 31 14:22:30 sandbox puppetd[1430]: Reopening log files.
156
+ Jan 31 14:22:32 sandbox puppetd[1430]: Could not request certificate
157
+
158
+
159
+ Sign the new sandbox certificat:
160
+
161
+ rake sandbox:puppet:sign
162
+
163
+ Request a puppet run in the sandbox:
164
+
165
+ rake sandbox:puppet:run
166
+
167
+ Stop the sandbox vm:
168
+
169
+ rake sandbox:stop
170
+
171
+ Destroy sandbox files:
172
+
173
+ rake sandbox:destroy
174
+
175
+ == REQUIREMENTS:
176
+
177
+ * rubigen: http://rubigen.rubyforge.org/
178
+
179
+ == INSTALL:
180
+
181
+ * sudo gem install gepetto
182
+
183
+ or to use the development release :
184
+
185
+ * gem sources -a http://gems.github.com
186
+ * sudo gem install albanpeignier-gepetto
187
+
188
+ == LICENSE:
189
+
190
+ (The MIT License)
191
+
192
+ Copyright (c) 2009 Alban Peignier
193
+
194
+ Permission is hereby granted, free of charge, to any person obtaining
195
+ a copy of this software and associated documentation files (the
196
+ 'Software'), to deal in the Software without restriction, including
197
+ without limitation the rights to use, copy, modify, merge, publish,
198
+ distribute, sublicense, and/or sell copies of the Software, and to
199
+ permit persons to whom the Software is furnished to do so, subject to
200
+ the following conditions:
201
+
202
+ The above copyright notice and this permission notice shall be
203
+ included in all copies or substantial portions of the Software.
204
+
205
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
206
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
207
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
208
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
209
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
210
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
211
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/gepetto'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('gepetto', Gepetto::VERSION) do |p|
7
+ p.developer('Alban Peignier', 'alban.peignier@free.fr')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.rubyforge_name = p.name # TODO this is default value
10
+ p.extra_deps = [
11
+ ['rubigen',">= #{RubiGen::VERSION}"],
12
+ ]
13
+ p.extra_dev_deps = [
14
+ ['newgem', ">= #{::Newgem::VERSION}"]
15
+ ]
16
+
17
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
18
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
19
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
20
+ p.rsync_args = '-av --delete --ignore-errors'
21
+ end
22
+
23
+ require 'newgem/tasks' # load /tasks/*.rake
24
+ Dir['tasks/**/*.rake'].each { |t| load t }
25
+
26
+ # TODO - want other tests/tasks run by default? Add them to the list
27
+ # task :default => [:spec, :features]
File without changes
@@ -0,0 +1,33 @@
1
+ require 'rbconfig'
2
+
3
+ class GepettoGenerator < RubiGen::Base
4
+
5
+ def initialize(runtime_args, runtime_options = {})
6
+ super
7
+
8
+ usage if args.empty?
9
+ @destination_root = File.expand_path(args.shift)
10
+ end
11
+
12
+ def manifest
13
+ script_options = { :chmod => 0755 }
14
+
15
+ record do |m|
16
+ # Root directory and all subdirectories.
17
+ m.directory ''
18
+
19
+ %w{script config manifests files templates tasks}.each { |path| m.directory path }
20
+
21
+ m.template_copy_each %w( Rakefile )
22
+
23
+ m.template_copy_each %w( site.pp templates.pp nodes.pp ), 'manifests'
24
+
25
+ m.template_copy_each %w( puppet.conf fileserver.conf ), 'config'
26
+
27
+ m.template_copy_each %w( puppetmasterd puppetca puppetrun module ), 'script', script_options
28
+
29
+ m.dependency "install_rubigen_scripts", [destination_root, "puppet"]
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,24 @@
1
+ %w[rubygems rake rake/clean fileutils].each { |f| require f }
2
+
3
+ require 'gepetto/tasks' # load /tasks/*.rake
4
+ Dir['tasks/**/*.rake'].each { |t| load t }
5
+
6
+ # Change the sandbox storage directory
7
+ # Sandbox.images_directory = '/disks/sandbox'
8
+
9
+ Sandbox.new do |s|
10
+ s.bootstraper = DebianBoostraper.new do |d|
11
+ # Specify the wanted debian distribution
12
+ # d.version = 'lenny'
13
+
14
+ # Use a local debian mirror
15
+ # d.mirror = 'http://ftp.fr.debian.org/debian'
16
+
17
+ # Use a local apt-proxy
18
+ # d.mirror = 'http://localhost:9999/debian'
19
+ end
20
+
21
+ # s.disk_size = '1G'
22
+ # s.memory_size = '128M'
23
+ end
24
+
@@ -0,0 +1,7 @@
1
+ [files]
2
+ path <%= File.expand_path destination_root, 'files' %>
3
+ allow *
4
+
5
+ [plugins]
6
+ path <%= File.expand_path destination_root, 'plugins' %>
7
+ allow *
@@ -0,0 +1,11 @@
1
+ [main]
2
+ factpath=$vardir/lib/facter
3
+ pluginsync=true
4
+ color=false
5
+
6
+ # To unable storeconfigs (requires gems sqlite3)
7
+ #
8
+ #[puppetmaster]
9
+ #storeconfigs = true
10
+ #dbadapter = sqlite3
11
+ #dblocation = $vardir/storeconfigs.sqlite
@@ -0,0 +1,62 @@
1
+ #!/bin/bash -e
2
+
3
+ # TODO just a POC, make a real implementation
4
+
5
+ function usage() {
6
+ cat - <<EOF
7
+ Usage: module [OPTIONS] command
8
+ Puppet module manager.
9
+ GENERAL OPTIONS
10
+ -h, --help Show this help message.
11
+ COMMANDS
12
+ install Install module from an URL.
13
+ EXAMPLES
14
+ Install a module from a git URL:
15
+ module install git://github.com/lak/puppet-puppet.git
16
+ Install a module from a git URL and a specified name:
17
+ module install git://github.com/lak/puppet-puppet.git lak-puppet
18
+ EOF
19
+ exit 0
20
+ }
21
+
22
+ command=$1
23
+ [ -z "$command" ] && usage
24
+
25
+ shift
26
+
27
+ modules_dir=modules
28
+ [ -d $modules_dir ] || mkdir $modules_dir
29
+ cd $modules_dir
30
+
31
+ case $command in
32
+ install)
33
+ module_url=$1
34
+ [ -z "$module_url" ] && usage
35
+
36
+ shift
37
+
38
+ if [ $# -gt 0 ]; then
39
+ module_name=$1
40
+ shift
41
+ else
42
+ module_name=`echo $module_url | sed 's@.*/\(.*\)$@\1@'`
43
+ # remove .git suffix
44
+ module_name=`echo $module_name | sed 's/\.git$//'`
45
+ # remove puppet- or module- prefix
46
+ module_name=`echo $module_name | sed -e 's/^puppet-//' -e 's/^module-//'`
47
+ fi
48
+
49
+ if [ -d $module_name ]; then
50
+ echo "module $module_name already installed"
51
+ exit 1
52
+ fi
53
+
54
+ echo "install module $module_name in $modules_dir/$module_name"
55
+
56
+ git clone $module_url $module_name
57
+ rm -rf $module_name/.git
58
+ ;;
59
+ *)
60
+ usage
61
+ ;;
62
+ esac
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ /usr/sbin/puppetca --ssldir $PWD/tmp/ssl $*
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ # create tmp if needed, other directories are created by puppetmasterd
4
+ [ -d tmp ] || mkdir tmp
5
+
6
+ # change working directories
7
+ OPTIONS="--logdir=$PWD/log --vardir=$PWD/tmp/lib --rundir=$PWD/tmp/run --ssldir=$PWD/tmp/ssl"
8
+ # use local files
9
+ OPTIONS="$OPTIONS --templatedir=$PWD/templates --manifestdir=$PWD/manifests --modulepath=$PWD/modules"
10
+
11
+ OPTIONS="$OPTIONS --certname=puppet --logdest=console"
12
+
13
+ /usr/sbin/puppetmasterd --no-daemonize $OPTIONS $*
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ /usr/sbin/puppetrun --ssldir=$PWD/tmp/ssl --confdir=$PWD/config --certname=puppet $*
data/bin/gepetto ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'rubigen'
5
+
6
+ if %w(-v --version).include? ARGV.first
7
+ require 'gepetto/version'
8
+ puts "#{File.basename($0)} #{Gepetto::VERSION}"
9
+ exit(0)
10
+ end
11
+
12
+ require 'rubigen/scripts/generate'
13
+ RubiGen::Base.use_application_sources!
14
+
15
+ RubiGen::Base.prepend_sources(
16
+ RubiGen::PathSource.new(:app, File.join(File.dirname(__FILE__), "..", "app_generators"))
17
+ )
18
+ RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'gepetto')
data/gepetto.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{gepetto}
5
+ s.version = "0.0.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Alban Peignier"]
9
+ s.date = %q{2009-01-31}
10
+ s.default_executable = %q{gepetto}
11
+ s.description = %q{A helper suite for Puppet projects to create, manage and help daily development More information about Puppet: http://reductivelabs.com/trac/puppet/}
12
+ s.email = ["alban.peignier@free.fr"]
13
+ s.executables = ["gepetto"]
14
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
15
+ s.files = ["History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "app_generators/gepetto/USAGE", "app_generators/gepetto/gepetto_generator.rb", "app_generators/gepetto/templates/Rakefile", "app_generators/gepetto/templates/config/fileserver.conf", "app_generators/gepetto/templates/config/puppet.conf", "app_generators/gepetto/templates/manifests/nodes.pp", "app_generators/gepetto/templates/manifests/site.pp", "app_generators/gepetto/templates/manifests/templates.pp", "app_generators/gepetto/templates/script/module", "app_generators/gepetto/templates/script/puppetca", "app_generators/gepetto/templates/script/puppetmasterd", "app_generators/gepetto/templates/script/puppetrun", "bin/gepetto", "gepetto.gemspec", "lib/gepetto.rb", "lib/gepetto/module.rb", "lib/gepetto/tasks.rb", "puppet_generators/module/USAGE", "puppet_generators/module/module_generator.rb", "puppet_generators/module/templates/README", "puppet_generators/module/templates/manifests/init.pp", "script/destroy", "script/generate", "tasks/log.rake", "tasks/puppet.rake", "tasks/sandbox.pp", "tasks/sandbox.rake", "tasks/tmp.rake", "tasks/utils.rake"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/albanpeignier/gepetto/}
18
+ s.rdoc_options = ["--main", "README.rdoc"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{gepetto}
21
+ s.rubygems_version = %q{1.3.1}
22
+ s.summary = %q{A helper suite for Puppet projects to create, manage and help daily development More information about Puppet: http://reductivelabs.com/trac/puppet/}
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 2
27
+
28
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
+ s.add_runtime_dependency(%q<rubigen>, [">= 1.5.2"])
30
+ s.add_development_dependency(%q<newgem>, [">= 1.2.3"])
31
+ s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
32
+ else
33
+ s.add_dependency(%q<rubigen>, [">= 1.5.2"])
34
+ s.add_dependency(%q<newgem>, [">= 1.2.3"])
35
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
36
+ end
37
+ else
38
+ s.add_dependency(%q<rubigen>, [">= 1.5.2"])
39
+ s.add_dependency(%q<newgem>, [">= 1.2.3"])
40
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
41
+ end
42
+ end
data/lib/gepetto.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Gepetto
5
+ VERSION = '0.0.3'
6
+ end
@@ -0,0 +1 @@
1
+ Dir[File.join(File.dirname(__FILE__), %w[.. .. tasks], '**/*.rake')].each { |rake| load rake }
@@ -0,0 +1,18 @@
1
+ Description:
2
+ Create an empty module organisation as specified by
3
+ http://reductivelabs.com/trac/puppet/wiki/ModuleOrganisation
4
+
5
+ This generates a module directories and files into modules/<modulename>.
6
+
7
+ Example:
8
+ ./script/generate module passenger
9
+
10
+ creates directories :
11
+ modules/passenger/templates
12
+ modules/passenger/files
13
+ modules/passenger/depends
14
+
15
+ creates files :
16
+ modules/passenger/README
17
+ modules/passenger/manifests/init.pp
18
+ modules/passenger/manifests/defaults.pp
@@ -0,0 +1,24 @@
1
+ require 'rbconfig'
2
+
3
+ class ModuleGenerator < RubiGen::Base
4
+
5
+ attr_reader :module_name
6
+
7
+ def initialize(runtime_args, runtime_options = {})
8
+ super
9
+ usage if args.empty?
10
+ @module_name = args.shift
11
+ @destination_root = "modules/#{module_name}"
12
+ end
13
+
14
+ def manifest
15
+ record do |m|
16
+ # Root directory and all subdirectories.
17
+ m.directory ''
18
+ %w{manifests files templates}.each { |path| m.directory path }
19
+ m.template_copy_each %w( README )
20
+ m.template_copy_each %w( init.pp ), 'manifests'
21
+ end
22
+ end
23
+
24
+ end
File without changes
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/tasks/log.rake ADDED
@@ -0,0 +1,9 @@
1
+ namespace :log do
2
+ desc "Truncates all *.log files in log/ to zero bytes"
3
+ task :clear do
4
+ FileList["log/*.log"].each do |log_file|
5
+ f = File.open(log_file, "w")
6
+ f.close
7
+ end
8
+ end
9
+ end
data/tasks/puppet.rake ADDED
@@ -0,0 +1,6 @@
1
+ namespace :puppet do
2
+ desc "Check syntax of puppet manifests"
3
+ task :check_syntax do
4
+ sh "puppet --color=false --confdir=/tmp --vardir=/tmp --parseonly --ignoreimport #{FileList['manifests/**/*.pp'].join(' ')}"
5
+ end
6
+ end
data/tasks/sandbox.pp ADDED
@@ -0,0 +1,110 @@
1
+ # Minimal settings to boot sandbox image with qemu
2
+
3
+ # These variables are defined by rake task
4
+ #$host_ip='172.20.0.1'
5
+ #$sandbox_ip='172.20.0.2'
6
+
7
+ Exec { path => "/usr/bin:/usr/sbin/:/bin:/sbin" }
8
+
9
+ file { "/etc/fstab":
10
+ content => "/dev/hda1 / ext3 errors=remount-ro 0 1
11
+ proc /proc proc defaults 0 0
12
+ "
13
+ }
14
+
15
+ # Console on ttyS0 not tty1
16
+ exec { "inittab-ttyS0-getty":
17
+ command => "sed -i '/getty 38400 tty1/ s/tty1/ttyS0/' /etc/inittab",
18
+ unless => "grep 'getty 38400 ttyS0' /etc/inittab"
19
+ }
20
+
21
+ # and no other gettys
22
+ exec { "inittab-no-tty-gettys":
23
+ command => "sed -i '/getty 38400 tty[23456]/ d' /etc/inittab",
24
+ onlyif => "grep 'getty 38400 tty[23456]' /etc/inittab"
25
+ }
26
+
27
+ file { "/etc/hostname":
28
+ content => "sandbox"
29
+ }
30
+
31
+ # an host object doesn't find a provider
32
+ file { "/etc/hosts":
33
+ content => "127.0.0.1 localhost
34
+ 127.0.1.1 sandbox
35
+ $host_ip puppet
36
+ "
37
+ }
38
+
39
+ # root's password is 'root'
40
+ user { root:
41
+ password => '$1$aybpiIGf$cB7iFDNZvViQtQjEZ5HFQ0'
42
+ }
43
+
44
+ package { [console-common,console-tools,console-data,base-config,man-db,manpages]:
45
+ ensure => absent
46
+ }
47
+
48
+ file { "/etc/network/interfaces":
49
+ content => "auto lo
50
+ iface lo inet loopback
51
+
52
+ auto eth0
53
+ iface eth0 inet static
54
+ address $sandbox_ip
55
+ netmask 255.255.255.0
56
+ gateway $host_ip
57
+ dns-nameservers $host_ip
58
+ "
59
+ }
60
+
61
+ file { "/etc/resolv.conf":
62
+ content => "nameserver $host_ip
63
+ "
64
+ }
65
+
66
+ exec { "apt-get update":
67
+ alias => "apt-update"
68
+ }
69
+
70
+ package { [udev, resolvconf]:
71
+ ensure => present,
72
+ require => Exec["apt-update"]
73
+ }
74
+
75
+ # puppet configuration
76
+
77
+ file { "/etc/default/puppet":
78
+ content => 'START=no
79
+ DAEMON_OPTS="-w 5"
80
+ '
81
+ }
82
+
83
+ file { "/etc/puppet/namespaceauth.conf":
84
+ content => "[puppetrunner]
85
+ allow $host_ip
86
+ "
87
+ }
88
+
89
+ file { "/etc/puppet/puppet.conf":
90
+ content => '[main]
91
+ logdir=/var/log/puppet
92
+ vardir=/var/lib/puppet
93
+ ssldir=/var/lib/puppet/ssl
94
+ rundir=/var/run/puppet
95
+ factpath=$vardir/lib/facter
96
+ pluginsync=false
97
+ color=false
98
+
99
+ [puppetd]
100
+ report=true
101
+ # run puppetd .. every day
102
+ runinterval = 86400
103
+ listen=true
104
+ '
105
+ }
106
+
107
+ exec { "syslog-to-ttyS0":
108
+ command => "echo '*.* -/dev/ttyS0' >> /etc/rsyslog.conf",
109
+ unless => 'grep /dev/ttyS0 /etc/rsyslog.conf'
110
+ }
@@ -0,0 +1,341 @@
1
+ require 'rake/tasklib'
2
+ require 'ping'
3
+ require 'tempfile'
4
+
5
+ class Sandbox < Rake::TaskLib
6
+
7
+ @@images_directory = "/var/tmp"
8
+
9
+ def self.images_directory
10
+ @@images_directory
11
+ end
12
+
13
+ def self.images_directory=(directory)
14
+ @@images_directory = directory
15
+ end
16
+
17
+ @@puppet_file = File.dirname(__FILE__) + '/sandbox.pp'
18
+
19
+ attr_reader :name
20
+ attr_accessor :bootstraper, :ip_address, :host_ip_address, :tap_device
21
+ attr_accessor :disk_size, :memory_size, :mount_point
22
+
23
+ def initialize(name = "sandbox")
24
+ @name = name
25
+
26
+ init
27
+ yield self if block_given?
28
+ define
29
+ end
30
+
31
+ def define
32
+ @bootstraper ||= DebianBoostraper.new
33
+
34
+ @ip_address ||= '172.20.0.2'
35
+ @host_ip_address ||= @ip_address.gsub(/\.[0-9]+$/,'.1')
36
+
37
+ @disk_size ||= '512M'
38
+ @memory_size ||= '128M'
39
+
40
+ @mount_point ||= "/mnt/#{name}"
41
+ @tap_device ||= 'tap0'
42
+ end
43
+
44
+ def init
45
+ namespace @name do
46
+
47
+ desc "Setup local machine to host sandbox"
48
+ task :setup => 'tmp:create' do
49
+ # experimental qemu required to work with kqemu
50
+ sudo "apt-get install -t experimental qemu"
51
+ sudo "module-assistant a-i kqemu"
52
+ sudo "apt-get install uml-utilities"
53
+
54
+ puts <<EOF
55
+
56
+ You need to route network traffic between your sandbox and your local network.
57
+
58
+ For example in your /etc/qemu-ifup:
59
+
60
+ /sbin/ifconfig $1 #{host_ip_address}
61
+ iptables -t nat -A POSTROUTING -s #{host_ip_address}/24 -o eth0 -j MASQUERADE
62
+ sysctl -w net.ipv4.ip_forward=1
63
+
64
+ EOF
65
+ end
66
+
67
+ # Mix between these ways :
68
+ # - http://www.mail-archive.com/qemu-devel@nongnu.org/msg01208.html
69
+ # - http://www.geocities.com/gtalon51/Articles/Minimal_Linux_system/Minimal_Linux_system.html
70
+ # - qemu-make-debian-root
71
+ namespace :create do
72
+ task :image do
73
+ sh "qemu-img create -f raw #{disk_image} #{disk_size}"
74
+ # create the partition table
75
+ sh "echo '63,' | /sbin/sfdisk --no-reread -uS -H16 -S63 #{disk_image}"
76
+ end
77
+
78
+ task :fs do
79
+ # format the filesystem
80
+ begin
81
+ sudo "losetup -o #{fs_offset} /dev/loop0 #{disk_image}"
82
+
83
+ # because '/sbin/sfdisk -s /dev/loop0' returns a wrong value :
84
+ extract_fs_block_size = "/sbin/sfdisk -l #{disk_image} 2> /dev/null | awk '/img1/ { print gensub(\"+\", \"\", \"\", $5) }'"
85
+
86
+ sudo "/sbin/mke2fs -jqF /dev/loop0 `#{extract_fs_block_size}`"
87
+ ensure
88
+ sudo "losetup -d /dev/loop0"
89
+ end
90
+ end
91
+
92
+ task :system do
93
+ # install a debian base system
94
+ mount do
95
+ bootstraper.bootstrap mount_point
96
+ end
97
+ end
98
+
99
+ task :kernel do
100
+ # TODO : install a kernel and a boot loader grub
101
+ # mount do
102
+ # sudo "chroot #{mount_point} sh -c \"echo 'do_initrd = Yes' >> /etc/kernel-img.conf && DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes grub linux-image-2.6-686\""
103
+ # end
104
+ end
105
+
106
+ task :config do
107
+ Tempfile.open('sandbox_puppet_file') do |sandbox_puppet_file|
108
+ sandbox_puppet_file.puts "$host_ip='#{host_ip_address}'"
109
+ sandbox_puppet_file.puts "$sandbox_ip='#{ip_address}'"
110
+ sandbox_puppet_file.puts IO.read(@@puppet_file)
111
+
112
+ sandbox_puppet_file.close
113
+
114
+ # finalize configuration with puppet
115
+ mount do
116
+ sudo "cp #{sandbox_puppet_file.path} #{mount_point}/etc/sandbox.pp"
117
+ sudo "chroot #{mount_point} puppet /etc/sandbox.pp"
118
+ end
119
+ end
120
+ end
121
+
122
+ task :tap_device do
123
+ unless tap_device_exists?
124
+ sudo "tunctl -u #{ENV['USER']} -t #{tap_device}"
125
+ end
126
+ end
127
+
128
+ task :snapshot do
129
+ snapshot(:initial)
130
+ end
131
+ end
132
+
133
+ desc "Create a fresh image for sandbox"
134
+ task :create => [ 'clean', 'create:image', 'create:fs', 'create:system', 'create:kernel', 'create:config', 'create:snapshot' ]
135
+
136
+ desc "Destroy sandbox images"
137
+ task :destroy => 'clean' do
138
+ rm_f disk_image
139
+ rm_f disk_image(:initial)
140
+ end
141
+
142
+ desc "Start sandbox"
143
+ task :start => 'create:tap_device' do
144
+ start
145
+ end
146
+
147
+ desc "Start sandbox from initial image in snapshot"
148
+ task :start_from_initial do
149
+ start :hda => disk_image(:initial), :snapshot => true
150
+ end
151
+
152
+ task :wait do
153
+ wait
154
+ end
155
+
156
+ desc "Stop sandbox"
157
+ task :stop do
158
+ sh "kill -9 `cat tmp/run/#{name}.pid`"
159
+ end
160
+
161
+ task :revert do
162
+ sh "qemu-img convert -O raw #{disk_image(:initial)} #{disk_image}"
163
+ end
164
+
165
+ task :mount do
166
+ mount_image
167
+ end
168
+
169
+ task :umount do
170
+ umount_image
171
+ end
172
+
173
+ task :clean => 'puppet:clean' do
174
+ # clean known_hosts
175
+ sh "sed -i '/#{hostname},#{ip_address}/ d' ~/.ssh/known_hosts"
176
+ end
177
+
178
+ task :status do
179
+ status
180
+ end
181
+
182
+ namespace :puppet do
183
+
184
+ desc "Run puppetd in sandbox"
185
+ task :run do
186
+ sh "./script/puppetrun --host #{hostname}"
187
+ end
188
+
189
+ desc "Sign a request from sandbox"
190
+ task :sign do
191
+ sh "./script/puppetca --sign #{hostname}"
192
+ end
193
+
194
+ task :clean do
195
+ # remove pending request
196
+ sh "rm -f ssl/ca/requests/#{hostname}*.pem"
197
+ # remove signed certificat
198
+ sh "./script/puppetca --clean #{hostname} || true"
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ def start(options = {})
205
+ options = {
206
+ :daemonize => true,
207
+ :snapshot => ENV['SNAPSHOT'],
208
+ :hda => disk_image,
209
+ :initrd => '/initrd.img',
210
+ :kernel => '/vmlinuz',
211
+ :append => 'console=ttyS0 root=/dev/hda1 ro',
212
+ :nographic => true,
213
+ :m => memory_size,
214
+ :net => ["nic", "tap,ifname=#{tap_device}"]
215
+ }.update(options)
216
+
217
+ if options[:daemonize]
218
+ options = {
219
+ :pidfile => "tmp/run/#{name}.pid", :serial => "file:log/#{name}.log"
220
+ }.update(options)
221
+ end
222
+
223
+ options_as_string = options.collect do |name,value|
224
+ argument = "-#{name}"
225
+
226
+ case value
227
+ when Array
228
+ value.collect { |v| "#{argument} '#{v}'" }
229
+ when true
230
+ argument
231
+ when false
232
+ when nil
233
+ when ''
234
+ nil
235
+ else
236
+ "#{argument} '#{value}'"
237
+ end
238
+ end.compact.join(' ')
239
+
240
+ sh "qemu #{options_as_string}"
241
+ end
242
+
243
+ def snapshot(name)
244
+ sh "qemu-img convert -O qcow2 #{disk_image} #{disk_image(name)}"
245
+ end
246
+
247
+ def wait(timeout = 30, max_try_count = 5)
248
+ try_count = 5
249
+ try_timeout = timeout / try_count
250
+
251
+ 5.times do
252
+ if Ping.pingecho(ip_address, try_timeout)
253
+ return
254
+ else
255
+ sleep try_timeout
256
+ end
257
+ end
258
+
259
+ raise "no response from #{hostname} after #{timeout} seconds"
260
+ end
261
+
262
+ def mount(&block)
263
+ begin
264
+ mount_image
265
+ yield mount_point
266
+ ensure
267
+ umount_image
268
+ end
269
+ end
270
+
271
+ def mount_image
272
+ sudo "mkdir #{mount_point}" unless File.exists? mount_point
273
+ sudo "mount -o loop,offset=#{fs_offset} #{disk_image} #{mount_point}"
274
+
275
+ sudo "mount proc #{mount_point}/proc -t proc" if File.exists? "#{mount_point}/proc"
276
+ end
277
+
278
+ def umount_image
279
+ [ "#{mount_point}/proc", mount_point ].each do |mount|
280
+ sudo "umount #{mount} || true"
281
+ end
282
+ end
283
+
284
+ # TODO to be customizable
285
+
286
+ def disk_image(suffix = nil)
287
+ suffix = "-#{suffix}" if suffix
288
+ File.join Sandbox.images_directory, "#{name}#{suffix}.img"
289
+ end
290
+
291
+ def fs_offset
292
+ 32256
293
+ end
294
+
295
+ def hostname
296
+ if name =~ /^sandbox/
297
+ name
298
+ else
299
+ "sandbox-#{name}"
300
+ end
301
+ end
302
+
303
+ def tap_device_exists?
304
+ IO.readlines('/proc/net/dev').any? { |l| l =~ /\s+#{tap_device}/ }
305
+ end
306
+
307
+ def status
308
+ puts "#{hostname} status:"
309
+ puts self.inspect
310
+ end
311
+
312
+ end
313
+
314
+ class DebianBoostraper
315
+
316
+ attr_accessor :version, :mirror
317
+
318
+ def initialize(&block)
319
+ @version = 'lenny'
320
+ @mirror = 'http://ftp.debian.org/debian'
321
+
322
+ yield self if block_given?
323
+ end
324
+
325
+ def bootstrap(root)
326
+ options = {
327
+ :arch => 'i386',
328
+ :exclude => debootstrap_excludes,
329
+ :include => %w{puppet ssh}
330
+ }
331
+
332
+ options_as_string = options.collect{|k,v| "--#{k} #{Array(v).join(',')}"}.join(' ')
333
+ sudo "debootstrap #{options_as_string} #{version} #{root} #{mirror}"
334
+ end
335
+
336
+ def debootstrap_excludes
337
+ # excluded by qemu-make-debian-root
338
+ %w{syslinux at exim mailx libstdc++2.10-glibc2.2 mbr setserial fdutils info ipchains iptables lilo pcmcia-cs ppp pppoe pppoeconf pppconfig wget telnet cron logrotate exim4 exim4-base exim4-config exim4-daemon-light pciutils modconf tasksel}
339
+ end
340
+
341
+ end
data/tasks/tmp.rake ADDED
@@ -0,0 +1,24 @@
1
+ namespace :tmp do
2
+
3
+ TMP_DIRECTORIES = %w( tmp/lib tmp/ssl tmp/run )
4
+
5
+ desc "Clear puppetmaster data, ssl, pids files from tmp/"
6
+ task :clear => [ "tmp:lib:clear", "tmp:ssl:clear", "tmp:run:clear" ]
7
+
8
+ desc "Creates tmp directories for puppetmaster data and ssl files"
9
+ task :create do
10
+ FileUtils.mkdir_p(TMP_DIRECTORIES)
11
+ end
12
+
13
+ TMP_DIRECTORIES.each do |tmp_directory|
14
+ name = File.basename(tmp_directory)
15
+
16
+ namespace name do
17
+ desc "Clears all files in #{tmp_directory}"
18
+ task :clear do
19
+ FileUtils.rm(Dir["#{tmp_directory}/[^.]*"])
20
+ end
21
+ end
22
+ end
23
+
24
+ end
data/tasks/utils.rake ADDED
@@ -0,0 +1,17 @@
1
+ def sudo(command)
2
+ sh "sudo #{command}"
3
+ end
4
+
5
+ def ssh(host, command, options = {})
6
+ target = [ options.delete(:user), host ].compact.join('@')
7
+
8
+ arguments = []
9
+
10
+ arguments << "-p #{options.delete(:port)}" if options[:port]
11
+ arguments = arguments + options.collect do |key, value|
12
+ formatted_key = key.to_s.gsub('_','')
13
+ "-o '#{formatted_key} #{value}'"
14
+ end
15
+
16
+ sh "ssh -t #{arguments.join(' ')} #{target} '#{command}'"
17
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: albanpeignier-gepetto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alban Peignier
@@ -9,9 +9,18 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-19 00:00:00 -08:00
13
- default_executable:
12
+ date: 2009-01-31 00:00:00 -08:00
13
+ default_executable: gepetto
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rubigen
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.5.2
23
+ version:
15
24
  - !ruby/object:Gem::Dependency
16
25
  name: newgem
17
26
  version_requirement:
@@ -33,14 +42,48 @@ dependencies:
33
42
  description: "A helper suite for Puppet projects to create, manage and help daily development More information about Puppet: http://reductivelabs.com/trac/puppet/"
34
43
  email:
35
44
  - alban.peignier@free.fr
36
- executables: []
37
-
45
+ executables:
46
+ - gepetto
38
47
  extensions: []
39
48
 
40
- extra_rdoc_files: []
41
-
42
- files: []
43
-
49
+ extra_rdoc_files:
50
+ - History.txt
51
+ - Manifest.txt
52
+ - README.rdoc
53
+ files:
54
+ - History.txt
55
+ - Manifest.txt
56
+ - README.rdoc
57
+ - Rakefile
58
+ - app_generators/gepetto/USAGE
59
+ - app_generators/gepetto/gepetto_generator.rb
60
+ - app_generators/gepetto/templates/Rakefile
61
+ - app_generators/gepetto/templates/config/fileserver.conf
62
+ - app_generators/gepetto/templates/config/puppet.conf
63
+ - app_generators/gepetto/templates/manifests/nodes.pp
64
+ - app_generators/gepetto/templates/manifests/site.pp
65
+ - app_generators/gepetto/templates/manifests/templates.pp
66
+ - app_generators/gepetto/templates/script/module
67
+ - app_generators/gepetto/templates/script/puppetca
68
+ - app_generators/gepetto/templates/script/puppetmasterd
69
+ - app_generators/gepetto/templates/script/puppetrun
70
+ - bin/gepetto
71
+ - gepetto.gemspec
72
+ - lib/gepetto.rb
73
+ - lib/gepetto/module.rb
74
+ - lib/gepetto/tasks.rb
75
+ - puppet_generators/module/USAGE
76
+ - puppet_generators/module/module_generator.rb
77
+ - puppet_generators/module/templates/README
78
+ - puppet_generators/module/templates/manifests/init.pp
79
+ - script/destroy
80
+ - script/generate
81
+ - tasks/log.rake
82
+ - tasks/puppet.rake
83
+ - tasks/sandbox.pp
84
+ - tasks/sandbox.rake
85
+ - tasks/tmp.rake
86
+ - tasks/utils.rake
44
87
  has_rdoc: true
45
88
  homepage: http://github.com/albanpeignier/gepetto/
46
89
  post_install_message: