beaker-hostgenerator 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +4 -0
- data/HISTORY.md +233 -2
- data/README.md +50 -11
- data/beaker-hostgenerator.gemspec +2 -2
- data/lib/beaker-hostgenerator.rb +0 -1
- data/lib/beaker-hostgenerator/cli.rb +38 -26
- data/lib/beaker-hostgenerator/data.rb +960 -35
- data/lib/beaker-hostgenerator/generator.rb +57 -97
- data/lib/beaker-hostgenerator/hypervisor.rb +97 -0
- data/lib/beaker-hostgenerator/hypervisor/none.rb +17 -0
- data/lib/beaker-hostgenerator/hypervisor/vmpooler.rb +32 -0
- data/lib/beaker-hostgenerator/parser.rb +199 -0
- data/lib/beaker-hostgenerator/roles.rb +21 -14
- data/lib/beaker-hostgenerator/util.rb +10 -29
- data/lib/beaker-hostgenerator/version.rb +1 -1
- data/spec/beaker-hostgenerator/generator_spec.rb +73 -109
- data/spec/beaker-hostgenerator/parser_spec.rb +84 -0
- data/test/fixtures/default/cisconx-64a +1 -1
- data/test/fixtures/default/windows10ent-32d +22 -0
- data/test/fixtures/default/windows10ent-64f +22 -0
- data/test/fixtures/default/windows10pro-64m +22 -0
- data/test/fixtures/default/windows2003-6432d +22 -0
- data/test/fixtures/default/windows2003-64c +22 -0
- data/test/fixtures/default/windows2003r2-32f +22 -0
- data/test/fixtures/default/windows2003r2-6432aulcdfm +27 -0
- data/test/fixtures/default/windows2003r2-64m +22 -0
- data/test/fixtures/default/windows2008-6432u +22 -0
- data/test/fixtures/default/windows2008-64a +21 -0
- data/test/fixtures/default/windows2008r2-6432c +22 -0
- data/test/fixtures/default/windows2008r2-64l +22 -0
- data/test/fixtures/default/windows2012-6432f +22 -0
- data/test/fixtures/default/windows2012-64d +22 -0
- data/test/fixtures/default/windows2012r2-6432aulcdfm +27 -0
- data/test/fixtures/default/windows2012r2-64m +22 -0
- data/test/fixtures/default/windows7-64a +21 -0
- data/test/fixtures/default/windows8-64u +22 -0
- data/test/fixtures/default/windows81-64l +22 -0
- data/test/fixtures/default/windowsvista-64c +22 -0
- data/test/fixtures/multiplatform/arista4-32a-windows10pro-64-arista4-32aulcdfm +47 -0
- data/test/fixtures/multiplatform/centos4-32u-windows10ent-64-centos4-32m +43 -0
- data/test/fixtures/multiplatform/centos4-64l-windows10ent-32-centos4-64f +43 -0
- data/test/fixtures/multiplatform/centos5-32c-windowsvista-64-centos5-32d +43 -0
- data/test/fixtures/multiplatform/centos5-64d-windows81-64-centos5-64c +43 -0
- data/test/fixtures/multiplatform/centos6-32f-windows8-64-centos6-32l +43 -0
- data/test/fixtures/multiplatform/centos6-64m-windows7-64-centos6-64u +43 -0
- data/test/fixtures/multiplatform/centos7-64aulcdfm-windows2012r2-6432-centos7-64a +47 -0
- data/test/fixtures/multiplatform/cisconx-64a-windows2012r2-64-cisconx-64aulcdfm +53 -0
- data/test/fixtures/multiplatform/ciscoxr-64u-windows2012-6432-ciscoxr-64m +43 -0
- data/test/fixtures/multiplatform/cumulus25-64l-windows2012-64-cumulus25-64f +43 -0
- data/test/fixtures/multiplatform/debian6-32c-windows2008r2-6432-debian6-32d +43 -0
- data/test/fixtures/multiplatform/debian6-64d-windows2008r2-64-debian6-64c +43 -0
- data/test/fixtures/multiplatform/debian7-32f-windows2008-6432-debian7-32l +43 -0
- data/test/fixtures/multiplatform/debian7-64m-windows2008-64-debian7-64u +43 -0
- data/test/fixtures/multiplatform/debian8-32aulcdfm-windows2003r2-6432-debian8-32a +47 -0
- data/test/fixtures/multiplatform/debian8-64a-windows2003r2-64-debian8-64aulcdfm +47 -0
- data/test/fixtures/multiplatform/debian9-32u-windows2003r2-32-debian9-32m +43 -0
- data/test/fixtures/multiplatform/debian9-64l-windows2003-6432-debian9-64f +43 -0
- data/test/fixtures/multiplatform/fedora14-32l-solaris11-64-fedora14-32f +42 -0
- data/test/fixtures/multiplatform/fedora19-32c-solaris11-32-fedora19-32d +42 -0
- data/test/fixtures/multiplatform/fedora19-64d-solaris10-64-fedora19-64c +42 -0
- data/test/fixtures/multiplatform/fedora20-32f-solaris10-32-fedora20-32l +42 -0
- data/test/fixtures/multiplatform/fedora20-64m-sles12-64-fedora20-64u +42 -0
- data/test/fixtures/multiplatform/fedora21-32aulcdfm-sles11-64-fedora21-32a +46 -0
- data/test/fixtures/multiplatform/fedora21-64a-sles11-32-fedora21-64aulcdfm +46 -0
- data/test/fixtures/multiplatform/fedora22-32u-sles10-64-fedora22-32m +42 -0
- data/test/fixtures/multiplatform/fedora22-64l-sles10-32-fedora22-64f +42 -0
- data/test/fixtures/multiplatform/fedora23-32c-scientific7-64-fedora23-32d +42 -0
- data/test/fixtures/multiplatform/fedora23-64d-scientific6-64-fedora23-64c +42 -0
- data/test/fixtures/multiplatform/opensuse11-32f-scientific6-32-opensuse11-32l +42 -0
- data/test/fixtures/multiplatform/opensuse11-64m-scientific5-64-opensuse11-64u +42 -0
- data/test/fixtures/multiplatform/oracle5-32c-windows2003-64-oracle5-32d +43 -0
- data/test/fixtures/multiplatform/oracle5-64d-ubuntu1604-64-oracle5-64c +42 -0
- data/test/fixtures/multiplatform/oracle6-32f-ubuntu1604-32-oracle6-32l +42 -0
- data/test/fixtures/multiplatform/oracle6-64m-ubuntu1510-64-oracle6-64u +42 -0
- data/test/fixtures/multiplatform/oracle7-64aulcdfm-ubuntu1510-32-oracle7-64a +46 -0
- data/test/fixtures/multiplatform/osx1010-64u-ubuntu1504-32-osx1010-64m +42 -0
- data/test/fixtures/multiplatform/osx1011-64l-ubuntu1404-64-osx1011-64f +42 -0
- data/test/fixtures/multiplatform/osx109-64a-ubuntu1504-64-osx109-64aulcdfm +46 -0
- data/test/fixtures/multiplatform/redhat4-32c-ubuntu1404-32-redhat4-32d +42 -0
- data/test/fixtures/multiplatform/redhat4-64d-ubuntu1204-64-redhat4-64c +42 -0
- data/test/fixtures/multiplatform/redhat5-32f-ubuntu1204-32-redhat5-32l +42 -0
- data/test/fixtures/multiplatform/redhat5-64m-ubuntu1004-64-redhat5-64u +42 -0
- data/test/fixtures/multiplatform/redhat6-32aulcdfm-ubuntu1004-32-redhat6-32a +46 -0
- data/test/fixtures/multiplatform/redhat6-64a-solaris112-64-redhat6-64aulcdfm +46 -0
- data/test/fixtures/multiplatform/redhat7-64u-solaris112-32-redhat7-64m +42 -0
- data/test/fixtures/multiplatform/scientific5-32aulcdfm-scientific5-32-scientific5-32a +46 -0
- data/test/fixtures/multiplatform/scientific5-64a-opensuse11-64-scientific5-64aulcdfm +46 -0
- data/test/fixtures/multiplatform/scientific6-32u-opensuse11-32-scientific6-32m +42 -0
- data/test/fixtures/multiplatform/scientific6-64l-fedora23-64-scientific6-64f +42 -0
- data/test/fixtures/multiplatform/scientific7-64c-fedora23-32-scientific7-64d +42 -0
- data/test/fixtures/multiplatform/sles10-32d-fedora22-64-sles10-32c +42 -0
- data/test/fixtures/multiplatform/sles10-64f-fedora22-32-sles10-64l +42 -0
- data/test/fixtures/multiplatform/sles11-32m-fedora21-64-sles11-32u +42 -0
- data/test/fixtures/multiplatform/sles11-64aulcdfm-fedora21-32-sles11-64a +46 -0
- data/test/fixtures/multiplatform/sles12-64a-fedora20-64-sles12-64aulcdfm +46 -0
- data/test/fixtures/multiplatform/solaris10-32u-fedora20-32-solaris10-32m +42 -0
- data/test/fixtures/multiplatform/solaris10-64l-fedora19-64-solaris10-64f +42 -0
- data/test/fixtures/multiplatform/solaris11-32c-fedora19-32-solaris11-32d +42 -0
- data/test/fixtures/multiplatform/solaris11-64d-fedora14-32-solaris11-64c +42 -0
- data/test/fixtures/multiplatform/solaris112-32f-redhat7-64-solaris112-32l +42 -0
- data/test/fixtures/multiplatform/solaris112-64m-redhat6-64-solaris112-64u +42 -0
- data/test/fixtures/multiplatform/ubuntu1004-32aulcdfm-redhat6-32-ubuntu1004-32a +46 -0
- data/test/fixtures/multiplatform/ubuntu1004-64a-redhat5-64-ubuntu1004-64aulcdfm +46 -0
- data/test/fixtures/multiplatform/ubuntu1204-32u-redhat5-32-ubuntu1204-32m +42 -0
- data/test/fixtures/multiplatform/ubuntu1204-64l-redhat4-64-ubuntu1204-64f +42 -0
- data/test/fixtures/multiplatform/ubuntu1404-32c-redhat4-32-ubuntu1404-32d +42 -0
- data/test/fixtures/multiplatform/ubuntu1404-64d-osx1011-64-ubuntu1404-64c +42 -0
- data/test/fixtures/multiplatform/ubuntu1504-32f-osx1010-64-ubuntu1504-32l +42 -0
- data/test/fixtures/multiplatform/ubuntu1504-64m-osx109-64-ubuntu1504-64u +42 -0
- data/test/fixtures/multiplatform/ubuntu1510-32aulcdfm-oracle7-64-ubuntu1510-32a +46 -0
- data/test/fixtures/multiplatform/ubuntu1510-64a-oracle6-64-ubuntu1510-64aulcdfm +46 -0
- data/test/fixtures/multiplatform/ubuntu1604-32u-oracle6-32-ubuntu1604-32m +42 -0
- data/test/fixtures/multiplatform/ubuntu1604-64l-oracle5-64-ubuntu1604-64f +42 -0
- data/test/fixtures/multiplatform/windows10ent-32d-centos4-64-windows10ent-32c +44 -0
- data/test/fixtures/multiplatform/windows10ent-64f-centos4-32-windows10ent-64l +44 -0
- data/test/fixtures/multiplatform/windows10pro-64m-arista4-32-windows10pro-64u +44 -0
- data/test/fixtures/multiplatform/windows2003-6432d-debian9-64-windows2003-6432c +44 -0
- data/test/fixtures/multiplatform/windows2003-64c-oracle5-32-windows2003-64d +44 -0
- data/test/fixtures/multiplatform/windows2003r2-32f-debian9-32-windows2003r2-32l +44 -0
- data/test/fixtures/multiplatform/windows2003r2-6432aulcdfm-debian8-32-windows2003r2-6432a +48 -0
- data/test/fixtures/multiplatform/windows2003r2-64m-debian8-64-windows2003r2-64u +44 -0
- data/test/fixtures/multiplatform/windows2008-6432u-debian7-32-windows2008-6432m +44 -0
- data/test/fixtures/multiplatform/windows2008-64a-debian7-64-windows2008-64aulcdfm +48 -0
- data/test/fixtures/multiplatform/windows2008r2-6432c-debian6-32-windows2008r2-6432d +44 -0
- data/test/fixtures/multiplatform/windows2008r2-64l-debian6-64-windows2008r2-64f +44 -0
- data/test/fixtures/multiplatform/windows2012-6432f-ciscoxr-64-windows2012-6432l +44 -0
- data/test/fixtures/multiplatform/windows2012-64d-cumulus25-64-windows2012-64c +44 -0
- data/test/fixtures/multiplatform/windows2012r2-6432aulcdfm-centos7-64-windows2012r2-6432a +48 -0
- data/test/fixtures/multiplatform/windows2012r2-64m-cisconx-64-windows2012r2-64u +47 -0
- data/test/fixtures/multiplatform/windows7-64a-centos6-64-windows7-64aulcdfm +48 -0
- data/test/fixtures/multiplatform/windows8-64u-centos6-32-windows8-64m +44 -0
- data/test/fixtures/multiplatform/windows81-64l-centos5-64-windows81-64f +44 -0
- data/test/fixtures/multiplatform/windowsvista-64c-centos5-32-windowsvista-64d +44 -0
- data/test/fixtures/osinfo-version-0/cisconx-64a +1 -1
- data/test/fixtures/osinfo-version-0/windows10ent-32d +22 -0
- data/test/fixtures/osinfo-version-0/windows10ent-64f +22 -0
- data/test/fixtures/osinfo-version-0/windows10pro-64m +22 -0
- data/test/fixtures/osinfo-version-0/windows2003-6432d +22 -0
- data/test/fixtures/osinfo-version-0/windows2003-64c +22 -0
- data/test/fixtures/osinfo-version-0/windows2003r2-32f +22 -0
- data/test/fixtures/osinfo-version-0/windows2003r2-6432aulcdfm +27 -0
- data/test/fixtures/osinfo-version-0/windows2003r2-64m +22 -0
- data/test/fixtures/osinfo-version-0/windows2008-6432u +22 -0
- data/test/fixtures/osinfo-version-0/windows2008-64a +21 -0
- data/test/fixtures/osinfo-version-0/windows2008r2-6432c +22 -0
- data/test/fixtures/osinfo-version-0/windows2008r2-64l +22 -0
- data/test/fixtures/osinfo-version-0/windows2012-6432f +22 -0
- data/test/fixtures/osinfo-version-0/windows2012-64d +22 -0
- data/test/fixtures/osinfo-version-0/windows2012r2-6432aulcdfm +27 -0
- data/test/fixtures/osinfo-version-0/windows2012r2-64m +22 -0
- data/test/fixtures/osinfo-version-0/windows7-64a +21 -0
- data/test/fixtures/osinfo-version-0/windows8-64u +22 -0
- data/test/fixtures/osinfo-version-0/windows81-64l +22 -0
- data/test/fixtures/osinfo-version-0/windowsvista-64c +22 -0
- data/test/fixtures/osinfo-version-1/cisconx-64a +1 -1
- data/test/fixtures/osinfo-version-1/windows10ent-32d +22 -0
- data/test/fixtures/osinfo-version-1/windows10ent-64f +22 -0
- data/test/fixtures/osinfo-version-1/windows10pro-64m +22 -0
- data/test/fixtures/osinfo-version-1/windows2003-6432d +22 -0
- data/test/fixtures/osinfo-version-1/windows2003-64c +22 -0
- data/test/fixtures/osinfo-version-1/windows2003r2-32f +22 -0
- data/test/fixtures/osinfo-version-1/windows2003r2-6432aulcdfm +27 -0
- data/test/fixtures/osinfo-version-1/windows2003r2-64m +22 -0
- data/test/fixtures/osinfo-version-1/windows2008-6432u +22 -0
- data/test/fixtures/osinfo-version-1/windows2008-64a +21 -0
- data/test/fixtures/osinfo-version-1/windows2008r2-6432c +22 -0
- data/test/fixtures/osinfo-version-1/windows2008r2-64l +22 -0
- data/test/fixtures/osinfo-version-1/windows2012-6432f +22 -0
- data/test/fixtures/osinfo-version-1/windows2012-64d +22 -0
- data/test/fixtures/osinfo-version-1/windows2012r2-6432aulcdfm +27 -0
- data/test/fixtures/osinfo-version-1/windows2012r2-64m +22 -0
- data/test/fixtures/osinfo-version-1/windows7-64a +21 -0
- data/test/fixtures/osinfo-version-1/windows8-64u +22 -0
- data/test/fixtures/osinfo-version-1/windows81-64l +22 -0
- data/test/fixtures/osinfo-version-1/windowsvista-64c +22 -0
- data/test/fixtures/per-host-settings/arbitrary-settings.yaml +57 -0
- data/test/fixtures/per-host-settings/every-hypervisor.yaml +30 -0
- data/test/fixtures/per-host-settings/malformed-input.yaml +5 -0
- data/test/test_stdout.rb +2 -2
- data/test/util/generator_helpers.rb +12 -4
- metadata +167 -6
- data/lib/beaker-hostgenerator/data/vmpooler.rb +0 -467
- data/lib/beaker-hostgenerator/generator/vmpooler.rb +0 -59
- data/test/test_util.rb +0 -26
@@ -1,43 +1,35 @@
|
|
1
|
-
require 'beaker-hostgenerator/util'
|
2
1
|
require 'beaker-hostgenerator/data'
|
3
|
-
require 'beaker-hostgenerator/exceptions'
|
4
2
|
require 'beaker-hostgenerator/roles'
|
3
|
+
require 'beaker-hostgenerator/hypervisor'
|
4
|
+
require 'beaker-hostgenerator/parser'
|
5
5
|
|
6
6
|
require 'yaml'
|
7
7
|
|
8
8
|
module BeakerHostGenerator
|
9
9
|
class Generator
|
10
10
|
include BeakerHostGenerator::Data
|
11
|
-
include BeakerHostGenerator::
|
12
|
-
include BeakerHostGenerator::
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
BeakerHostGenerator::Vagrant
|
28
|
-
else
|
29
|
-
raise "Invalid hypervisor #{type}"
|
30
|
-
end
|
31
|
-
|
32
|
-
return hclass.new(options)
|
33
|
-
end
|
34
|
-
|
35
|
-
def generate tokens
|
11
|
+
include BeakerHostGenerator::Parser
|
12
|
+
include BeakerHostGenerator::Roles
|
13
|
+
|
14
|
+
# Main host generation entry point, returns a YAML map as a string for the
|
15
|
+
# given host specification and optional configuration.
|
16
|
+
#
|
17
|
+
# @param layout [String] The raw hosts specification user input.
|
18
|
+
# For example `"centos6-64m-redhat7-64a"`.
|
19
|
+
# @param options [Hash] Global, optional configuration such as the default
|
20
|
+
# hypervisor or OS info version.
|
21
|
+
#
|
22
|
+
# @returns [String] A complete YAML map as a string defining the HOSTS and
|
23
|
+
# CONFIG sections as required by Beaker.
|
24
|
+
def generate(layout, options)
|
25
|
+
tokens = tokenize_layout(layout)
|
26
|
+
config = {}.deep_merge(BASE_CONFIG)
|
36
27
|
nodeid = Hash.new(1)
|
37
28
|
ostype = nil
|
29
|
+
bhg_version = options[:osinfo_version] || 0
|
38
30
|
|
39
31
|
tokens.each do |token|
|
40
|
-
if is_ostype_token?(token,
|
32
|
+
if is_ostype_token?(token, bhg_version)
|
41
33
|
if nodeid[ostype] == 1 and ostype != nil
|
42
34
|
raise "Error: no nodes generated for #{ostype}"
|
43
35
|
end
|
@@ -45,85 +37,45 @@ module BeakerHostGenerator
|
|
45
37
|
next
|
46
38
|
end
|
47
39
|
|
48
|
-
node_info =
|
40
|
+
node_info = parse_node_info_token(token)
|
49
41
|
|
42
|
+
# Build node host name
|
43
|
+
platform = "#{ostype}-#{node_info['bits']}"
|
44
|
+
host_name = "#{platform}-#{nodeid[ostype]}"
|
45
|
+
|
46
|
+
node_info['platform'] = platform
|
50
47
|
node_info['ostype'] = ostype
|
51
48
|
node_info['nodeid'] = nodeid[ostype]
|
52
49
|
|
53
|
-
|
54
|
-
'pe_dir' => pe_dir(pe_version, pe_family),
|
55
|
-
'pe_ver' => pe_version,
|
56
|
-
'pe_upgrade_dir' => pe_dir(pe_upgrade_version, pe_upgrade_family),
|
57
|
-
'pe_upgrade_ver' => pe_upgrade_version,
|
58
|
-
}
|
50
|
+
host_config = base_host_config(options)
|
59
51
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
52
|
+
# Delegate to the hypervisor
|
53
|
+
hypervisor = BeakerHostGenerator::Hypervisor.create(node_info, options)
|
54
|
+
host_config = hypervisor.generate_node(node_info, host_config, bhg_version)
|
55
|
+
config['CONFIG'].deep_merge!(hypervisor.global_config())
|
65
56
|
|
66
|
-
|
67
|
-
|
57
|
+
# Merge in any arbitrary key-value host settings. Treat the 'hostname'
|
58
|
+
# setting specially, and don't merge it in as an arbitrary setting.
|
59
|
+
arbitrary_settings = node_info['host_settings']
|
60
|
+
host_name = arbitrary_settings.delete('hostname') if
|
61
|
+
arbitrary_settings.has_key?('hostname')
|
62
|
+
host_config.merge!(arbitrary_settings)
|
68
63
|
|
69
64
|
if PE_USE_WIN32 && ostype =~ /windows/ && node_info['bits'] == "64"
|
70
65
|
host_config['ruby_arch'] = 'x86'
|
71
66
|
host_config['install_32'] = true
|
72
67
|
end
|
73
68
|
|
74
|
-
|
75
|
-
host_config['roles'] = ['agent']
|
76
|
-
else
|
77
|
-
host_config['roles'] = []
|
78
|
-
end
|
79
|
-
|
80
|
-
host_config['roles'].concat __generate_host_roles(node_info)
|
81
|
-
host_config['roles'].uniq!
|
69
|
+
generate_host_roles!(host_config, node_info, options)
|
82
70
|
|
83
|
-
|
84
|
-
host_config['roles'].each do |role|
|
85
|
-
host_config.deep_merge! __get_role_config(role)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
@config['HOSTS'][host_name] = host_config
|
71
|
+
config['HOSTS'][host_name] = host_config
|
90
72
|
nodeid[ostype] += 1
|
91
73
|
end
|
92
74
|
|
93
|
-
return
|
94
|
-
end
|
95
|
-
|
96
|
-
def __get_role_config role
|
97
|
-
begin
|
98
|
-
r = BeakerHostGenerator::Roles.new
|
99
|
-
m = r.method(role)
|
100
|
-
rescue NameError
|
101
|
-
return {}
|
102
|
-
end
|
103
|
-
|
104
|
-
return m.call
|
105
|
-
end
|
106
|
-
|
107
|
-
def __parse_node_info_token token
|
108
|
-
node_info = NODE_REGEX.match(token)
|
109
|
-
|
110
|
-
if node_info
|
111
|
-
node_info = Hash[ node_info.names.zip( node_info.captures ) ]
|
112
|
-
else
|
113
|
-
raise InvalidNodeSpecError.new, "Invalid node_info token: #{token}"
|
114
|
-
end
|
115
|
-
|
116
|
-
if node_info['arbitrary_roles']
|
117
|
-
node_info['arbitrary_roles'] = node_info['arbitrary_roles'].split(',') || ''
|
118
|
-
else
|
119
|
-
# Default to empty list to avoid having to check for nil elsewhere
|
120
|
-
node_info['arbitrary_roles'] = []
|
121
|
-
end
|
122
|
-
|
123
|
-
return node_info
|
75
|
+
return config.to_yaml
|
124
76
|
end
|
125
77
|
|
126
|
-
def
|
78
|
+
def get_host_roles(node_info)
|
127
79
|
roles = []
|
128
80
|
|
129
81
|
node_info['roles'].each_char do |c|
|
@@ -137,15 +89,23 @@ module BeakerHostGenerator
|
|
137
89
|
return roles
|
138
90
|
end
|
139
91
|
|
140
|
-
|
141
|
-
raise "Method 'is_ostype_token?' not implemented!"
|
142
|
-
end
|
92
|
+
private
|
143
93
|
|
144
|
-
def
|
145
|
-
|
146
|
-
|
94
|
+
def generate_host_roles!(host_config, node_info, options)
|
95
|
+
if not options[:disable_default_role]
|
96
|
+
host_config['roles'] = ['agent']
|
97
|
+
else
|
98
|
+
host_config['roles'] = []
|
99
|
+
end
|
100
|
+
|
101
|
+
host_config['roles'].concat get_host_roles(node_info)
|
102
|
+
host_config['roles'].uniq!
|
147
103
|
|
104
|
+
if not options[:disable_role_config]
|
105
|
+
host_config['roles'].each do |role|
|
106
|
+
host_config.deep_merge! get_role_config(role)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
148
110
|
end
|
149
111
|
end
|
150
|
-
|
151
|
-
require 'beaker-hostgenerator/generator/vmpooler'
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module BeakerHostGenerator
|
2
|
+
|
3
|
+
# Defines an Interface for the implementation of a hypervisor, and provides
|
4
|
+
# a static module function `create(node_info, options)` for instantiating
|
5
|
+
# the appropriate hypervisor implementation.
|
6
|
+
#
|
7
|
+
# New hypervisor implementations must define the methods in the Interface
|
8
|
+
# class, and add a new element to the `supported_hypervisors` map.
|
9
|
+
#
|
10
|
+
# Any number of hypervisors are used by a single Generator during host
|
11
|
+
# generation in the `BeakerHostGenerator::Generator#generate` method.
|
12
|
+
# Whenever a host specifies a specific hypervisor implementation, the
|
13
|
+
# Generator will instantiate the appropriate hypervisor via
|
14
|
+
# `BeakerHostGenerator::Hypervisor.create`.
|
15
|
+
module Hypervisor
|
16
|
+
|
17
|
+
# Static factory method to instantiate the appropriate hypervisor for the
|
18
|
+
# given node. If no hypervisor is specified in the node info, then the
|
19
|
+
# hypervisor specified in the options will be created.
|
20
|
+
#
|
21
|
+
# @param node_info [Hash{String=>Object}] Node data parsed from the input
|
22
|
+
# spec string.
|
23
|
+
#
|
24
|
+
# @option options [String] :hypervisor The string name of the hypervisor to
|
25
|
+
# create. An exception will be thrown if the
|
26
|
+
# hypervisor is unrecognized.
|
27
|
+
def self.create(node_info, options)
|
28
|
+
name = node_info['host_settings']['hypervisor'] || options[:hypervisor]
|
29
|
+
hypervisor = supported_hypervisors[name]
|
30
|
+
if hypervisor
|
31
|
+
hypervisor.new
|
32
|
+
else
|
33
|
+
raise "Invalid hypervisor: #{name}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns a map of all valid hypervisor implementations, where the keys are
|
38
|
+
# the string names and the values are the implementation classes.
|
39
|
+
#
|
40
|
+
# The string names are part of the beaker-hostgenerator API as they are
|
41
|
+
# used for specifying the default or per-host hypervisor in the layout
|
42
|
+
# specification input string.
|
43
|
+
#
|
44
|
+
# @returns [Hash{String=>Hypervisor::Interface}] A map of hypervisor names
|
45
|
+
# and their implementations.
|
46
|
+
def self.supported_hypervisors()
|
47
|
+
{
|
48
|
+
'none' => BeakerHostGenerator::Hypervisor::None,
|
49
|
+
'vmpooler' => BeakerHostGenerator::Hypervisor::Vmpooler
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
class Interface
|
54
|
+
# Returns a map containing any general configuration required by this
|
55
|
+
# hypervisor. This map will be merged into the 'CONFIG' section of the
|
56
|
+
# final hosts configuration output.
|
57
|
+
#
|
58
|
+
# This will only be called if the hypervisor is used for a node, in which
|
59
|
+
# case the returned map will be merged in with global configuration from
|
60
|
+
# other hypervisors.
|
61
|
+
def global_config()
|
62
|
+
{}
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns a map of host configuration for a single node.
|
66
|
+
#
|
67
|
+
# This will be called for each individual node requested in the hosts
|
68
|
+
# specification input.
|
69
|
+
#
|
70
|
+
# Any configuration that is required by this hypervisor but is not
|
71
|
+
# specific to each node can be put in the `global_config` map.
|
72
|
+
#
|
73
|
+
# @param [Hash{String=>String}] node_info General info about the given
|
74
|
+
# node, such as the ostype, nodeid, and
|
75
|
+
# bits.
|
76
|
+
#
|
77
|
+
# @param [Hash{String=>Object}] base_config The node definition so far,
|
78
|
+
# which serves a starting point for this
|
79
|
+
# hypervisor to build upon. It is expected
|
80
|
+
# that this map will be merged into the map
|
81
|
+
# returned by this method.
|
82
|
+
#
|
83
|
+
# @param [Integer] bhg_version The version of OS info to use when building
|
84
|
+
# up the node definition.
|
85
|
+
def generate_node(node_info, base_config, bhg_version)
|
86
|
+
raise "Method 'generate_node' not implemented!"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Require the hypervisor implementations so they can be referenced/instantiated
|
93
|
+
# in the `create` factory method. We need to put these require statements at the
|
94
|
+
# bottom of this file to avoid circular references between this file and the
|
95
|
+
# hypervisor implementation files.
|
96
|
+
require 'beaker-hostgenerator/hypervisor/vmpooler'
|
97
|
+
require 'beaker-hostgenerator/hypervisor/none'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'beaker-hostgenerator/hypervisor'
|
2
|
+
require 'beaker-hostgenerator/data'
|
3
|
+
require 'deep_merge'
|
4
|
+
|
5
|
+
module BeakerHostGenerator::Hypervisor
|
6
|
+
class None < BeakerHostGenerator::Hypervisor::Interface
|
7
|
+
include BeakerHostGenerator::Data
|
8
|
+
|
9
|
+
def generate_node(node_info, base_config, bhg_version)
|
10
|
+
platform = node_info['platform']
|
11
|
+
general_info = get_platform_info(bhg_version, platform, :general)
|
12
|
+
base_config.deep_merge! general_info
|
13
|
+
base_config['hypervisor'] = 'none'
|
14
|
+
return base_config
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'beaker-hostgenerator/data'
|
2
|
+
require 'beaker-hostgenerator/hypervisor'
|
3
|
+
require 'deep_merge'
|
4
|
+
|
5
|
+
module BeakerHostGenerator
|
6
|
+
module Hypervisor
|
7
|
+
class Vmpooler < BeakerHostGenerator::Hypervisor::Interface
|
8
|
+
include BeakerHostGenerator::Data
|
9
|
+
|
10
|
+
def global_config()
|
11
|
+
{
|
12
|
+
'pooling_api' => 'http://vmpooler.delivery.puppetlabs.net/'
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate_node(node_info, base_config, bhg_version)
|
17
|
+
# set hypervisor
|
18
|
+
base_config['hypervisor'] = 'vmpooler'
|
19
|
+
|
20
|
+
platform = node_info['platform']
|
21
|
+
platform_info = get_platform_info(bhg_version, platform, :vmpooler)
|
22
|
+
base_config.deep_merge! platform_info
|
23
|
+
|
24
|
+
# Some vmpooler/vsphere platforms have special requirements.
|
25
|
+
# We munge the node host config here if that is necessary.
|
26
|
+
fixup_node base_config
|
27
|
+
|
28
|
+
return base_config
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'beaker-hostgenerator/data'
|
2
|
+
require 'beaker-hostgenerator/exceptions'
|
3
|
+
|
4
|
+
module BeakerHostGenerator
|
5
|
+
# Functions for parsing the raw user input host layout string and turning
|
6
|
+
# them into proper data structures suitable for processing by the Generator.
|
7
|
+
#
|
8
|
+
# The functions mainly perform data type conversions, like splitting the
|
9
|
+
# single input string into a list of strings, each of which will be processed
|
10
|
+
# further by other functions in this module.
|
11
|
+
#
|
12
|
+
# For example, given the raw user input string that defines the host layout,
|
13
|
+
# you would first split it into tokens via `tokenize_layout`, and then for
|
14
|
+
# each token you would call `is_ostype_token?` and/or `parse_node_info_token`.
|
15
|
+
module Parser
|
16
|
+
|
17
|
+
# Capture role and bit width information about the node.
|
18
|
+
#
|
19
|
+
# See Ruby Regexp class for information on the capture groups used below.
|
20
|
+
# http://ruby-doc.org/core-2.2.0/Regexp.html#class-Regexp-label-Character+Classes
|
21
|
+
#
|
22
|
+
# Examples node specs and their resulting roles
|
23
|
+
#
|
24
|
+
# 64compile_master,zuul,meow.a
|
25
|
+
# * compile_master
|
26
|
+
# * zuul
|
27
|
+
# * meow
|
28
|
+
# * agent
|
29
|
+
#
|
30
|
+
# 32herp.cdma
|
31
|
+
# * herp
|
32
|
+
# * dashboard
|
33
|
+
# * database
|
34
|
+
# * master
|
35
|
+
# * agent
|
36
|
+
#
|
37
|
+
# 64dashboard,master,agent,database.
|
38
|
+
# * dashboard
|
39
|
+
# * master
|
40
|
+
# * agent
|
41
|
+
# * database
|
42
|
+
#
|
43
|
+
NODE_REGEX=/\A(?<bits>\d+)((?<arbitrary_roles>([[:lower:]_]*|\,)*)\.)?(?<roles>[uacldfm]*)(?<host_settings>\{[[:print:]]*\})?\Z/
|
44
|
+
|
45
|
+
module_function
|
46
|
+
|
47
|
+
# Breaks apart the host input string into chunks suitable for processing
|
48
|
+
# by the generator. Returns an array of substrings of the input spec string.
|
49
|
+
#
|
50
|
+
# The input string is expected to be properly formatted using the dash `-`
|
51
|
+
# character as a delimiter. Dashes may also be used within braces `{...}`,
|
52
|
+
# which are used to define arbitrary key-values on a node.
|
53
|
+
#
|
54
|
+
# @param spec [String] Well-formatted string specification of the hosts to
|
55
|
+
# generate. For example `"centos6-64m-debian8-32a"`.
|
56
|
+
# @returns [Array<String>] Input string split into substrings suitable for
|
57
|
+
# processing by the generator. For example
|
58
|
+
# `["centos6", "64m", "debian8", "32a"]`.
|
59
|
+
def tokenize_layout(layout_spec)
|
60
|
+
# Here we allow dashes in certain parts of the spec string
|
61
|
+
# i.e. "centos6-64m{hostname=foo-bar}-debian8-32"
|
62
|
+
# by first replacing all occurrences of - with | that exist within
|
63
|
+
# the braces {...}.
|
64
|
+
#
|
65
|
+
# So we'd end up with:
|
66
|
+
# "centos6-64m{hostname=foo|bar}-debian8-32"
|
67
|
+
#
|
68
|
+
# Which we can then simply split on - into:
|
69
|
+
# ["centos6", "64{hostname=foo|bar}", "debian8", "32"]
|
70
|
+
#
|
71
|
+
# And then finally turn the | back into - now that we've
|
72
|
+
# properly decomposed the spec string:
|
73
|
+
# ["centos6", "64{hostname=foo-bar}", "debian8", "32"]
|
74
|
+
#
|
75
|
+
# NOTE we've specifically chosen to use the pipe character |
|
76
|
+
# due to its unlikely occurrence in the user input string.
|
77
|
+
spec = String.new(layout_spec) # Copy so we can replace characters inline
|
78
|
+
within_braces = false
|
79
|
+
spec.chars.each_with_index do |char, index|
|
80
|
+
case char
|
81
|
+
when '{'
|
82
|
+
within_braces = true
|
83
|
+
when '}'
|
84
|
+
within_braces = false
|
85
|
+
when '-'
|
86
|
+
spec[index] = '|' if within_braces
|
87
|
+
end
|
88
|
+
end
|
89
|
+
tokens = spec.split('-')
|
90
|
+
tokens.map { |t| t.gsub('|', '-') }
|
91
|
+
end
|
92
|
+
|
93
|
+
# Tests if a string token represents an OS platform (i.e. "centos6" or
|
94
|
+
# "debian8") and not another part of the host specification like the
|
95
|
+
# architecture bit (i.e. "32" or "64").
|
96
|
+
#
|
97
|
+
# This is used when parsing the host generator input string to determine
|
98
|
+
# if we're introducing a host for a new platform or if we're adding another
|
99
|
+
# host for a current platform.
|
100
|
+
#
|
101
|
+
# @param [String] token A piece of the host generator input that might refer
|
102
|
+
# to an OS platform. For example `"centos6"` or `"debian8"`.
|
103
|
+
#
|
104
|
+
# @param [Integer] bhg_version The version of OS info to use when testing
|
105
|
+
# for whether the token represent an OS platform.
|
106
|
+
def is_ostype_token?(token, bhg_version)
|
107
|
+
BeakerHostGenerator::Data.get_platforms(bhg_version).each do |platform|
|
108
|
+
ostype = platform.split('-')[0]
|
109
|
+
if ostype == token
|
110
|
+
return true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
return false
|
114
|
+
end
|
115
|
+
|
116
|
+
# Converts a string token that represents a node (and not an OS type) into
|
117
|
+
# a proper hash map with keys representing the various regex capture groups
|
118
|
+
# in `NODE_REGEX` and values being the captured text.
|
119
|
+
#
|
120
|
+
# Throws an exception if the token is not in the expected formatted, as
|
121
|
+
# determined by `NODE_REGEX.match`.
|
122
|
+
#
|
123
|
+
# It is expected that the `Generator` will have initimate knowledge about
|
124
|
+
# the keys and values in the returned map, as it may be adjusted and given
|
125
|
+
# to the hypervisors or other abstractions for processing.
|
126
|
+
#
|
127
|
+
# @param token [String] The portion of the user input layout specifiction
|
128
|
+
# that describes the node (and not the OS platform).
|
129
|
+
# For example `"64myrole.mdca"`.
|
130
|
+
#
|
131
|
+
# @returns [Hash{String=>Object}] A map containing the regex capture groups
|
132
|
+
# suitable for processing by the Generator
|
133
|
+
# and hypervisors.
|
134
|
+
def parse_node_info_token(token)
|
135
|
+
node_info = NODE_REGEX.match(token)
|
136
|
+
|
137
|
+
if node_info
|
138
|
+
node_info = Hash[ node_info.names.zip( node_info.captures ) ]
|
139
|
+
else
|
140
|
+
raise BeakerHostGenerator::Exceptions::InvalidNodeSpecError.new,
|
141
|
+
"Invalid node_info token: #{token}"
|
142
|
+
end
|
143
|
+
|
144
|
+
if node_info['arbitrary_roles']
|
145
|
+
node_info['arbitrary_roles'] =
|
146
|
+
node_info['arbitrary_roles'].split(',') || ''
|
147
|
+
else
|
148
|
+
# Default to empty list to avoid having to check for nil elsewhere
|
149
|
+
node_info['arbitrary_roles'] = []
|
150
|
+
end
|
151
|
+
|
152
|
+
if node_info['host_settings']
|
153
|
+
node_info['host_settings'] =
|
154
|
+
settings_string_to_map(node_info['host_settings'])
|
155
|
+
else
|
156
|
+
node_info['host_settings'] = {}
|
157
|
+
end
|
158
|
+
|
159
|
+
return node_info
|
160
|
+
end
|
161
|
+
|
162
|
+
# Transforms the arbitrary host settings map from a string representation
|
163
|
+
# to a proper hash map data structure for merging into the host
|
164
|
+
# configuration.
|
165
|
+
#
|
166
|
+
# The string is expected to be of the form "{key1=value1,key2=value2,...}".
|
167
|
+
# Any whitespace found in the string will be stripped and ignored.
|
168
|
+
#
|
169
|
+
# Throws an exception of the string is malformed in any way.
|
170
|
+
#
|
171
|
+
# @param host_settings [String] Non-nil user input string that defines host
|
172
|
+
# specific settings.
|
173
|
+
#
|
174
|
+
# @returns [Hash{String=>String}] The host_settings string as a map.
|
175
|
+
def settings_string_to_map(host_settings)
|
176
|
+
# Strip it down to a list of pairs
|
177
|
+
settings_pairs =
|
178
|
+
host_settings.
|
179
|
+
delete('{}').
|
180
|
+
gsub(' ', '').
|
181
|
+
split(',').
|
182
|
+
map { |keyvalue| keyvalue.split('=') }
|
183
|
+
|
184
|
+
# Validate they're actually pairs, and that all keys are non-empty
|
185
|
+
settings_pairs.each do |pair|
|
186
|
+
if pair.length != 2
|
187
|
+
raise BeakerHostGenerator::Exceptions::InvalidNodeSpecError,
|
188
|
+
"Malformed host settings: #{host_settings}"
|
189
|
+
end
|
190
|
+
if pair.first.nil? || pair.first.empty?
|
191
|
+
raise BeakerHostGenerator::Exceptions::InvalidNodeSpecError,
|
192
|
+
"Malformed host settings: #{host_settings}"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
Hash[settings_pairs]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|