beaker-hostgenerator 0.5.0 → 0.6.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/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
|