gepetto 0.0.8
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/History.txt +4 -0
- data/Manifest.txt +35 -0
- data/README.rdoc +212 -0
- data/Rakefile +28 -0
- data/app_generators/gepetto/USAGE +0 -0
- data/app_generators/gepetto/gepetto_generator.rb +35 -0
- data/app_generators/gepetto/templates/Rakefile +24 -0
- data/app_generators/gepetto/templates/config/fileserver.conf +7 -0
- data/app_generators/gepetto/templates/config/puppet.conf +11 -0
- data/app_generators/gepetto/templates/manifests/classes/empty.pp +1 -0
- data/app_generators/gepetto/templates/manifests/defaults.pp +12 -0
- data/app_generators/gepetto/templates/manifests/nodes.pp +5 -0
- data/app_generators/gepetto/templates/manifests/site.pp +9 -0
- data/app_generators/gepetto/templates/manifests/templates.pp +0 -0
- data/app_generators/gepetto/templates/script/module +67 -0
- data/app_generators/gepetto/templates/script/puppetca +3 -0
- data/app_generators/gepetto/templates/script/puppetmasterd +13 -0
- data/app_generators/gepetto/templates/script/puppetrun +2 -0
- data/bin/gepetto +18 -0
- data/gepetto.gemspec +37 -0
- data/lib/gepetto.rb +6 -0
- data/lib/gepetto/tasks.rb +1 -0
- data/puppet_generators/module/USAGE +18 -0
- data/puppet_generators/module/module_generator.rb +24 -0
- data/puppet_generators/module/templates/README +0 -0
- data/puppet_generators/module/templates/manifests/init.pp +0 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/tasks/host.pp +75 -0
- data/tasks/log.rake +9 -0
- data/tasks/puppet.rake +8 -0
- data/tasks/sandbox.pp +101 -0
- data/tasks/sandbox.rake +437 -0
- data/tasks/tmp.rake +24 -0
- data/tasks/utils.rake +17 -0
- metadata +104 -0
| @@ -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 --confdir=$PWD/config"
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            OPTIONS="$OPTIONS --certname=puppet --logdest=console"
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            /usr/sbin/puppetmasterd --no-daemonize $OPTIONS $*
         | 
    
        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,37 @@ | |
| 1 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Gem::Specification.new do |s|
         | 
| 4 | 
            +
              s.name = %q{gepetto}
         | 
| 5 | 
            +
              s.version = "0.0.7"
         | 
| 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-08-20}
         | 
| 10 | 
            +
              s.default_executable = %q{gepetto}
         | 
| 11 | 
            +
              s.description = %q{A helper suite for Puppet projects to create, manage and help daily development
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            More information about Puppet: http://reductivelabs.com/trac/puppet/}
         | 
| 14 | 
            +
              s.email = ["alban.peignier@free.fr"]
         | 
| 15 | 
            +
              s.executables = ["gepetto"]
         | 
| 16 | 
            +
              s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
         | 
| 17 | 
            +
              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/classes/empty.pp", "app_generators/gepetto/templates/manifests/defaults.pp", "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/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/host.pp", "tasks/log.rake", "tasks/puppet.rake", "tasks/sandbox.pp", "tasks/sandbox.rake", "tasks/tmp.rake", "tasks/utils.rake"]
         | 
| 18 | 
            +
              s.homepage = %q{http://github.com/albanpeignier/gepetto/}
         | 
| 19 | 
            +
              s.rdoc_options = ["--main", "README.rdoc"]
         | 
| 20 | 
            +
              s.require_paths = ["lib"]
         | 
| 21 | 
            +
              s.rubyforge_project = %q{gepetto}
         | 
| 22 | 
            +
              s.rubygems_version = %q{1.3.4}
         | 
| 23 | 
            +
              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/}
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              if s.respond_to? :specification_version then
         | 
| 26 | 
            +
                current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
         | 
| 27 | 
            +
                s.specification_version = 3
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
         | 
| 30 | 
            +
                  s.add_development_dependency(%q<hoe>, [">= 2.3.3"])
         | 
| 31 | 
            +
                else
         | 
| 32 | 
            +
                  s.add_dependency(%q<hoe>, [">= 2.3.3"])
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              else
         | 
| 35 | 
            +
                s.add_dependency(%q<hoe>, [">= 2.3.3"])
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
    
        data/lib/gepetto.rb
    ADDED
    
    
| @@ -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
         | 
| 
            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/host.pp
    ADDED
    
    | @@ -0,0 +1,75 @@ | |
| 1 | 
            +
            Exec { path => "/usr/bin:/usr/sbin/:/bin:/sbin" }
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # install qemu
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            package { qemu: 
         | 
| 6 | 
            +
              ensure => "latest"
         | 
| 7 | 
            +
            }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # compile kqemu module 
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            package { kqemu-source:
         | 
| 12 | 
            +
              ensure => "latest",
         | 
| 13 | 
            +
              require => Package[qemu]
         | 
| 14 | 
            +
            }
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            exec { "modass-kqemu":
         | 
| 17 | 
            +
              # modass returns 249 with non-inter ...
         | 
| 18 | 
            +
              command => 'module-assistant --non-inter a-i kqemu || dpkg -l "kqemu-modules-`uname -r`" | grep ^ii',
         | 
| 19 | 
            +
              unless => 'dpkg -l "kqemu-modules-`uname -r`" | grep ^ii',
         | 
| 20 | 
            +
              require => Package[kqemu-source]
         | 
| 21 | 
            +
            }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            exec { "add kqemu in /etc/modules":
         | 
| 24 | 
            +
              command => "echo kqemu >> /etc/modules",
         | 
| 25 | 
            +
              unless => "grep kqemu /etc/modules",
         | 
| 26 | 
            +
              require => Exec["modass-kqemu"]
         | 
| 27 | 
            +
            }
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            exec { "modprobe-kqemu":
         | 
| 30 | 
            +
              command => "modprobe kqemu",
         | 
| 31 | 
            +
              unless => "lsmod | grep kqemu",
         | 
| 32 | 
            +
              require => Exec["modass-kqemu"]
         | 
| 33 | 
            +
            }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            file { "/dev/kqemu":
         | 
| 36 | 
            +
              # default permissions on debian, but not on ubuntu
         | 
| 37 | 
            +
              mode => 666,
         | 
| 38 | 
            +
              require => Exec["modprobe-kqemu"]
         | 
| 39 | 
            +
            }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            # install uml-utilities for tunctl 
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            package { uml-utilities: }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            exec { "add tun in /etc/modules":
         | 
| 46 | 
            +
              command => "echo tun >> /etc/modules",
         | 
| 47 | 
            +
              unless => "grep tun /etc/modules"
         | 
| 48 | 
            +
            }
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            exec { "modprobe tun":
         | 
| 51 | 
            +
              unless => "lsmod | grep tun"
         | 
| 52 | 
            +
            }
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            file { "/dev/net/tun":
         | 
| 55 | 
            +
              mode => 666
         | 
| 56 | 
            +
            }
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            # provide a basic qemu-ifup
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            file { "/etc/qemu-ifup":
         | 
| 61 | 
            +
              mode => 755,
         | 
| 62 | 
            +
              content => '#!/bin/sh -x
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            if [ "$USER" != "root" -o "$1" != "sudo" ]; then
         | 
| 65 | 
            +
              exec sudo -p "Password for $0:" $0 sudo $1
         | 
| 66 | 
            +
            fi
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            [ "$1" = "sudo" ] && shift
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            /sbin/ifconfig $1 172.20.0.1
         | 
| 71 | 
            +
            iptables -t nat -A POSTROUTING -s 172.20.0.1/24 -o eth0 -j MASQUERADE
         | 
| 72 | 
            +
            sysctl -w net.ipv4.ip_forward=1
         | 
| 73 | 
            +
            ',
         | 
| 74 | 
            +
              require => Package[qemu]
         | 
| 75 | 
            +
            }
         | 
    
        data/tasks/log.rake
    ADDED
    
    
    
        data/tasks/puppet.rake
    ADDED
    
    
    
        data/tasks/sandbox.pp
    ADDED
    
    | @@ -0,0 +1,101 @@ | |
| 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 | 
            +
            # if network configuration changes, eth0 is renamed by udev :-/
         | 
| 49 | 
            +
            file { "/etc/udev/rules.d/70-persistent-net.rules":
         | 
| 50 | 
            +
              ensure => absent
         | 
| 51 | 
            +
            }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            file { "/etc/network/interfaces":
         | 
| 54 | 
            +
              content => "auto lo
         | 
| 55 | 
            +
            iface lo inet loopback
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            auto eth0
         | 
| 58 | 
            +
            iface eth0 inet static
         | 
| 59 | 
            +
                    address $sandbox_ip
         | 
| 60 | 
            +
                    netmask 255.255.255.0
         | 
| 61 | 
            +
                    gateway $host_ip
         | 
| 62 | 
            +
                    dns-nameservers $host_ip
         | 
| 63 | 
            +
            "
         | 
| 64 | 
            +
            }
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            # puppet configuration
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            file { "/etc/default/puppet":
         | 
| 69 | 
            +
              content => 'START=no
         | 
| 70 | 
            +
            DAEMON_OPTS="-w 5"
         | 
| 71 | 
            +
            '
         | 
| 72 | 
            +
            }
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            file { "/etc/puppet/namespaceauth.conf":
         | 
| 75 | 
            +
              content => "[puppetrunner]
         | 
| 76 | 
            +
              allow $host_ip
         | 
| 77 | 
            +
            "
         | 
| 78 | 
            +
            }
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            file { "/etc/puppet/puppet.conf":
         | 
| 81 | 
            +
              content => '[main]
         | 
| 82 | 
            +
            logdir=/var/log/puppet
         | 
| 83 | 
            +
            vardir=/var/lib/puppet
         | 
| 84 | 
            +
            ssldir=/var/lib/puppet/ssl
         | 
| 85 | 
            +
            rundir=/var/run/puppet
         | 
| 86 | 
            +
            factpath=$vardir/lib/facter
         | 
| 87 | 
            +
            pluginsync=false
         | 
| 88 | 
            +
            color=false
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            [puppetd]
         | 
| 91 | 
            +
            report=true
         | 
| 92 | 
            +
            # run puppetd .. every day
         | 
| 93 | 
            +
            runinterval = 86400
         | 
| 94 | 
            +
            listen=true
         | 
| 95 | 
            +
            '
         | 
| 96 | 
            +
            }
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            exec { "syslog-to-ttyS0":
         | 
| 99 | 
            +
              command => "echo '*.*		-/dev/ttyS0' >> /etc/rsyslog.conf",
         | 
| 100 | 
            +
              unless => 'grep /dev/ttyS0 /etc/rsyslog.conf'
         | 
| 101 | 
            +
            }
         | 
    
        data/tasks/sandbox.rake
    ADDED
    
    | @@ -0,0 +1,437 @@ | |
| 1 | 
            +
            require 'rake/tasklib'
         | 
| 2 | 
            +
            require 'ping'
         | 
| 3 | 
            +
            require 'tempfile'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class Sandbox < Rake::TaskLib
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def self.default_architecture
         | 
| 8 | 
            +
                case PLATFORM
         | 
| 9 | 
            +
                when /x86_64/
         | 
| 10 | 
            +
                  "amd64"
         | 
| 11 | 
            +
                else
         | 
| 12 | 
            +
                  "i386"
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              @@images_directory = "/var/tmp"
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def self.images_directory
         | 
| 19 | 
            +
                @@images_directory
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def self.images_directory=(directory)
         | 
| 23 | 
            +
                @@images_directory = directory
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              def puppet_file(name)
         | 
| 27 | 
            +
                File.dirname(__FILE__) + "/#{name}.pp"
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              attr_reader :name
         | 
| 31 | 
            +
              attr_accessor :bootstraper, :ip_address, :host_ip_address, :tap_device
         | 
| 32 | 
            +
              attr_accessor :disk_size, :memory_size, :mount_point
         | 
| 33 | 
            +
              attr_accessor :architecture
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              def initialize(name = "sandbox")
         | 
| 36 | 
            +
                @name = name
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                init
         | 
| 39 | 
            +
                yield self if block_given?
         | 
| 40 | 
            +
                define
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              def define
         | 
| 44 | 
            +
                @architecture = Sandbox.default_architecture
         | 
| 45 | 
            +
                bootstraper = DebianBoostraper.new
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                @ip_address ||= '172.20.0.2'
         | 
| 48 | 
            +
                @host_ip_address ||= @ip_address.gsub(/\.[0-9]+$/,'.1')
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                @disk_size ||= '512M'
         | 
| 51 | 
            +
                @memory_size ||= '128M'
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                @mount_point ||= "/mnt/#{name}"
         | 
| 54 | 
            +
                @tap_device ||= 'tap0'
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              def bootstraper=(bootstraper)
         | 
| 58 | 
            +
                @bootstraper = bootstraper
         | 
| 59 | 
            +
                sync_architecture
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              def architecture=(architecture)
         | 
| 63 | 
            +
                @architecture = architecture
         | 
| 64 | 
            +
                sync_architecture
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def sync_architecture
         | 
| 68 | 
            +
                if self.bootstraper and self.architecture 
         | 
| 69 | 
            +
                  self.bootstraper.architecture = self.architecture 
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              def kernel_architecture
         | 
| 74 | 
            +
                case self.architecture
         | 
| 75 | 
            +
                when 'i386'
         | 
| 76 | 
            +
                  '686'
         | 
| 77 | 
            +
                else 
         | 
| 78 | 
            +
                  self.architecture
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
              def init
         | 
| 83 | 
            +
                namespace @name do
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  desc "Setup local machine to host sandbox"
         | 
| 86 | 
            +
                  task :setup => 'tmp:create' do
         | 
| 87 | 
            +
                    sudo "puppet #{puppet_file(:host)}"
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  # Mix between these ways :
         | 
| 91 | 
            +
                  # - http://www.mail-archive.com/qemu-devel@nongnu.org/msg01208.html
         | 
| 92 | 
            +
                  # - http://www.geocities.com/gtalon51/Articles/Minimal_Linux_system/Minimal_Linux_system.html
         | 
| 93 | 
            +
                  # - qemu-make-debian-root
         | 
| 94 | 
            +
                  namespace :create do
         | 
| 95 | 
            +
                    task :image do
         | 
| 96 | 
            +
                      sh "qemu-img create -f raw #{disk_image} #{disk_size}"
         | 
| 97 | 
            +
                      # create the partition table
         | 
| 98 | 
            +
                      sh "echo '63,' | /sbin/sfdisk --no-reread -uS -H16 -S63 #{disk_image}"
         | 
| 99 | 
            +
                    end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                    task :fs do 
         | 
| 102 | 
            +
                      # format the filesystem
         | 
| 103 | 
            +
                      begin
         | 
| 104 | 
            +
                        sudo "losetup -o #{fs_offset} /dev/loop0 #{disk_image}"
         | 
| 105 | 
            +
                        
         | 
| 106 | 
            +
                        # because '/sbin/sfdisk -s /dev/loop0' returns a wrong value :
         | 
| 107 | 
            +
                        extract_fs_block_size = "/sbin/sfdisk -l #{disk_image} 2> /dev/null | awk '/img1/ { gsub(\"\\+\", \"\", $5); print $5 }'"
         | 
| 108 | 
            +
                        
         | 
| 109 | 
            +
                        sudo "/sbin/mke2fs -jqF /dev/loop0 `#{extract_fs_block_size}`"
         | 
| 110 | 
            +
                      ensure
         | 
| 111 | 
            +
                        sudo "losetup -d /dev/loop0"
         | 
| 112 | 
            +
                      end
         | 
| 113 | 
            +
                    end
         | 
| 114 | 
            +
                    
         | 
| 115 | 
            +
                    task :system do
         | 
| 116 | 
            +
                      # install a debian base system
         | 
| 117 | 
            +
                      mount do 
         | 
| 118 | 
            +
                        bootstraper.bootstrap mount_point
         | 
| 119 | 
            +
                      end
         | 
| 120 | 
            +
                    end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                    task :kernel do
         | 
| 123 | 
            +
                      mount do
         | 
| 124 | 
            +
                        chroot_sh "echo 'do_initrd = Yes' >> /etc/kernel-img.conf"
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                        kernel_package =
         | 
| 127 | 
            +
                          case self.bootstraper.version
         | 
| 128 | 
            +
                          when 'etch', 'lenny'
         | 
| 129 | 
            +
                            "linux-image-2.6-#{kernel_architecture}"
         | 
| 130 | 
            +
                          when 'hardy'    
         | 
| 131 | 
            +
                            'linux-image-2.6.24-16-generic'
         | 
| 132 | 
            +
                          when 'intrepid'
         | 
| 133 | 
            +
                            'linux-image-generic'
         | 
| 134 | 
            +
                          end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                        chroot_sh "DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes #{kernel_package}"
         | 
| 137 | 
            +
                      end
         | 
| 138 | 
            +
                    end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                    task :grub do
         | 
| 141 | 
            +
                      mount do
         | 
| 142 | 
            +
                        chroot_sh "DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes grub"
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                        grub_dir = "#{mount_point}/boot/grub"
         | 
| 145 | 
            +
                        chroot_sh "mkdir /boot/grub" unless File.exists?(grub_dir)
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                        stage_files = Dir["#{mount_point}/usr/lib/grub/**/stage?", "#{mount_point}/usr/lib/grub/**/e2fs_stage1_5"]
         | 
| 148 | 
            +
                        sudo "cp #{stage_files.join(' ')} #{grub_dir}"
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                        Tempfile.open('menu_lst') do |f|
         | 
| 151 | 
            +
                          f.write(['default 0',
         | 
| 152 | 
            +
                                   'timeout 0',
         | 
| 153 | 
            +
                                   'title Linux',
         | 
| 154 | 
            +
                                   'root (hd0,0)',
         | 
| 155 | 
            +
                                   'kernel /vmlinuz root=/dev/hda1 ro',
         | 
| 156 | 
            +
                                   'initrd /initrd.img'].join("\n"))
         | 
| 157 | 
            +
                          f.close
         | 
| 158 | 
            +
                          sudo "cp #{f.path} #{grub_dir}/menu.lst"
         | 
| 159 | 
            +
                        end
         | 
| 160 | 
            +
                      end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                      Tempfile.open('grub_input') do |f| 
         | 
| 163 | 
            +
                        f.write(["device (hd0) #{disk_image}",
         | 
| 164 | 
            +
                                 "root (hd0,0)",
         | 
| 165 | 
            +
                                 "setup (hd0)",
         | 
| 166 | 
            +
                                 "quit"].join("\n"))
         | 
| 167 | 
            +
                        f.close
         | 
| 168 | 
            +
                        sudo "grub --device-map=/dev/null < #{f.path}"
         | 
| 169 | 
            +
                      end
         | 
| 170 | 
            +
                    end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                    task :config do
         | 
| 173 | 
            +
                      Tempfile.open('sandbox_puppet_file') do |sandbox_puppet_file|
         | 
| 174 | 
            +
                        sandbox_puppet_file.puts "$host_ip='#{host_ip_address}'"            
         | 
| 175 | 
            +
                        sandbox_puppet_file.puts "$sandbox_ip='#{ip_address}'"            
         | 
| 176 | 
            +
                        sandbox_puppet_file.puts IO.read(puppet_file(:sandbox))
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                        sandbox_puppet_file.close
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                        # finalize configuration with puppet
         | 
| 181 | 
            +
                        mount do
         | 
| 182 | 
            +
                          sudo "cp #{sandbox_puppet_file.path} #{mount_point}/etc/sandbox.pp"
         | 
| 183 | 
            +
                          sudo "chroot #{mount_point} puppet /etc/sandbox.pp"
         | 
| 184 | 
            +
                        end
         | 
| 185 | 
            +
                      end
         | 
| 186 | 
            +
                    end
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                    task :tap_device do
         | 
| 189 | 
            +
                      unless tap_device_exists?
         | 
| 190 | 
            +
                        sudo "tunctl -u #{ENV['USER']} -t #{tap_device}"
         | 
| 191 | 
            +
                      end
         | 
| 192 | 
            +
                    end
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                    task :snapshot do
         | 
| 195 | 
            +
                      snapshot(:initial)
         | 
| 196 | 
            +
                    end
         | 
| 197 | 
            +
                  end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                  desc "Create a fresh image for sandbox"
         | 
| 200 | 
            +
                  task :create => [ 'clean', 'create:image', 'create:fs', 'create:system', 'create:kernel', 'create:grub', 'create:config', 'create:snapshot' ]
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                  desc "Destroy sandbox images"
         | 
| 203 | 
            +
                  task :destroy => 'clean' do
         | 
| 204 | 
            +
                    rm_f disk_image
         | 
| 205 | 
            +
                    rm_f disk_image(:initial)
         | 
| 206 | 
            +
                  end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                  desc "Start sandbox"
         | 
| 209 | 
            +
                  task :start => ['create:tap_device', 'tmp:create'] do
         | 
| 210 | 
            +
                    start
         | 
| 211 | 
            +
                  end
         | 
| 212 | 
            +
             | 
| 213 | 
            +
                  desc "Start sandbox from initial image in snapshot"
         | 
| 214 | 
            +
                  task :start_from_initial do
         | 
| 215 | 
            +
                    start :hda => disk_image(:initial), :snapshot => true
         | 
| 216 | 
            +
                  end
         | 
| 217 | 
            +
             | 
| 218 | 
            +
                  task :wait do 
         | 
| 219 | 
            +
                    wait
         | 
| 220 | 
            +
                  end
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                  desc "Stop sandbox"
         | 
| 223 | 
            +
                  task :stop do
         | 
| 224 | 
            +
                    sh "kill -9 `cat tmp/run/#{name}.pid`"
         | 
| 225 | 
            +
                  end
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                  task :revert do
         | 
| 228 | 
            +
                    sh "qemu-img convert -O raw #{disk_image(:initial)} #{disk_image}"
         | 
| 229 | 
            +
                  end
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                  task :mount do
         | 
| 232 | 
            +
                    mount_image
         | 
| 233 | 
            +
                  end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                  task :umount do
         | 
| 236 | 
            +
                    umount_image
         | 
| 237 | 
            +
                  end
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                  task :clean => 'puppet:clean' do
         | 
| 240 | 
            +
                    # clean known_hosts
         | 
| 241 | 
            +
                    known_hosts_file="#{ENV['HOME']}/.ssh/known_hosts"
         | 
| 242 | 
            +
                    sh "sed -i '/#{hostname},#{ip_address}/ d' #{known_hosts_file}" if File.exists?(known_hosts_file)
         | 
| 243 | 
            +
                  end
         | 
| 244 | 
            +
             | 
| 245 | 
            +
                  task :status do
         | 
| 246 | 
            +
                    status
         | 
| 247 | 
            +
                  end
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                  namespace :puppet do
         | 
| 250 | 
            +
             | 
| 251 | 
            +
                    desc "Run puppetd in sandbox"
         | 
| 252 | 
            +
                    task :run do
         | 
| 253 | 
            +
                      sh "./script/puppetrun --host #{hostname}"
         | 
| 254 | 
            +
                    end
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                    desc "Sign a request from sandbox"
         | 
| 257 | 
            +
                    task :sign do
         | 
| 258 | 
            +
                      sh "./script/puppetca --sign #{hostname}"
         | 
| 259 | 
            +
                    end
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                    task :clean do 
         | 
| 262 | 
            +
                      # remove pending request
         | 
| 263 | 
            +
                      sh "rm -f ssl/ca/requests/#{hostname}*.pem"
         | 
| 264 | 
            +
                      # remove signed certificat
         | 
| 265 | 
            +
                      sh "./script/puppetca --clean #{hostname} || true"
         | 
| 266 | 
            +
                    end
         | 
| 267 | 
            +
                  end
         | 
| 268 | 
            +
                end
         | 
| 269 | 
            +
              end
         | 
| 270 | 
            +
             | 
| 271 | 
            +
              def start(options = {})
         | 
| 272 | 
            +
                options = {
         | 
| 273 | 
            +
                  :daemonize => true,
         | 
| 274 | 
            +
                  :snapshot => ENV['SNAPSHOT'],
         | 
| 275 | 
            +
                  :hda => disk_image,
         | 
| 276 | 
            +
                  :nographic => false,
         | 
| 277 | 
            +
                  :m => memory_size,
         | 
| 278 | 
            +
                  :net => ["nic", "tap,ifname=#{tap_device}"]
         | 
| 279 | 
            +
                }.update(options)
         | 
| 280 | 
            +
             | 
| 281 | 
            +
                if options[:daemonize]
         | 
| 282 | 
            +
                  options = {
         | 
| 283 | 
            +
                    :pidfile => File.expand_path("tmp/run/#{name}.pid"), :serial => "file:" + File.expand_path("log/#{name}.log")
         | 
| 284 | 
            +
                  }.update(options)
         | 
| 285 | 
            +
                end
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                options_as_string = options.collect do |name,value| 
         | 
| 288 | 
            +
                  argument = "-#{name}"  
         | 
| 289 | 
            +
             | 
| 290 | 
            +
                  case value
         | 
| 291 | 
            +
                  when Array
         | 
| 292 | 
            +
                    value.collect { |v| "#{argument} '#{v}'" }
         | 
| 293 | 
            +
                  when true
         | 
| 294 | 
            +
                    argument
         | 
| 295 | 
            +
                  when false
         | 
| 296 | 
            +
                  when nil
         | 
| 297 | 
            +
                  when ''
         | 
| 298 | 
            +
                    nil
         | 
| 299 | 
            +
                  else
         | 
| 300 | 
            +
                    "#{argument} '#{value}'"
         | 
| 301 | 
            +
                  end
         | 
| 302 | 
            +
                end.compact.join(' ')
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                qemu_command = 
         | 
| 305 | 
            +
                  case PLATFORM
         | 
| 306 | 
            +
                  when /x86_64/
         | 
| 307 | 
            +
                    "qemu-system-x86_64"
         | 
| 308 | 
            +
                  else
         | 
| 309 | 
            +
                    "qemu"
         | 
| 310 | 
            +
                  end
         | 
| 311 | 
            +
             | 
| 312 | 
            +
                sh "#{qemu_command} #{options_as_string}"
         | 
| 313 | 
            +
              end
         | 
| 314 | 
            +
             | 
| 315 | 
            +
              def snapshot(name)
         | 
| 316 | 
            +
                sh "qemu-img convert -O qcow2 #{disk_image} #{disk_image(name)}"
         | 
| 317 | 
            +
              end
         | 
| 318 | 
            +
             | 
| 319 | 
            +
              def wait(timeout = 30, max_try_count = 5)
         | 
| 320 | 
            +
                try_count = 5
         | 
| 321 | 
            +
                try_timeout = timeout / try_count
         | 
| 322 | 
            +
             | 
| 323 | 
            +
                5.times do
         | 
| 324 | 
            +
                  if Ping.pingecho(ip_address, try_timeout)
         | 
| 325 | 
            +
                    return
         | 
| 326 | 
            +
                  else
         | 
| 327 | 
            +
                    sleep try_timeout
         | 
| 328 | 
            +
                  end
         | 
| 329 | 
            +
                end
         | 
| 330 | 
            +
             | 
| 331 | 
            +
                raise "no response from #{hostname} after #{timeout} seconds"
         | 
| 332 | 
            +
              end
         | 
| 333 | 
            +
             | 
| 334 | 
            +
              def mount(&block)
         | 
| 335 | 
            +
                begin
         | 
| 336 | 
            +
                  mount_image
         | 
| 337 | 
            +
                  yield mount_point
         | 
| 338 | 
            +
                ensure
         | 
| 339 | 
            +
                  umount_image
         | 
| 340 | 
            +
                end
         | 
| 341 | 
            +
              end
         | 
| 342 | 
            +
             | 
| 343 | 
            +
              def mount_image
         | 
| 344 | 
            +
                sudo "mkdir #{mount_point}" unless File.exists? mount_point
         | 
| 345 | 
            +
                sudo "mount -o loop,offset=#{fs_offset} #{disk_image} #{mount_point}"
         | 
| 346 | 
            +
                
         | 
| 347 | 
            +
                sudo "mount proc #{mount_point}/proc -t proc" if File.exists? "#{mount_point}/proc"
         | 
| 348 | 
            +
              end
         | 
| 349 | 
            +
             | 
| 350 | 
            +
              def umount_image
         | 
| 351 | 
            +
                [ "#{mount_point}/proc", mount_point ].each do |mount|
         | 
| 352 | 
            +
                  sudo "umount #{mount} || true"
         | 
| 353 | 
            +
                end
         | 
| 354 | 
            +
              end
         | 
| 355 | 
            +
             | 
| 356 | 
            +
              # TODO to be customizable
         | 
| 357 | 
            +
             | 
| 358 | 
            +
              def disk_image(suffix = nil)
         | 
| 359 | 
            +
                suffix = "-#{suffix}" if suffix
         | 
| 360 | 
            +
                File.join Sandbox.images_directory, "#{name}#{suffix}.img"    
         | 
| 361 | 
            +
              end
         | 
| 362 | 
            +
             | 
| 363 | 
            +
              def fs_offset
         | 
| 364 | 
            +
                32256
         | 
| 365 | 
            +
              end
         | 
| 366 | 
            +
             | 
| 367 | 
            +
              def hostname
         | 
| 368 | 
            +
                if name =~ /^sandbox/
         | 
| 369 | 
            +
                  name
         | 
| 370 | 
            +
                else
         | 
| 371 | 
            +
                  "sandbox-#{name}"
         | 
| 372 | 
            +
                end
         | 
| 373 | 
            +
              end
         | 
| 374 | 
            +
             | 
| 375 | 
            +
              def tap_device_exists?
         | 
| 376 | 
            +
                IO.readlines('/proc/net/dev').any? { |l| l =~ /\s+#{tap_device}/ }
         | 
| 377 | 
            +
              end
         | 
| 378 | 
            +
             | 
| 379 | 
            +
              def status
         | 
| 380 | 
            +
                puts "#{hostname} status:"
         | 
| 381 | 
            +
                puts self.inspect
         | 
| 382 | 
            +
              end
         | 
| 383 | 
            +
             | 
| 384 | 
            +
              def chroot_sh(cmd)
         | 
| 385 | 
            +
                sudo "chroot #{mount_point} sh -c \"#{cmd}\""
         | 
| 386 | 
            +
              end
         | 
| 387 | 
            +
             | 
| 388 | 
            +
            end
         | 
| 389 | 
            +
             | 
| 390 | 
            +
            class DebianBoostraper
         | 
| 391 | 
            +
             | 
| 392 | 
            +
              attr_accessor :version, :mirror, :include, :exclude, :architecture
         | 
| 393 | 
            +
             | 
| 394 | 
            +
              def initialize(&block)
         | 
| 395 | 
            +
                default_attributes
         | 
| 396 | 
            +
             | 
| 397 | 
            +
                @include = %w{puppet ssh udev resolvconf}
         | 
| 398 | 
            +
                @exclude = %w{syslinux at exim mailx libstdc++2.10-glibc2.2 mbr setserial fdutils info ipchains iptables lilo pcmcia-cs ppp pppoe pppoeconf pppconfig telnet exim4 exim4-base exim4-config exim4-daemon-light pciutils modconf tasksel console-common console-tools console-data base-config man-db manpages}
         | 
| 399 | 
            +
             | 
| 400 | 
            +
                yield self if block_given?
         | 
| 401 | 
            +
              end
         | 
| 402 | 
            +
             | 
| 403 | 
            +
              def default_attributes
         | 
| 404 | 
            +
                @version = 'lenny'
         | 
| 405 | 
            +
                @mirror = 'http://ftp.debian.org/debian'
         | 
| 406 | 
            +
                @architecture = Sandbox.default_architecture
         | 
| 407 | 
            +
              end
         | 
| 408 | 
            +
             | 
| 409 | 
            +
              def bootstrap(root)
         | 
| 410 | 
            +
                options_as_string = options.collect{|k,v| "--#{k} #{Array(v).join(',')}"}.join(' ')
         | 
| 411 | 
            +
                sudo "debootstrap #{options_as_string} #{version} #{root} #{mirror}"
         | 
| 412 | 
            +
              end
         | 
| 413 | 
            +
             | 
| 414 | 
            +
              def options
         | 
| 415 | 
            +
                {
         | 
| 416 | 
            +
                  :arch => architecture,  
         | 
| 417 | 
            +
                  :exclude => @exclude,
         | 
| 418 | 
            +
                  :include => @include
         | 
| 419 | 
            +
                }
         | 
| 420 | 
            +
              end
         | 
| 421 | 
            +
             | 
| 422 | 
            +
            end
         | 
| 423 | 
            +
             | 
| 424 | 
            +
            class UbuntuBoostraper < DebianBoostraper
         | 
| 425 | 
            +
             | 
| 426 | 
            +
              def default_attributes
         | 
| 427 | 
            +
                super
         | 
| 428 | 
            +
             | 
| 429 | 
            +
                @version = 'intrepid'
         | 
| 430 | 
            +
                @mirror = 'http://archive.ubuntu.com/ubuntu/'
         | 
| 431 | 
            +
              end
         | 
| 432 | 
            +
             | 
| 433 | 
            +
              def options
         | 
| 434 | 
            +
                super.update :components => 'main,universe'
         | 
| 435 | 
            +
              end
         | 
| 436 | 
            +
             | 
| 437 | 
            +
            end
         |