beaker 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +8 -0
  3. data/README.md +6 -6
  4. data/beaker.gemspec +6 -2
  5. data/lib/beaker.rb +1 -1
  6. data/lib/beaker/answers.rb +34 -7
  7. data/lib/beaker/answers/version20.rb +124 -0
  8. data/lib/beaker/answers/version28.rb +21 -0
  9. data/lib/beaker/answers/version30.rb +24 -5
  10. data/lib/beaker/cli.rb +55 -41
  11. data/lib/beaker/command.rb +2 -2
  12. data/lib/beaker/dsl/helpers.rb +320 -106
  13. data/lib/beaker/dsl/install_utils.rb +202 -81
  14. data/lib/beaker/dsl/roles.rb +40 -0
  15. data/lib/beaker/host.rb +28 -20
  16. data/lib/beaker/host/unix.rb +7 -4
  17. data/lib/beaker/host/unix/pkg.rb +42 -12
  18. data/lib/beaker/host/windows.rb +9 -5
  19. data/lib/beaker/host/windows/group.rb +1 -1
  20. data/lib/beaker/host/windows/pkg.rb +41 -8
  21. data/lib/beaker/hypervisor.rb +23 -10
  22. data/lib/beaker/hypervisor/aixer.rb +15 -19
  23. data/lib/beaker/hypervisor/blimper.rb +71 -72
  24. data/lib/beaker/hypervisor/fusion.rb +11 -10
  25. data/lib/beaker/hypervisor/solaris.rb +17 -23
  26. data/lib/beaker/hypervisor/vagrant.rb +27 -12
  27. data/lib/beaker/hypervisor/vcloud.rb +154 -138
  28. data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
  29. data/lib/beaker/hypervisor/vsphere.rb +8 -5
  30. data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
  31. data/lib/beaker/network_manager.rb +16 -12
  32. data/lib/beaker/options/command_line_parser.rb +199 -0
  33. data/lib/beaker/options/hosts_file_parser.rb +39 -0
  34. data/lib/beaker/options/options_file_parser.rb +45 -0
  35. data/lib/beaker/options/options_hash.rb +294 -0
  36. data/lib/beaker/options/parser.rb +288 -0
  37. data/lib/beaker/options/pe_version_scraper.rb +35 -0
  38. data/lib/beaker/options/presets.rb +70 -0
  39. data/lib/beaker/shared.rb +2 -1
  40. data/lib/beaker/shared/host_handler.rb +7 -2
  41. data/lib/beaker/shared/repetition.rb +1 -0
  42. data/lib/beaker/shared/timed.rb +14 -0
  43. data/lib/beaker/test_case.rb +2 -38
  44. data/lib/beaker/test_suite.rb +11 -25
  45. data/lib/beaker/utils/repo_control.rb +6 -8
  46. data/lib/beaker/utils/setup_helper.rb +9 -20
  47. data/spec/beaker/answers_spec.rb +109 -0
  48. data/spec/beaker/command_spec.rb +2 -2
  49. data/spec/beaker/dsl/assertions_spec.rb +1 -3
  50. data/spec/beaker/dsl/helpers_spec.rb +519 -84
  51. data/spec/beaker/dsl/install_utils_spec.rb +265 -16
  52. data/spec/beaker/dsl/roles_spec.rb +31 -10
  53. data/spec/beaker/host/windows/group_spec.rb +55 -0
  54. data/spec/beaker/host_spec.rb +130 -40
  55. data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
  56. data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
  57. data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
  58. data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
  59. data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
  60. data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
  61. data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
  62. data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
  63. data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
  64. data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
  65. data/spec/beaker/options/command_line_parser_spec.rb +25 -0
  66. data/spec/beaker/options/data/LATEST +1 -0
  67. data/spec/beaker/options/data/badyaml.cfg +21 -0
  68. data/spec/beaker/options/data/hosts.cfg +21 -0
  69. data/spec/beaker/options/data/opts.txt +6 -0
  70. data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
  71. data/spec/beaker/options/options_file_parser_spec.rb +23 -0
  72. data/spec/beaker/options/options_hash_spec.rb +111 -0
  73. data/spec/beaker/options/parser_spec.rb +172 -0
  74. data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
  75. data/spec/beaker/options/presets_spec.rb +24 -0
  76. data/spec/beaker/puppet_command_spec.rb +54 -21
  77. data/spec/beaker/shared/error_handler_spec.rb +40 -0
  78. data/spec/beaker/shared/host_handler_spec.rb +104 -0
  79. data/spec/beaker/shared/repetition_spec.rb +72 -0
  80. data/spec/beaker/test_suite_spec.rb +3 -16
  81. data/spec/beaker/utils/ntp_control_spec.rb +42 -0
  82. data/spec/beaker/utils/repo_control_spec.rb +168 -0
  83. data/spec/beaker/utils/setup_helper_spec.rb +82 -0
  84. data/spec/beaker/utils/validator_spec.rb +58 -0
  85. data/spec/helpers.rb +97 -0
  86. data/spec/matchers.rb +39 -0
  87. data/spec/mock_blimpy.rb +48 -0
  88. data/spec/mock_fission.rb +60 -0
  89. data/spec/mock_vsphere.rb +310 -0
  90. data/spec/mock_vsphere_helper.rb +183 -0
  91. data/spec/mocks.rb +83 -0
  92. data/spec/spec_helper.rb +8 -1
  93. metadata +106 -13
  94. data/beaker.rb +0 -10
  95. data/lib/beaker/options_parsing.rb +0 -323
  96. data/lib/beaker/test_config.rb +0 -148
  97. data/spec/beaker/options_parsing_spec.rb +0 -37
  98. data/spec/mocks_and_helpers.rb +0 -34
@@ -0,0 +1,97 @@
1
+ require 'yaml' unless defined?(YAML)
2
+ require 'json'
3
+ require 'net/http'
4
+
5
+ module Beaker
6
+ class VcloudPooled < Beaker::Hypervisor
7
+ CHARMAP = [('a'..'z'),('0'..'9')].map{|r| r.to_a}.flatten
8
+ SSH_EXCEPTIONS = [
9
+ SocketError,
10
+ Timeout::Error,
11
+ Errno::ETIMEDOUT,
12
+ Errno::EHOSTDOWN,
13
+ Errno::EHOSTUNREACH,
14
+ Errno::ECONNREFUSED,
15
+ Errno::ECONNRESET,
16
+ Errno::ENETUNREACH,
17
+ ]
18
+
19
+ def initialize(vcloud_hosts, options)
20
+ @options = options
21
+ @logger = options[:logger]
22
+ @vcloud_hosts = vcloud_hosts
23
+
24
+ raise 'You must specify a datastore for vCloud instances!' unless @options['datastore']
25
+ raise 'You must specify a resource pool for vCloud instances!' unless @options['resourcepool']
26
+ raise 'You must specify a folder for vCloud instances!' unless @options['folder']
27
+ end
28
+
29
+ def provision
30
+ start = Time.now
31
+ try = 1
32
+ @vcloud_hosts.each_with_index do |h, i|
33
+ if h['template'] =~ /\//
34
+ templatefolders = h['template'].split('/')
35
+ h['template'] = templatefolders.pop
36
+ end
37
+
38
+ @logger.notify "Requesting '#{h['template']}' VM from vCloud host pool"
39
+
40
+ begin
41
+ uri = URI.parse(@options['pooling_api']+'/vm/'+h['template'])
42
+
43
+ http = Net::HTTP.new( uri.host, uri.port )
44
+ request = Net::HTTP::Post.new(uri.request_uri)
45
+
46
+ request.set_form_data({'pool' => @options['resourcepool'], 'folder' => 'foo'})
47
+
48
+ attempts = @options[:timeout].to_i / 5
49
+ response = http.request(request)
50
+ parsed_response = JSON.parse(response.body)
51
+ if parsed_response[h['template']] && parsed_response[h['template']]['ok'] && parsed_response[h['template']]['hostname']
52
+ h['vmhostname'] = parsed_response[h['template']]['hostname']
53
+ else
54
+ raise "VcloudPooled.provision - no vCloud host free for #{h.name} in pool"
55
+ end
56
+ rescue JSON::ParserError, RuntimeError, *SSH_EXCEPTIONS => e
57
+ if try <= attempts
58
+ sleep 5
59
+ try += 1
60
+ retry
61
+ end
62
+ report_and_raise(@logger, e, 'vCloudPooled.provision')
63
+ end
64
+
65
+ @logger.notify "Using available vCloud host '#{h['vmhostname']}' (#{h.name})"
66
+ end
67
+
68
+ @logger.notify 'Spent %.2f seconds grabbing VMs' % (Time.now - start)
69
+ end
70
+
71
+ def cleanup
72
+ vm_names = @vcloud_hosts.map {|h| h['vmhostname'] }.compact
73
+ if @vcloud_hosts.length != vm_names.length
74
+ @logger.warn "Some hosts did not have vmhostname set correctly! This likely means VM provisioning was not successful"
75
+ end
76
+
77
+ start = Time.now
78
+ vm_names.each do |name|
79
+ @logger.notify "Handing '#{name}' back to pooling API for VM destruction"
80
+
81
+ uri = URI.parse(@options['pooling_api']+'/vm/'+name)
82
+
83
+ http = Net::HTTP.new( uri.host, uri.port )
84
+ request = Net::HTTP::Delete.new(uri.request_uri)
85
+
86
+ begin
87
+ response = http.request(request)
88
+ rescue *SSH_EXCEPTIONS => e
89
+ report_and_raise(@logger, e, 'vCloudPooled.cleanup (http.request)')
90
+ end
91
+ end
92
+
93
+ @logger.notify "Spent %.2f seconds cleaning up" % (Time.now - start)
94
+ end
95
+
96
+ end
97
+ end
@@ -1,13 +1,16 @@
1
+ require 'yaml' unless defined?(YAML)
2
+
1
3
  module Beaker
2
4
  class Vsphere < Beaker::Hypervisor
3
5
 
4
- def initialize(vsphere_hosts, options, config)
6
+ def initialize(vsphere_hosts, options)
5
7
  @options = options
6
- @@config = config['CONFIG'].dup
7
8
  @logger = options[:logger]
8
9
  @vsphere_hosts = vsphere_hosts
9
- require 'yaml' unless defined?(YAML)
10
- vsphere_credentials = VsphereHelper.load_config
10
+ end
11
+
12
+ def provision
13
+ vsphere_credentials = VsphereHelper.load_config(@options[:dot_fog])
11
14
 
12
15
  @logger.notify "Connecting to vSphere at #{vsphere_credentials[:server]}" +
13
16
  " with credentials for #{vsphere_credentials[:user]}"
@@ -50,7 +53,7 @@ module Beaker
50
53
 
51
54
  def cleanup
52
55
  @logger.notify "Destroying vsphere boxes"
53
- vsphere_credentials = VsphereHelper.load_config
56
+ vsphere_credentials = VsphereHelper.load_config(@options[:dot_fog])
54
57
 
55
58
  @logger.notify "Connecting to vSphere at #{vsphere_credentials[:server]}" +
56
59
  " with credentials for #{vsphere_credentials[:user]}"
@@ -1,5 +1,5 @@
1
1
  require 'yaml' unless defined?(YAML)
2
- require 'rubygems' unless defined?(Gem)
2
+ require 'rbvmomi'
3
3
  begin
4
4
  require 'beaker/logger'
5
5
  rescue LoadError
@@ -7,35 +7,29 @@ rescue LoadError
7
7
  end
8
8
 
9
9
  class VsphereHelper
10
- def initialize vInfo = {}
10
+ def initialize vInfo
11
11
  @logger = vInfo[:logger] || Beaker::Logger.new
12
- begin
13
- require 'rbvmomi'
14
- rescue LoadError
15
- raise "Unable to load RbVmomi, please ensure its installed"
16
- end
17
12
  @connection = RbVmomi::VIM.connect :host => vInfo[:server],
18
13
  :user => vInfo[:user],
19
14
  :password => vInfo[:pass],
20
15
  :insecure => true
21
16
  end
22
17
 
23
- def self.load_config
18
+ def self.load_config(dot_fog = '.fog')
24
19
  # support Fog/Cloud Provisioner layout
25
20
  # (ie, someplace besides my made up conf)
26
21
  vsphere_credentials = nil
27
- if File.exists? '/etc/plharness/vsphere'
28
- vsphere_credentials = load_legacy_credentials
29
-
30
- elsif File.exists?( File.join(ENV['HOME'], '.fog') )
31
- vsphere_credentials = load_fog_credentials
22
+ if File.exists?( dot_fog )
23
+ vsphere_credentials = load_fog_credentials(dot_fog)
24
+ else
25
+ raise ArgumentError, ".fog file '#{dot_fog}' does not exist"
32
26
  end
33
27
 
34
28
  return vsphere_credentials
35
29
  end
36
30
 
37
- def self.load_fog_credentials
38
- vInfo = YAML.load_file( File.join(ENV['HOME'], '.fog') )
31
+ def self.load_fog_credentials(dot_fog = '.fog')
32
+ vInfo = YAML.load_file( dot_fog )
39
33
 
40
34
  vsphere_credentials = {}
41
35
  vsphere_credentials[:server] = vInfo[:default][:vsphere_server]
@@ -45,24 +39,6 @@ class VsphereHelper
45
39
  return vsphere_credentials
46
40
  end
47
41
 
48
- def self.load_legacy_credentials
49
- vInfo = YAML.load_file '/etc/plharness/vsphere'
50
-
51
- puts(
52
- "Use of /etc/plharness/vsphere as a config file is deprecated.\n" +
53
- "Please use ~/.fog instead\n" +
54
- "See http://docs.puppetlabs.com/pe/2.0/" +
55
- "cloudprovisioner_configuring.html for format"
56
- )
57
-
58
- vsphere_credentials = {}
59
- vsphere_credentials[:server] = vInfo['location']
60
- vsphere_credentials[:user] = vInfo['user']
61
- vsphere_credentials[:pass] = vInfo['pass']
62
-
63
- return vsphere_credentials
64
- end
65
-
66
42
  def find_snapshot vm, snapname
67
43
  search_child_snaps vm.snapshot.rootSnapshotList, snapname
68
44
  end
@@ -193,6 +169,40 @@ class VsphereHelper
193
169
  })
194
170
  end
195
171
 
172
+ def wait_for_tasks tasks, try, attempts
173
+ obj_set = tasks.map { |task| { :obj => task } }
174
+ filter = @connection.propertyCollector.CreateFilter(
175
+ :spec => {
176
+ :propSet => [{ :type => 'Task',
177
+ :all => false,
178
+ :pathSet => ['info.state']}],
179
+ :objectSet => obj_set
180
+ },
181
+ :partialUpdates => false
182
+ )
183
+ ver = ''
184
+ while true
185
+ result = @connection.propertyCollector.WaitForUpdates(:version => ver)
186
+ ver = result.version
187
+ complete = 0
188
+ tasks.each do |task|
189
+ if ['success', 'error'].member? task.info.state
190
+ complete += 1
191
+ end
192
+ end
193
+ break if (complete == tasks.length)
194
+ if try <= attempts
195
+ sleep 5
196
+ try += 1
197
+ else
198
+ raise "unable to complete Vsphere tasks before timeout"
199
+ end
200
+ end
201
+
202
+ filter.DestroyPropertyFilter
203
+ tasks
204
+ end
205
+
196
206
  def close
197
207
  @connection.close
198
208
  end
@@ -10,15 +10,18 @@ module Beaker
10
10
  class NetworkManager
11
11
  HYPERVISOR_TYPES = ['solaris', 'blimpy', 'vsphere', 'fusion', 'aix', 'vcloud', 'vagrant']
12
12
 
13
- def initialize(config, options, logger)
13
+ def initialize(options, logger)
14
14
  @logger = logger
15
15
  @options = options
16
16
  @hosts = []
17
- @config = config
18
17
  @virtual_machines = {}
19
18
  @noprovision_machines = []
20
- @config['HOSTS'].each_key do |name|
21
- host_info = @config['HOSTS'][name]
19
+ end
20
+
21
+ def provision
22
+ #sort hosts into those to be provisioned and those to use non-provisioned
23
+ @options['HOSTS'].each_key do |name|
24
+ host_info = @options['HOSTS'][name]
22
25
  #check to see if this host has a hypervisor
23
26
  hypervisor = host_info['hypervisor']
24
27
  #provision this box
@@ -34,24 +37,21 @@ module Beaker
34
37
  @logger.debug "No hypervisor for #{name}, connecting to host without provisioning"
35
38
  @noprovision_machines << name
36
39
  end
37
-
38
40
  end
39
- end
40
41
 
41
- def provision
42
42
  @provisioned_set = {}
43
43
  @virtual_machines.each do |type, names|
44
44
  hosts_for_type = []
45
45
  #set up host objects for provisioned provisioned_set
46
46
  names.each do |name|
47
- host = Beaker::Host.create(name, @options, @config)
47
+ host = Beaker::Host.create(name, @options)
48
48
  hosts_for_type << host
49
49
  end
50
- @provisioned_set[type] = Beaker::Hypervisor.create(type, hosts_for_type, @options, @config)
50
+ @provisioned_set[type] = Beaker::Hypervisor.create(type, hosts_for_type, @options)
51
51
  @hosts << hosts_for_type
52
52
  end
53
53
  @noprovision_machines.each do |name|
54
- @hosts << Beaker::Host.create(name, @options, @config)
54
+ @hosts << Beaker::Host.create(name, @options)
55
55
  end
56
56
  @hosts = @hosts.flatten
57
57
  @hosts
@@ -63,8 +63,12 @@ module Beaker
63
63
  @hosts.each {|host| host.close }
64
64
 
65
65
  if not @options[:preserve_hosts]
66
- @provisioned_set.each_key do |type|
67
- @provisioned_set[type].cleanup
66
+ if @provisioned_set
67
+ @provisioned_set.each_key do |type|
68
+ if @provisioned_set[type]
69
+ @provisioned_set[type].cleanup
70
+ end
71
+ end
68
72
  end
69
73
  end
70
74
  end
@@ -0,0 +1,199 @@
1
+ module Beaker
2
+ module Options
3
+ #An object that parses arguments in the format ['--option', 'value', '--option2', 'value2', '--switch']
4
+ class CommandLineParser
5
+
6
+ # @example Create a CommanLineParser
7
+ # a = CommandLineParser.new
8
+ #
9
+ # @note All of Beaker's supported command line options are defined here
10
+ def initialize
11
+ @cmd_options = Beaker::Options::OptionsHash.new
12
+
13
+ @optparse = OptionParser.new do|opts|
14
+ # Set a banner
15
+ opts.banner = "Usage: #{File.basename($0)} [options...]"
16
+
17
+ opts.on '-h', '--hosts FILE',
18
+ 'Use host configuration FILE',
19
+ '(default sample.cfg)' do |file|
20
+ @cmd_options[:hosts_file] = file
21
+ end
22
+
23
+ opts.on '-o', '--options-file FILE',
24
+ 'Read options from FILE',
25
+ 'This should evaluate to a ruby hash.',
26
+ 'CLI optons are given precedence.' do |file|
27
+ @cmd_options[:options_file] = file
28
+ end
29
+
30
+ opts.on '--type TYPE',
31
+ 'one of git or pe',
32
+ 'used to determine underlying path structure of puppet install',
33
+ '(default pe)' do |type|
34
+ @cmd_options[:type] = type
35
+ end
36
+
37
+ opts.on '--helper PATH/TO/SCRIPT',
38
+ 'Ruby file evaluated prior to tests',
39
+ '(a la spec_helper)' do |script|
40
+ @cmd_options[:helper] = script
41
+ end
42
+
43
+ opts.on '--load-path /PATH/TO/DIR,/ADDITIONAL/DIR/PATHS',
44
+ 'Add paths to LOAD_PATH' do |value|
45
+ @cmd_options[:load_path] = value
46
+ end
47
+
48
+ opts.on '-t', '--tests /PATH/TO/DIR,/ADDITIONA/DIR/PATHS,/PATH/TO/FILE.rb',
49
+ 'Execute tests from paths and files' do |value|
50
+ @cmd_options[:tests] = value
51
+ end
52
+
53
+ opts.on '--pre-suite /PRE-SUITE/DIR/PATH,/ADDITIONAL/DIR/PATHS,/PATH/TO/FILE.rb',
54
+ 'Path to project specific steps to be run BEFORE testing' do |value|
55
+ @cmd_options[:pre_suite] = value
56
+ end
57
+
58
+ opts.on '--post-suite /POST-SUITE/DIR/PATH,/OPTIONAL/ADDITONAL/DIR/PATHS,/PATH/TO/FILE.rb',
59
+ 'Path to project specific steps to be run AFTER testing' do |value|
60
+ @cmd_options[:post_suite] = value
61
+ end
62
+
63
+ opts.on '--[no-]provision',
64
+ 'Do not provision vm images before testing',
65
+ '(default: true)' do |bool|
66
+ @cmd_options[:provision] = bool
67
+ end
68
+
69
+ opts.on '--[no-]preserve-hosts',
70
+ 'Preserve cloud instances' do |value|
71
+ @cmd_options[:preserve_hosts] = value
72
+ end
73
+
74
+ opts.on '--root-keys',
75
+ 'Install puppetlabs pubkeys for superuser',
76
+ '(default: false)' do |bool|
77
+ @cmd_options[:root_keys] = bool
78
+ end
79
+
80
+ opts.on '--keyfile /PATH/TO/SSH/KEY',
81
+ 'Specify alternate SSH key',
82
+ '(default: ~/.ssh/id_rsa)' do |key|
83
+ @cmd_options[:keyfile] = key
84
+ end
85
+
86
+ opts.on '--timeout TIMEOUT',
87
+ '(vCloud only) Specify a provisioning timeout (in seconds)',
88
+ '(default: 300)' do |value|
89
+ @cmd_options[:timeout] = value
90
+ end
91
+
92
+ opts.on '-i URI', '--install URI',
93
+ 'Install a project repo/app on the SUTs',
94
+ 'Provide full git URI or use short form KEYWORD/name',
95
+ 'supported keywords: PUPPET, FACTER, HIERA, HIERA-PUPPET' do |value|
96
+ @cmd_options[:install] = value
97
+ end
98
+
99
+ opts.on('-m', '--modules URI', 'Select puppet module git install URI') do |value|
100
+ @cmd_options[:modules] = value
101
+ end
102
+
103
+ opts.on '-q', '--[no-]quiet',
104
+ 'Do not log output to STDOUT',
105
+ '(default: false)' do |bool|
106
+ @cmd_options[:quiet] = bool
107
+ end
108
+
109
+ opts.on '-x', '--[no-]xml',
110
+ 'Emit JUnit XML reports on tests',
111
+ '(default: false)' do |bool|
112
+ @cmd_options[:xml] = bool
113
+ end
114
+
115
+ opts.on '--[no-]color',
116
+ 'Do not display color in log output',
117
+ '(default: true)' do |bool|
118
+ @cmd_options[:color] = bool
119
+ end
120
+
121
+ opts.on '--[no-]debug',
122
+ 'Enable full debugging',
123
+ '(default: false)' do |bool|
124
+ @cmd_options[:debug] = bool
125
+ end
126
+
127
+ opts.on '-d', '--[no-]dry-run',
128
+ 'Report what would happen on targets',
129
+ '(default: false)' do |bool|
130
+ @cmd_options[:dry_run] = bool
131
+ $dry_run = bool
132
+ end
133
+
134
+ opts.on '--fail-mode [MODE]',
135
+ 'How should the harness react to errors/failures',
136
+ 'Possible values:',
137
+ 'fast (skip all subsequent tests, cleanup, exit)',
138
+ 'stop (skip all subsequent tests, do no cleanup, exit immediately)' do |mode|
139
+ @cmd_options[:fail_mode] = mode
140
+ end
141
+
142
+ opts.on '--[no-]ntp',
143
+ 'Sync time on SUTs before testing',
144
+ '(default: false)' do |bool|
145
+ @cmd_options[:timesync] = bool
146
+ end
147
+
148
+ opts.on '--repo-proxy',
149
+ 'Proxy packaging repositories on ubuntu, debian and solaris-11',
150
+ '(default: false)' do
151
+ @cmd_options[:repo_proxy] = true
152
+ end
153
+
154
+ opts.on '--add-el-extras',
155
+ 'Add Extra Packages for Enterprise Linux (EPEL) repository to el-* hosts',
156
+ '(default: false)' do
157
+ @cmd_options[:add_el_extras] = true
158
+ end
159
+
160
+ opts.on '-c', '--config FILE',
161
+ 'DEPRECATED use --hosts' do |file|
162
+ @cmd_options[:hosts_file] = file
163
+ end
164
+
165
+ opts.on('--help', 'Display this screen' ) do
166
+ @cmd_options[:help] = true
167
+ end
168
+ end
169
+
170
+ end
171
+
172
+ # Parse an array of arguments into a Hash of options
173
+ # @param [Array] args The array of arguments to consume
174
+ #
175
+ # @example
176
+ # args = ['--option', 'value', '--option2', 'value2', '--switch']
177
+ # parser = CommandLineParser.new
178
+ # parser.parse!(args) == {:option => 'value, :options2 => value, :switch => true}
179
+ #
180
+ # @return [Hash] Return the Hash of options
181
+ def parse!( args = ARGV )
182
+ @optparse.parse!(args)
183
+ @cmd_options
184
+ end
185
+
186
+ # Generate a string representing the supported arguments
187
+ #
188
+ # @example
189
+ # parser = CommandLineParser.new
190
+ # parser.usage = "Options: ..."
191
+ #
192
+ # @return [String] Return a string representing the available arguments
193
+ def usage
194
+ @optparse.help
195
+ end
196
+
197
+ end
198
+ end
199
+ end