beaker 0.0.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.travis.yml +8 -0
- data/README.md +6 -6
- data/beaker.gemspec +6 -2
- data/lib/beaker.rb +1 -1
- data/lib/beaker/answers.rb +34 -7
- data/lib/beaker/answers/version20.rb +124 -0
- data/lib/beaker/answers/version28.rb +21 -0
- data/lib/beaker/answers/version30.rb +24 -5
- data/lib/beaker/cli.rb +55 -41
- data/lib/beaker/command.rb +2 -2
- data/lib/beaker/dsl/helpers.rb +320 -106
- data/lib/beaker/dsl/install_utils.rb +202 -81
- data/lib/beaker/dsl/roles.rb +40 -0
- data/lib/beaker/host.rb +28 -20
- data/lib/beaker/host/unix.rb +7 -4
- data/lib/beaker/host/unix/pkg.rb +42 -12
- data/lib/beaker/host/windows.rb +9 -5
- data/lib/beaker/host/windows/group.rb +1 -1
- data/lib/beaker/host/windows/pkg.rb +41 -8
- data/lib/beaker/hypervisor.rb +23 -10
- data/lib/beaker/hypervisor/aixer.rb +15 -19
- data/lib/beaker/hypervisor/blimper.rb +71 -72
- data/lib/beaker/hypervisor/fusion.rb +11 -10
- data/lib/beaker/hypervisor/solaris.rb +17 -23
- data/lib/beaker/hypervisor/vagrant.rb +27 -12
- data/lib/beaker/hypervisor/vcloud.rb +154 -138
- data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
- data/lib/beaker/hypervisor/vsphere.rb +8 -5
- data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
- data/lib/beaker/network_manager.rb +16 -12
- data/lib/beaker/options/command_line_parser.rb +199 -0
- data/lib/beaker/options/hosts_file_parser.rb +39 -0
- data/lib/beaker/options/options_file_parser.rb +45 -0
- data/lib/beaker/options/options_hash.rb +294 -0
- data/lib/beaker/options/parser.rb +288 -0
- data/lib/beaker/options/pe_version_scraper.rb +35 -0
- data/lib/beaker/options/presets.rb +70 -0
- data/lib/beaker/shared.rb +2 -1
- data/lib/beaker/shared/host_handler.rb +7 -2
- data/lib/beaker/shared/repetition.rb +1 -0
- data/lib/beaker/shared/timed.rb +14 -0
- data/lib/beaker/test_case.rb +2 -38
- data/lib/beaker/test_suite.rb +11 -25
- data/lib/beaker/utils/repo_control.rb +6 -8
- data/lib/beaker/utils/setup_helper.rb +9 -20
- data/spec/beaker/answers_spec.rb +109 -0
- data/spec/beaker/command_spec.rb +2 -2
- data/spec/beaker/dsl/assertions_spec.rb +1 -3
- data/spec/beaker/dsl/helpers_spec.rb +519 -84
- data/spec/beaker/dsl/install_utils_spec.rb +265 -16
- data/spec/beaker/dsl/roles_spec.rb +31 -10
- data/spec/beaker/host/windows/group_spec.rb +55 -0
- data/spec/beaker/host_spec.rb +130 -40
- data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
- data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
- data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
- data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
- data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
- data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
- data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
- data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
- data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
- data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
- data/spec/beaker/options/command_line_parser_spec.rb +25 -0
- data/spec/beaker/options/data/LATEST +1 -0
- data/spec/beaker/options/data/badyaml.cfg +21 -0
- data/spec/beaker/options/data/hosts.cfg +21 -0
- data/spec/beaker/options/data/opts.txt +6 -0
- data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
- data/spec/beaker/options/options_file_parser_spec.rb +23 -0
- data/spec/beaker/options/options_hash_spec.rb +111 -0
- data/spec/beaker/options/parser_spec.rb +172 -0
- data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
- data/spec/beaker/options/presets_spec.rb +24 -0
- data/spec/beaker/puppet_command_spec.rb +54 -21
- data/spec/beaker/shared/error_handler_spec.rb +40 -0
- data/spec/beaker/shared/host_handler_spec.rb +104 -0
- data/spec/beaker/shared/repetition_spec.rb +72 -0
- data/spec/beaker/test_suite_spec.rb +3 -16
- data/spec/beaker/utils/ntp_control_spec.rb +42 -0
- data/spec/beaker/utils/repo_control_spec.rb +168 -0
- data/spec/beaker/utils/setup_helper_spec.rb +82 -0
- data/spec/beaker/utils/validator_spec.rb +58 -0
- data/spec/helpers.rb +97 -0
- data/spec/matchers.rb +39 -0
- data/spec/mock_blimpy.rb +48 -0
- data/spec/mock_fission.rb +60 -0
- data/spec/mock_vsphere.rb +310 -0
- data/spec/mock_vsphere_helper.rb +183 -0
- data/spec/mocks.rb +83 -0
- data/spec/spec_helper.rb +8 -1
- metadata +106 -13
- data/beaker.rb +0 -10
- data/lib/beaker/options_parsing.rb +0 -323
- data/lib/beaker/test_config.rb +0 -148
- data/spec/beaker/options_parsing_spec.rb +0 -37
- data/spec/mocks_and_helpers.rb +0 -34
data/lib/beaker/host/unix.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'host'))
|
|
2
2
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'command_factory'))
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'command'))
|
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'options'))
|
|
4
5
|
|
|
5
6
|
module Unix
|
|
6
7
|
class Host < Beaker::Host
|
|
@@ -17,7 +18,8 @@ module Unix
|
|
|
17
18
|
include Unix::Pkg
|
|
18
19
|
|
|
19
20
|
def self.pe_defaults
|
|
20
|
-
|
|
21
|
+
h = Beaker::Options::OptionsHash.new
|
|
22
|
+
h.merge({
|
|
21
23
|
'user' => 'root',
|
|
22
24
|
'group' => 'pe-puppet',
|
|
23
25
|
'puppetpath' => '/etc/puppetlabs/puppet',
|
|
@@ -29,11 +31,12 @@ module Unix
|
|
|
29
31
|
'distmoduledir' => '/etc/puppetlabs/puppet/modules',
|
|
30
32
|
'sitemoduledir' => '/opt/puppet/share/puppet/modules',
|
|
31
33
|
'pathseparator' => ':',
|
|
32
|
-
}
|
|
34
|
+
})
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def self.foss_defaults
|
|
36
|
-
|
|
38
|
+
h = Beaker::Options::OptionsHash.new
|
|
39
|
+
h.merge({
|
|
37
40
|
'user' => 'root',
|
|
38
41
|
'group' => 'puppet',
|
|
39
42
|
'puppetpath' => '/etc/puppet',
|
|
@@ -48,7 +51,7 @@ module Unix
|
|
|
48
51
|
'distmoduledir' => '/etc/puppet/modules',
|
|
49
52
|
'sitemoduledir' => '/usr/share/puppet/modules',
|
|
50
53
|
'pathseparator' => ':',
|
|
51
|
-
}
|
|
54
|
+
})
|
|
52
55
|
end
|
|
53
56
|
end
|
|
54
57
|
end
|
data/lib/beaker/host/unix/pkg.rb
CHANGED
|
@@ -1,22 +1,52 @@
|
|
|
1
1
|
module Unix::Pkg
|
|
2
2
|
include Beaker::CommandFactory
|
|
3
3
|
|
|
4
|
-
def check_for_package
|
|
4
|
+
def check_for_package(name)
|
|
5
5
|
result = exec(Beaker::Command.new("which #{name}"), :acceptable_exit_codes => (0...127))
|
|
6
|
-
|
|
6
|
+
case self['platform']
|
|
7
|
+
when /solaris-10/
|
|
8
|
+
result.stdout =~ %r|/.*/#{name}|
|
|
9
|
+
else
|
|
10
|
+
result.exit_code == 0
|
|
11
|
+
end
|
|
7
12
|
end
|
|
8
13
|
|
|
9
|
-
def install_package
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
def install_package(name, cmdline_args = '')
|
|
15
|
+
case self['platform']
|
|
16
|
+
when /sles-/
|
|
17
|
+
execute("zypper --non-interactive in #{name}")
|
|
18
|
+
when /el-4/
|
|
19
|
+
@logger.debug("Package installation not supported on rhel4")
|
|
20
|
+
when /fedora|centos|el-/
|
|
21
|
+
execute("yum -y #{cmdline_args} install #{name}")
|
|
22
|
+
when /ubuntu|debian/
|
|
23
|
+
execute("apt-get update")
|
|
24
|
+
execute("apt-get install #{cmdline_args} -y #{name}")
|
|
25
|
+
when /solaris-11/
|
|
26
|
+
execute("pkg #{cmdline_args} install #{name}")
|
|
27
|
+
when /solaris-10/
|
|
28
|
+
execute("pkgutil -i -y #{cmdline_args} #{name}")
|
|
29
|
+
else
|
|
30
|
+
raise "Package #{name} cannot be installed on #{self}"
|
|
19
31
|
end
|
|
20
32
|
end
|
|
21
33
|
|
|
34
|
+
def uninstall_package(name, cmdline_args = '')
|
|
35
|
+
case self['platform']
|
|
36
|
+
when /sles-/
|
|
37
|
+
execute("zypper --non-interactive rm #{name}")
|
|
38
|
+
when /el-4/
|
|
39
|
+
@logger.debug("Package uninstallation not supported on rhel4")
|
|
40
|
+
when /fedora|centos|el-/
|
|
41
|
+
execute("yum -y #{cmdline_args} remove #{name}")
|
|
42
|
+
when /ubuntu|debian/
|
|
43
|
+
execute("apt-get purge #{cmdline_args} -y #{name}")
|
|
44
|
+
when /solaris-11/
|
|
45
|
+
execute("pkg #{cmdline_args} uninstall #{name}")
|
|
46
|
+
when /solaris-10/
|
|
47
|
+
execute("pkgutil -r -y #{cmdline_args} #{name}")
|
|
48
|
+
else
|
|
49
|
+
raise "Package #{name} cannot be installed on #{self}"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
22
52
|
end
|
data/lib/beaker/host/windows.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'host'))
|
|
2
2
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'command_factory'))
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'command'))
|
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'options'))
|
|
4
5
|
|
|
5
6
|
module Windows
|
|
6
7
|
class Host < Beaker::Host
|
|
@@ -17,18 +18,21 @@ module Windows
|
|
|
17
18
|
include Windows::Pkg
|
|
18
19
|
|
|
19
20
|
def self.pe_defaults
|
|
20
|
-
|
|
21
|
+
h = Beaker::Options::OptionsHash.new
|
|
22
|
+
h.merge({
|
|
21
23
|
'user' => 'Administrator',
|
|
22
24
|
'group' => 'Administrators',
|
|
23
25
|
'puppetpath' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
|
|
24
26
|
'puppetvardir' => '`cygpath -smF 35`/PuppetLabs/puppet/var',
|
|
25
|
-
|
|
27
|
+
#if an x86 Program Files dir exists then use it, default to just Program Files
|
|
28
|
+
'puppetbindir' => '$( [ -d "/cygdrive/c/Program Files (x86)" ] && echo "/cygdrive/c/Program Files (x86)" || echo "/cygdrive/c/Program Files" )/Puppet Labs/Puppet Enterprise/bin',
|
|
26
29
|
'pathseparator' => ';',
|
|
27
|
-
}
|
|
30
|
+
})
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
def self.foss_defaults
|
|
31
|
-
|
|
34
|
+
h = Beaker::Options::OptionsHash.new
|
|
35
|
+
h.merge({
|
|
32
36
|
'user' => 'Administrator',
|
|
33
37
|
'group' => 'Administrators',
|
|
34
38
|
'puppetpath' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
|
|
@@ -38,7 +42,7 @@ module Windows
|
|
|
38
42
|
# PATH related variables need to be Unix, which cygwin converts
|
|
39
43
|
'hierabindir' => '/opt/puppet-git-repos/hiera/bin',
|
|
40
44
|
'pathseparator' => ';',
|
|
41
|
-
}
|
|
45
|
+
})
|
|
42
46
|
end
|
|
43
47
|
end
|
|
44
48
|
end
|
|
@@ -5,7 +5,7 @@ module Windows::Group
|
|
|
5
5
|
execute('cmd /c echo "" | wmic group where localaccount="true" get name /format:value') do |result|
|
|
6
6
|
groups = []
|
|
7
7
|
result.stdout.each_line do |line|
|
|
8
|
-
groups << (line.match(/^Name=(
|
|
8
|
+
groups << (line.match(/^Name=(.+)$/) or next)[1]
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
yield result if block_given?
|
|
@@ -1,26 +1,59 @@
|
|
|
1
1
|
module Windows::Pkg
|
|
2
2
|
include Beaker::CommandFactory
|
|
3
3
|
|
|
4
|
-
def check_for_package
|
|
4
|
+
def check_for_package(name)
|
|
5
5
|
result = exec(Beaker::Command.new("which #{name}"), :acceptable_exit_codes => (0...127))
|
|
6
6
|
result.exit_code == 0
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def install_package
|
|
9
|
+
def install_package(name, cmdline_args = '')
|
|
10
10
|
cygwin = ""
|
|
11
11
|
rootdir = ""
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
else #64 bit version
|
|
12
|
+
|
|
13
|
+
arch = identify_windows_architecture
|
|
14
|
+
|
|
15
|
+
if arch == '64'
|
|
17
16
|
rootdir = "c:\\\\cygwin64"
|
|
18
17
|
cygwin = "setup-x86_64.exe"
|
|
18
|
+
else #32 bit version
|
|
19
|
+
rootdir = "c:\\\\cygwin"
|
|
20
|
+
cygwin = "setup-x86.exe"
|
|
19
21
|
end
|
|
22
|
+
|
|
20
23
|
if not check_for_package(cygwin)
|
|
21
24
|
execute("curl --retry 5 http://cygwin.com/#{cygwin} -o /cygdrive/c/Windows/System32/#{cygwin}")
|
|
22
25
|
end
|
|
23
|
-
execute("#{cygwin} -q -n -N -d -R #{rootdir} -s http://cygwin.osuosl.org -P #{name}")
|
|
26
|
+
execute("#{cygwin} -q -n -N -d -R #{cmdline_args} #{rootdir} -s http://cygwin.osuosl.org -P #{name}")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def uninstall_package(name, cmdline_args = '')
|
|
30
|
+
raise "Package #{name} cannot be uninstalled on #{self}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
# @api private
|
|
36
|
+
def identify_windows_architecture
|
|
37
|
+
arch = nil
|
|
38
|
+
execute("echo '' | wmic os get osarchitecture",
|
|
39
|
+
:acceptable_exit_codes => (0...127)) do |result|
|
|
40
|
+
|
|
41
|
+
arch = if result.exit_code == 0
|
|
42
|
+
result.stdout =~ /64/ ? '64' : '32'
|
|
43
|
+
else
|
|
44
|
+
identify_windows_architecture_from_os_name_for_win2003
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
arch
|
|
24
48
|
end
|
|
25
49
|
|
|
50
|
+
# @api private
|
|
51
|
+
def identify_windows_architecture_from_os_name_for_win2003
|
|
52
|
+
arch = nil
|
|
53
|
+
execute("echo '' | wmic os get name | grep x64",
|
|
54
|
+
:acceptable_exit_codes => (0...127)) do |result|
|
|
55
|
+
arch = result.exit_code == 0 ? '64' : '32'
|
|
56
|
+
end
|
|
57
|
+
arch
|
|
58
|
+
end
|
|
26
59
|
end
|
data/lib/beaker/hypervisor.rb
CHANGED
|
@@ -5,30 +5,43 @@ module Beaker
|
|
|
5
5
|
@logger.debug "No post-provisioning configuration necessary for #{self.class.name} boxes"
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def self.create
|
|
8
|
+
def self.create(type, hosts_to_provision, options)
|
|
9
9
|
@logger = options[:logger]
|
|
10
10
|
@logger.notify("Beaker::Hypervisor, found some #{type} boxes to create")
|
|
11
|
-
case type
|
|
11
|
+
hyper_class = case type
|
|
12
12
|
when /aix/
|
|
13
|
-
Beaker::Aixer
|
|
13
|
+
Beaker::Aixer
|
|
14
14
|
when /solaris/
|
|
15
|
-
Beaker::Solaris
|
|
15
|
+
Beaker::Solaris
|
|
16
16
|
when /vsphere/
|
|
17
|
-
Beaker::Vsphere
|
|
17
|
+
Beaker::Vsphere
|
|
18
18
|
when /fusion/
|
|
19
|
-
Beaker::Fusion
|
|
19
|
+
Beaker::Fusion
|
|
20
20
|
when /blimpy/
|
|
21
|
-
Beaker::Blimper
|
|
21
|
+
Beaker::Blimper
|
|
22
22
|
when /vcloud/
|
|
23
|
-
|
|
23
|
+
if options['pooling_api']
|
|
24
|
+
Beaker::VcloudPooled
|
|
25
|
+
else
|
|
26
|
+
Beaker::Vcloud
|
|
27
|
+
end
|
|
24
28
|
when /vagrant/
|
|
25
|
-
Beaker::Vagrant
|
|
29
|
+
Beaker::Vagrant
|
|
26
30
|
end
|
|
31
|
+
hypervisor = hyper_class.new(hosts_to_provision, options)
|
|
32
|
+
hypervisor.provision
|
|
33
|
+
|
|
34
|
+
hypervisor
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def provision
|
|
38
|
+
nil
|
|
27
39
|
end
|
|
40
|
+
|
|
28
41
|
end
|
|
29
42
|
end
|
|
30
43
|
|
|
31
|
-
%w( vsphere_helper vagrant fusion blimper vsphere vcloud aixer solaris).each do |lib|
|
|
44
|
+
%w( vsphere_helper vagrant fusion blimper vsphere vcloud vcloud_pooled aixer solaris).each do |lib|
|
|
32
45
|
begin
|
|
33
46
|
require "hypervisor/#{lib}"
|
|
34
47
|
rescue LoadError
|
|
@@ -1,35 +1,31 @@
|
|
|
1
|
-
module Beaker
|
|
1
|
+
module Beaker
|
|
2
2
|
class Aixer < Beaker::Hypervisor
|
|
3
3
|
|
|
4
|
-
def initialize(aix_hosts, options
|
|
4
|
+
def initialize(aix_hosts, options)
|
|
5
5
|
@options = options
|
|
6
|
-
@config = config['CONFIG'].dup
|
|
7
6
|
@logger = options[:logger]
|
|
8
7
|
@aix_hosts = aix_hosts
|
|
9
8
|
#aix machines are reverted to known state, not a snapshot
|
|
10
|
-
fog_file = nil
|
|
11
|
-
if File.exists?(
|
|
12
|
-
fog_file = YAML.load_file(
|
|
9
|
+
@fog_file = nil
|
|
10
|
+
if File.exists?( @options[:dot_fog] )
|
|
11
|
+
@fog_file = YAML.load_file( @options[:dot_fog] )
|
|
13
12
|
end
|
|
14
|
-
raise "Cant load
|
|
13
|
+
raise "Cant load #{@options[:dot_fog]} config" unless @fog_file
|
|
15
14
|
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def provision
|
|
16
18
|
# Running the rake task on rpm-builder
|
|
17
|
-
hypername = fog_file[:default][:aix_hypervisor_server]
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
hypername = @fog_file[:default][:aix_hypervisor_server]
|
|
20
|
+
hyperopts = @options.dup
|
|
21
|
+
hyperopts['HOSTS'] = {
|
|
20
22
|
hypername => { 'platform' => 'el-6-x86_64' }
|
|
21
|
-
},
|
|
22
|
-
'CONFIG' => {
|
|
23
|
-
'user' => fog_file[:default][:aix_hypervisor_username] || ENV['USER'],
|
|
24
|
-
'ssh' => {
|
|
25
|
-
:keys => fog_file[:default][:aix_hypervisor_keyfile] || "#{ENV['HOME']}/.ssh/id_rsa"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
23
|
}
|
|
29
|
-
hyperconfig = Beaker::TestConfig.new( hyperconf, @options )
|
|
30
24
|
|
|
31
25
|
@logger.notify "Connecting to hypervisor at #{hypername}"
|
|
32
|
-
hypervisor = Beaker::Host.create( hypername,
|
|
26
|
+
hypervisor = Beaker::Host.create( hypername, hyperopts )
|
|
27
|
+
hypervisor[:user] = @fog_file[:default][:aix_hypervisor_username] || hypervisor[:user]
|
|
28
|
+
hypervisor[:ssh][:keys] = [@fog_file[:default][:aix_hypervisor_keyfile]] || hypervisor[:ssh][:keys]
|
|
33
29
|
|
|
34
30
|
@aix_hosts.each do |host|
|
|
35
31
|
vm_name = host['vmname'] || host.name
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require 'blimpy'
|
|
2
|
+
require 'yaml' unless defined?(YAML)
|
|
3
|
+
|
|
1
4
|
module Beaker
|
|
2
5
|
class Blimper < Beaker::Hypervisor
|
|
3
6
|
|
|
@@ -21,93 +24,89 @@ module Beaker
|
|
|
21
24
|
ports
|
|
22
25
|
end
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
require 'rubygems' unless defined?(Gem)
|
|
30
|
-
require 'yaml' unless defined?(YAML)
|
|
31
|
-
begin
|
|
32
|
-
require 'blimpy'
|
|
33
|
-
rescue LoadError
|
|
34
|
-
raise "Unable to load Blimpy, please ensure its installed"
|
|
27
|
+
def initialize(blimpy_hosts, options)
|
|
28
|
+
@options = options
|
|
29
|
+
@logger = options[:logger]
|
|
30
|
+
@blimpy_hosts = blimpy_hosts
|
|
31
|
+
@blimpy = Blimpy
|
|
35
32
|
end
|
|
36
|
-
ami_spec= YAML.load_file('config/image_templates/ec2.yaml')["AMI"]
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
@
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
34
|
+
def provision
|
|
35
|
+
ami_spec= YAML.load_file(@options[:ec2_yaml])["AMI"]
|
|
36
|
+
|
|
37
|
+
fleet = @blimpy.fleet do |fleet|
|
|
38
|
+
@blimpy_hosts.each do |host|
|
|
39
|
+
amitype = host['vmname'] || host['platform']
|
|
40
|
+
amisize = host['amisize'] || 'm1.small'
|
|
41
|
+
#use snapshot provided for this host
|
|
42
|
+
image_type = host['snapshot']
|
|
43
|
+
if not image_type
|
|
44
|
+
raise "No snapshot/image_type provided for blimpy provisioning"
|
|
45
|
+
end
|
|
46
|
+
ami = ami_spec[amitype]
|
|
47
|
+
fleet.add(:aws) do |ship|
|
|
48
|
+
ship.name = host.name
|
|
49
|
+
ship.ports = amiports(host)
|
|
50
|
+
ship.image_id = ami[:image][image_type.to_sym]
|
|
51
|
+
if not ship.image_id
|
|
52
|
+
raise "No image_id found for host #{ship.name} (#{amitype}:#{amisize}) using snapshot/image_type #{image_type}"
|
|
53
|
+
end
|
|
54
|
+
ship.flavor = amisize
|
|
55
|
+
ship.region = ami[:region]
|
|
56
|
+
ship.username = 'root'
|
|
54
57
|
end
|
|
55
|
-
|
|
56
|
-
ship.region = ami[:region]
|
|
57
|
-
ship.username = 'root'
|
|
58
|
+
@logger.debug "Added #{host.name} (#{amitype}:#{amisize}) using snapshot/image_type #{image_type} to blimpy fleet"
|
|
58
59
|
end
|
|
59
|
-
@logger.debug "Added #{host.name} (#{amitype}:#{amisize}) using snapshot/image_type #{image_type} to blimpy fleet"
|
|
60
60
|
end
|
|
61
|
-
end
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
ex.message}), retry attempt #{fleet_retries}.")
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
62
|
+
# Attempt to start the fleet, we wrap it with some error handling that deals
|
|
63
|
+
# with generic Fog errors and retrying in case these errors are transient.
|
|
64
|
+
fleet_retries = 0
|
|
65
|
+
begin
|
|
66
|
+
fleet.start
|
|
67
|
+
rescue Fog::Errors::Error => ex
|
|
68
|
+
fleet_retries += 1
|
|
69
|
+
if fleet_retries <= 3
|
|
70
|
+
sleep_time = rand(10) + 10
|
|
71
|
+
@logger.notify("Calling fleet.destroy, sleeping #{sleep_time} seconds and retrying fleet.start due to Fog::Errors::Error (#{
|
|
72
|
+
ex.message}), retry attempt #{fleet_retries}.")
|
|
73
|
+
begin
|
|
74
|
+
timeout(30) do
|
|
75
|
+
fleet.destroy
|
|
76
|
+
end
|
|
77
|
+
rescue
|
|
77
78
|
end
|
|
78
|
-
|
|
79
|
+
sleep sleep_time
|
|
80
|
+
retry
|
|
81
|
+
else
|
|
82
|
+
@logger.error("Retried Fog #{fleet_retries} times, giving up and throwing the exception")
|
|
83
|
+
raise ex
|
|
79
84
|
end
|
|
80
|
-
sleep sleep_time
|
|
81
|
-
retry
|
|
82
|
-
else
|
|
83
|
-
@logger.error("Retried Fog #{fleet_retries} times, giving up and throwing the exception")
|
|
84
|
-
raise ex
|
|
85
85
|
end
|
|
86
|
-
end
|
|
87
86
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
87
|
+
# Configure our nodes to match the blimp fleet
|
|
88
|
+
# Also generate hosts entries for the fleet, since we're iterating
|
|
89
|
+
etc_hosts = "127.0.0.1\tlocalhost localhost.localdomain\n"
|
|
90
|
+
fleet.ships.each do |ship|
|
|
91
|
+
ship.wait_for_sshd
|
|
92
|
+
name = ship.name
|
|
93
|
+
host = @blimpy_hosts.select { |host| host.name == name }[0]
|
|
94
|
+
host['ip'] = ship.dns
|
|
95
|
+
host.exec(Command.new("hostname #{name}"))
|
|
96
|
+
ip = get_ip(host)
|
|
97
|
+
domain = get_domain_name(host)
|
|
98
|
+
etc_hosts += "#{ip}\t#{name}\t#{name}.#{domain}\n"
|
|
99
|
+
end
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
# Send our hosts information to the nodes
|
|
102
|
+
@blimpy_hosts.each do |host|
|
|
103
|
+
set_etc_hosts(host, etc_hosts)
|
|
104
|
+
end
|
|
106
105
|
|
|
107
106
|
end #revert_blimpy
|
|
108
107
|
|
|
109
108
|
def cleanup
|
|
110
|
-
fleet =
|
|
109
|
+
fleet = @blimpy.fleet do |fleet|
|
|
111
110
|
@blimpy_hosts.each do |host|
|
|
112
111
|
fleet.add(:aws) do |ship|
|
|
113
112
|
ship.name = host.name
|