beaker 1.13.1 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
- ---
2
- SHA512:
3
- data.tar.gz: 57e9508cea8ac335f9d67bd3dab67a76df031b9b6c9e47e2f674446976b2e135a9e3b5d3aaa7ad1de142e5a254c27c714639a2a4ecc56a98ebc6c8914f9b2798
4
- metadata.gz: 7e5c4415ae77f26189b861d6332868284e5a7d8bee1e221961d8887858901efe8f9b23f74d2b9818fb66816cd418ccc12fe8c902b078c0db2cff36a23bbfabd5
5
- SHA1:
6
- data.tar.gz: 53f6a4f5809c8c7e64c71907127992763dad9108
7
- metadata.gz: d738e6e7d4c974cd295f3c2130f86c118423aef5
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YTAxN2IzZDYzNjNjM2E0NjhjZDVjNmE1OWQ2YmZkNWY2MDE5MGNiMg==
5
+ data.tar.gz: !binary |-
6
+ OGRjYjFhOWYxNjI5MTc2NDc3NTNlZjEyNGFkMTZmYmUxZmRkZjVhZg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YWUwMDIzZTc4MDM5MjlhY2M4ZmVkZGE3ZjIzYWVjNzk2YmEyZjZjMjRiZjdm
10
+ YTQzMTU4Njg3ZDQzNDMxMDk1NDY3NDdjZWY1NTZjMjA4ZDA2OTk4ZWE5Yzk5
11
+ MjY0Y2JjNjcxMWZlNDZhZmZlNGVkM2FiMDBhMTIzYjY2OGZmOTE=
12
+ data.tar.gz: !binary |-
13
+ NjA0MzQwMjE2YmZiZDQ1YTZhMTUwZWU5Yjk1MjFlMWNjN2EzMzg3MzJlZmQ2
14
+ OTZkMjBkYTEwM2E3MTFjMTRkMDJiMjUwMGU0ZTAxZWVhZTcwNWVjMDUwNDNh
15
+ MDE2YzNlNzQ2ZWIzMzJkMjY3MTVlYzczZWE0MjEzYTYzZjNlMTU=
@@ -1,4 +1,4 @@
1
- [ 'version32', 'version30', 'version28', 'version20' ].each do |lib|
1
+ [ 'version34', 'version32', 'version30', 'version28', 'version20' ].each do |lib|
2
2
  require "beaker/answers/#{lib}"
3
3
  end
4
4
 
@@ -21,6 +21,8 @@ module Beaker
21
21
  def self.answers(version, hosts, master_certname, options)
22
22
 
23
23
  case version
24
+ when /\A3\.4/
25
+ Version34.answers(hosts, master_certname, options)
24
26
  when /\A3\.[2-3]/
25
27
  Version32.answers(hosts, master_certname, options)
26
28
  when /\A3\.1/
@@ -0,0 +1,12 @@
1
+ require 'beaker/answers/version32'
2
+
3
+ module Beaker
4
+ module Answers
5
+ module Version34
6
+ def self.answers(hosts, master_certname, options)
7
+ the_answers = Version32.answers(hosts, master_certname, options)
8
+ return the_answers
9
+ end
10
+ end
11
+ end
12
+ end
data/lib/beaker/cli.rb CHANGED
@@ -15,6 +15,7 @@ module Beaker
15
15
  @options = @options_parser.parse_args
16
16
  @logger = Beaker::Logger.new(@options)
17
17
  @options[:logger] = @logger
18
+ @options[:timestamp] = @timestamp
18
19
  @execute = true
19
20
 
20
21
  if @options[:help]
data/lib/beaker/dsl.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  [ 'install_utils', 'roles', 'outcomes', 'assertions',
2
- 'structure', 'helpers', 'wrappers' ].each do |lib|
2
+ 'structure', 'helpers', 'ezbake_utils', 'wrappers' ].each do |lib|
3
3
  require "beaker/dsl/#{lib}"
4
4
  end
5
5
 
@@ -76,6 +76,7 @@ module Beaker
76
76
  include Beaker::DSL::Assertions
77
77
  include Beaker::DSL::Wrappers
78
78
  include Beaker::DSL::Helpers
79
+ include Beaker::DSL::EZBakeUtils
79
80
  include Beaker::DSL::InstallUtils
80
81
  end
81
82
  end
@@ -0,0 +1,220 @@
1
+ require 'beaker/dsl/install_utils'
2
+
3
+ module Beaker
4
+ module DSL
5
+ #
6
+ # This module contains methods to assist in installing projects from source
7
+ # that use ezbake for packaging.
8
+ #
9
+ # @api dsl
10
+ module EZBakeUtils
11
+
12
+ REMOTE_PACKAGES_REQUIRED = ['make']
13
+ LOCAL_COMMANDS_REQUIRED = [
14
+ ['leiningen', 'lein --version', nil],
15
+ ['lein-pprint', 'lein with-profile ci pprint :version',
16
+ 'Must have lein-pprint installed under the :ci profile.'],
17
+ ['java', 'java -version', nil],
18
+ ['git', 'git --version', nil],
19
+ ['rake', 'rake --version', nil],
20
+ ]
21
+ class << self
22
+ attr_accessor :config
23
+ end
24
+
25
+ # Return the ezbake config.
26
+ #
27
+ def ezbake_config
28
+ EZBakeUtils.config
29
+ end
30
+
31
+ # Checks given host for the tools necessary to perform
32
+ # install_from_ezbake. If no host is given then check the local machine
33
+ # for necessary available tools. If a tool is not found, then raise
34
+ # RuntimeError.
35
+ #
36
+ def ezbake_tools_available? host = nil
37
+ if host
38
+ REMOTE_PACKAGES_REQUIRED.each do |package_name|
39
+ if not check_for_package host, package_name
40
+ raise "Required package, #{package_name}, not installed on #{host}"
41
+ end
42
+ end
43
+ else
44
+ LOCAL_COMMANDS_REQUIRED.each do |software_name, command, additional_error_message|
45
+ if not system command
46
+ error_message = "Must have #{software_name} installed on development system.\n"
47
+ if additional_error_message
48
+ error_message += additional_error_message
49
+ end
50
+ raise error_message
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ # Prepares a staging directory for the specified project.
57
+ #
58
+ # @param [String] project_name The name of the ezbake project being worked
59
+ # on.
60
+ # @param [String] project_version The desired version of the primary
61
+ # subproject being worked.
62
+ # @param [String] ezbake_dir The local directory where the ezbake project
63
+ # resides or should reside if it doesn't exist
64
+ # already.
65
+ #
66
+ def ezbake_stage project_name, project_version, ezbake_dir="tmp/ezbake"
67
+ ezbake_tools_available?
68
+ conditionally_clone "git@github.com:puppetlabs/ezbake.git", ezbake_dir
69
+
70
+ package_version = ''
71
+ Dir.chdir(ezbake_dir) do
72
+ `lein run -- stage #{project_name} #{project_name}-version=#{project_version}`
73
+ end
74
+
75
+ staging_dir = File.join(ezbake_dir, 'target/staging')
76
+ Dir.chdir(staging_dir) do
77
+ output = `rake package:bootstrap`
78
+ load 'ezbake.rb'
79
+ ezbake = EZBake::Config
80
+ ezbake[:package_version] = `echo -n $(rake pl:print_build_param[ref] | tail -n 1)`
81
+ EZBakeUtils.config = ezbake
82
+ end
83
+ end
84
+
85
+ # Installs ezbake dependencies on given host.
86
+ #
87
+ # @param [Host] host A single remote host on which to install the
88
+ # packaging dependencies of the ezbake project configuration currently in
89
+ # Beaker::DSL::EZBakeUtils.config
90
+ #
91
+ def install_ezbake_deps host
92
+ ezbake_tools_available? host
93
+
94
+ if not ezbake_config
95
+ ezbake_stage project_name, project_version
96
+ end
97
+
98
+ variant, version, arch, codename = host['platform'].to_array
99
+ ezbake = ezbake_config
100
+
101
+ case variant
102
+ when /^(fedora|el|centos)$/
103
+ dependency_list = ezbake[:redhat][:additional_dependencies]
104
+ dependency_list.each do |dependency|
105
+ package_name, _, package_version = dependency.split
106
+ install_package host, package_name, package_version
107
+ end
108
+
109
+ when /^(debian|ubuntu)$/
110
+ dependency_list = ezbake[:debian][:additional_dependencies]
111
+ dependency_list.each do |dependency|
112
+ package_name, _, package_version = dependency.split
113
+ if package_version
114
+ package_version = package_version.chop
115
+ end
116
+ install_package host, package_name, package_version
117
+ end
118
+
119
+ else
120
+ raise "No repository installation step for #{variant} yet..."
121
+ end
122
+
123
+ end
124
+
125
+ # Installs leiningen project with given name and version on remote host.
126
+ #
127
+ # @param [Host] host A single remote host on which to install the
128
+ # specified leiningen project.
129
+ # @param [String] project_name The name of the project. In ezbake context
130
+ # this is the name of both a subdirectory of the ezbake_dir/configs dir
131
+ # and the name of the .clj file in that directory which contains the
132
+ # project map used by ezbake to create the staging directory.
133
+ # @param [String] project_version The version of the project specified by
134
+ # project_name which is to be built and installed on the remote host.
135
+ # @param [String] ezbake_dir The directory to which ezbake should be
136
+ # cloned; alternatively, if ezbake is already at that directory, it will
137
+ # be updated from its github master before any ezbake operations are
138
+ # performed.
139
+ #
140
+ def install_from_ezbake host, project_name, project_version, env_args={}, ezbake_dir='tmp/ezbake'
141
+ ezbake_tools_available? host
142
+
143
+ if not ezbake_config
144
+ ezbake_stage project_name, project_version
145
+ end
146
+
147
+ variant, _, _, _ = host['platform'].to_array
148
+
149
+ case variant
150
+ when /^(osx|windows|solaris|aix)$/
151
+ raise "Beaker::DSL::EZBakeUtils unsupported platform: #{variant}"
152
+ end
153
+
154
+ ezbake = ezbake_config
155
+ project_package_version = ezbake[:package_version]
156
+ project_name = ezbake[:project]
157
+
158
+ ezbake_staging_dir = File.join(ezbake_dir, "target/staging")
159
+
160
+ remote_tarball = ""
161
+ local_tarball = ""
162
+ dir_name = ""
163
+
164
+ Dir.chdir(ezbake_staging_dir) do
165
+ output = `rake package:tar`
166
+
167
+ pattern = "%s-%s"
168
+ dir_name = pattern % [
169
+ project_name,
170
+ project_package_version
171
+ ]
172
+ local_tarball = "./pkg/" + dir_name + ".tar.gz"
173
+ remote_tarball = "/root/" + dir_name + ".tar.gz"
174
+
175
+ scp_to host, local_tarball, remote_tarball
176
+ end
177
+
178
+ # untar tarball on host
179
+ on host, "tar -xzf " + remote_tarball
180
+
181
+ # "make" on target
182
+ cd_to_package_dir = "cd /root/" + dir_name + "; "
183
+ env = ""
184
+ if not env_args.empty?
185
+ env = "env " + env_args.map {|k, v| "#{k}=#{v} "}.join(' ')
186
+ end
187
+ on host, cd_to_package_dir + env + "make -e install-" + project_name
188
+
189
+ # install init scripts and default settings, perform additional preinst
190
+ # TODO: figure out a better way to install init scripts and defaults
191
+ case variant
192
+ when /^(fedora|el|centos)$/
193
+ env += "defaultsdir=/etc/sysconfig "
194
+ on host, cd_to_package_dir + env + "make -e install-rpm-sysv-init"
195
+ when /^(debian|ubuntu)$/
196
+ env += "defaultsdir=/etc/default "
197
+ on host, cd_to_package_dir + env + "make -e install-deb-sysv-init"
198
+ else
199
+ raise "No ezbake installation step for #{variant} yet..."
200
+ end
201
+ end
202
+
203
+ # Only clone from given git URI if there is no existing git clone at the
204
+ # given local_path location.
205
+ #
206
+ # @!visibility private
207
+ def conditionally_clone(upstream_uri, local_path)
208
+ ezbake_tools_available?
209
+ if system "git --work-tree=#{local_path} --git-dir=#{local_path}/.git status"
210
+ system "git --work-tree=#{local_path} --git-dir=#{local_path}/.git pull"
211
+ else
212
+ parent_dir = File.dirname(local_path)
213
+ FileUtils.mkdir_p(parent_dir)
214
+ system "git clone #{upstream_uri} #{local_path}"
215
+ end
216
+ end
217
+
218
+ end
219
+ end
220
+ end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require 'resolv'
2
3
  require 'inifile'
3
4
  require 'timeout'
@@ -23,6 +24,9 @@ module Beaker
23
24
  #
24
25
  # @api dsl
25
26
  module Helpers
27
+
28
+ PUPPET_MODULE_INSTALL_IGNORE = ['.git', '.idea', '.vagrant', '.vendor', 'acceptance', 'spec', 'tests', 'log']
29
+
26
30
  # @!macro common_opts
27
31
  # @param [Hash{Symbol=>String}] opts Options to alter execution.
28
32
  # @option opts [Boolean] :silent (false) Do not produce log output
@@ -221,8 +225,8 @@ module Beaker
221
225
  # @param [String] package_name Name of the package to install
222
226
  #
223
227
  # @return [Result] An object representing the outcome of *install command*.
224
- def install_package host, package_name
225
- host.install_package package_name
228
+ def install_package host, package_name, package_version = nil
229
+ host.install_package package_name, '', package_version
226
230
  end
227
231
 
228
232
  # Upgrade a package on a host. The package must already be installed
@@ -345,8 +349,8 @@ module Beaker
345
349
  # @option opts [String] :source The location on the test runners box where the files are found
346
350
  # @option opts [String] :module_name The name of the module to be copied over
347
351
  def puppet_module_install_on(host, opts = {})
348
- Array(host).each do |host|
349
- scp_to host, opts[:source], File.join(host['distmoduledir'], opts[:module_name])
352
+ Array(host).each do |h|
353
+ on h, puppet("module install #{opts[:module_name]}")
350
354
  end
351
355
  end
352
356
 
@@ -522,12 +526,15 @@ module Beaker
522
526
  cmdline_args = conf_opts[:__commandline_args__]
523
527
  conf_opts = conf_opts.reject { |k,v| k == :__commandline_args__ }
524
528
 
529
+ curl_retries = host['master-start-curl-retries'] || options['master-start-curl-retries']
530
+ logger.debug "Setting curl retries to #{curl_retries}"
531
+
525
532
  begin
526
533
  backup_file = backup_the_file(host, host['puppetpath'], testdir, 'puppet.conf')
527
534
  lay_down_new_puppet_conf host, conf_opts, testdir
528
535
 
529
536
  if host['puppetservice']
530
- bounce_service( host, host['puppetservice'] )
537
+ bounce_service( host, host['puppetservice'], curl_retries )
531
538
  else
532
539
  puppet_master_started = start_puppet_from_source_on!( host, cmdline_args )
533
540
  end
@@ -543,7 +550,7 @@ module Beaker
543
550
  restore_puppet_conf_from_backup( host, backup_file )
544
551
 
545
552
  if host['puppetservice']
546
- bounce_service( host, host['puppetservice'] )
553
+ bounce_service( host, host['puppetservice'], curl_retries )
547
554
  else
548
555
  if puppet_master_started
549
556
  stop_puppet_from_source_on( host )
@@ -681,14 +688,12 @@ module Beaker
681
688
  end
682
689
 
683
690
  # @!visibility private
684
- def bounce_service host, service
691
+ def bounce_service host, service, curl_retries = 120
685
692
  # Any reason to not
686
693
  # host.exec puppet_resource( 'service', service, 'ensure=stopped' )
687
694
  # host.exec puppet_resource( 'service', service, 'ensure=running' )
688
695
  host.exec( Command.new( "#{host['service-prefix']}#{service} restart" ) )
689
- if host['service-wait']
690
- curl_with_retries(" #{service} ", host, "http://localhost:8140", [0, 52], 120)
691
- end
696
+ curl_with_retries(" #{service} ", host, "https://localhost:8140", [35, 60], curl_retries)
692
697
  end
693
698
 
694
699
  # Blocks until the port is open on the host specified, returns false
@@ -1135,7 +1140,7 @@ module Beaker
1135
1140
  end
1136
1141
 
1137
1142
 
1138
- #Install local module for acceptance testing
1143
+ # Install local module for acceptance testing
1139
1144
  # should be used as a presuite to ensure local module is copied to the hosts you want, particularly masters
1140
1145
  # @api dsl
1141
1146
  # @param [Host, Array<Host>, String, Symbol] host
@@ -1148,38 +1153,26 @@ module Beaker
1148
1153
  # Name which the module should be installed under, please do not include author,
1149
1154
  # if none is provided it will attempt to parse the metadata.json and then the Modulefile to determine
1150
1155
  # the name of the module
1151
- # @option opts [String] :target_module_path (host['puppetpath']/modules)
1156
+ # @option opts [String] :target_module_path (host['distmoduledir']/modules)
1152
1157
  # Location where the module should be installed, will default
1153
- # to host['puppetpath']/modules
1158
+ # to host['distmoduledir']/modules
1159
+ # @option opts [Array] :ignore_list
1154
1160
  # @raise [ArgumentError] if not host is provided or module_name is not provided and can not be found in Modulefile
1155
1161
  #
1156
- def copy_root_module_to(host, opts = {})
1157
- if !host
1158
- raise(ArgumentError, "Host must be defined")
1159
- end
1160
- source = opts[:source] || parse_for_moduleroot(Dir.getwd)
1161
- target_module_path = opts[:target_module_path] || "#{host['puppetpath']}/modules"
1162
-
1163
- module_name = opts[:module_name] || parse_for_modulename(source)
1164
- if !module_name
1165
- logger.debug('Still unable to determine the modulename')
1166
- raise(ArgumentError, "Unable to determine the module name, please update your call of puppet_module_install")
1167
- end
1168
-
1169
- module_dir = File.join(target_module_path, module_name)
1170
- on host, "mkdir -p #{target_module_path}"
1171
- ['manifests', 'lib', 'templates', 'metadata.json', 'Modulefile', 'files', 'Gemfile'].each do |item|
1172
- item_source = File.join(source, item)
1173
- if File.exists? item_source
1174
- options = {}
1175
- if File.directory? item_source
1176
- on host, "mkdir -p #{File.join(module_dir, item)}"
1177
- options = { :mkdir => true }
1178
- end
1179
- host.do_scp_to(item_source, module_dir, options)
1180
- end
1162
+ def copy_module_to(host, opts = {})
1163
+ opts = {:source => './',
1164
+ :target_module_path => host['distmoduledir'],
1165
+ :ignore_list => PUPPET_MODULE_INSTALL_IGNORE}.merge(opts)
1166
+ ignore_list = build_ignore_list(opts)
1167
+ target_module_dir = opts[:target_module_path]
1168
+ if opts.has_key?(:module_name)
1169
+ module_name = opts[:module_name]
1170
+ else
1171
+ module_name = parse_for_modulename(opts[:source])
1181
1172
  end
1173
+ scp_to host, File.join(opts[:source]), File.join(target_module_dir, module_name), {:ignore => ignore_list}
1182
1174
  end
1175
+ alias :copy_root_module_to :copy_module_to
1183
1176
 
1184
1177
 
1185
1178
  #Recursive method for finding the module root
@@ -1253,6 +1246,22 @@ module Beaker
1253
1246
  end
1254
1247
  end
1255
1248
 
1249
+ # Build an array list of files/directories to ignore when pushing to remote host
1250
+ # Automatically adds '..' and '.' to array. If not opts of :ignore list is provided
1251
+ # it will use the static variable PUPPET_MODULE_INSTALL_IGNORE
1252
+ #
1253
+ # @param opts [Hash]
1254
+ # @option opts [Array] :ignore_list A list of files/directories to ignore
1255
+ def build_ignore_list(opts = {})
1256
+ ignore_list = opts[:ignore_list] || PUPPET_MODULE_INSTALL_IGNORE
1257
+ if !ignore_list.kind_of?(Array) || ignore_list.nil?
1258
+ raise ArgumentError "Ignore list must be an Array"
1259
+ end
1260
+ ignore_list << '.' unless ignore_list.include? '.'
1261
+ ignore_list << '..' unless ignore_list.include? '..'
1262
+ ignore_list
1263
+ end
1264
+
1256
1265
  end
1257
1266
  end
1258
1267
  end