puppet 2.7.25 → 2.7.26

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (77) hide show
  1. data/bin/puppet +4 -0
  2. data/ext/build_defaults.yaml +4 -4
  3. data/ext/debian/control +1 -1
  4. data/ext/packaging/Gemfile +8 -0
  5. data/ext/packaging/Gemfile.lock +28 -0
  6. data/ext/packaging/README.md +31 -4
  7. data/ext/packaging/lib/packaging.rb +21 -0
  8. data/ext/packaging/lib/packaging/config.rb +277 -0
  9. data/ext/packaging/lib/packaging/config/params.rb +175 -0
  10. data/ext/packaging/lib/packaging/tar.rb +186 -0
  11. data/ext/packaging/lib/packaging/util.rb +44 -0
  12. data/ext/packaging/lib/packaging/util/date.rb +15 -0
  13. data/ext/packaging/lib/packaging/util/file.rb +60 -0
  14. data/ext/packaging/lib/packaging/util/jira.rb +83 -0
  15. data/ext/packaging/lib/packaging/util/net.rb +16 -0
  16. data/ext/packaging/lib/packaging/util/rake_utils.rb +57 -0
  17. data/ext/packaging/lib/packaging/util/serialization.rb +19 -0
  18. data/ext/packaging/lib/packaging/util/tool.rb +30 -0
  19. data/ext/packaging/lib/packaging/util/version.rb +300 -0
  20. data/ext/packaging/packaging.rake +10 -5
  21. data/ext/packaging/spec/fixtures/config/ext/build_defaults.yaml +2 -0
  22. data/ext/packaging/spec/fixtures/config/ext/project_data.yaml +2 -0
  23. data/ext/packaging/spec/fixtures/config/params.yaml +2 -0
  24. data/ext/packaging/spec/fixtures/util/pre_tasks.yaml +4 -0
  25. data/ext/packaging/spec/lib/packaging/config_spec.rb +330 -0
  26. data/ext/packaging/spec/lib/packaging/tar_spec.rb +122 -0
  27. data/ext/packaging/spec/lib/packaging/util/file_spec.rb +48 -0
  28. data/ext/packaging/spec/lib/packaging/util/jira_spec.rb +50 -0
  29. data/ext/packaging/spec/lib/packaging/util/net_spec.rb +23 -0
  30. data/ext/packaging/spec/lib/packaging/util/rake_utils_spec.rb +70 -0
  31. data/ext/packaging/spec/lib/packaging/util/version_spec.rb +67 -0
  32. data/ext/packaging/spec/lib/packaging_spec.rb +19 -0
  33. data/ext/packaging/spec/spec_helper.rb +10 -0
  34. data/ext/packaging/spec/tasks/00_utils_spec.rb +218 -88
  35. data/ext/packaging/tasks/00_utils.rake +63 -320
  36. data/ext/packaging/tasks/30_metrics.rake +4 -4
  37. data/ext/packaging/tasks/apple.rake +28 -13
  38. data/ext/packaging/tasks/build.rake +2 -176
  39. data/ext/packaging/tasks/deb.rake +61 -20
  40. data/ext/packaging/tasks/deb_repos.rake +12 -12
  41. data/ext/packaging/tasks/doc.rake +5 -5
  42. data/ext/packaging/tasks/fetch.rake +9 -9
  43. data/ext/packaging/tasks/gem.rake +59 -33
  44. data/ext/packaging/tasks/ips.rake +22 -23
  45. data/ext/packaging/tasks/jenkins.rake +34 -34
  46. data/ext/packaging/tasks/jenkins_dynamic.rake +22 -19
  47. data/ext/packaging/tasks/load_extras.rake +21 -0
  48. data/ext/packaging/tasks/mock.rake +16 -16
  49. data/ext/packaging/tasks/pe_deb.rake +2 -2
  50. data/ext/packaging/tasks/pe_remote.rake +9 -9
  51. data/ext/packaging/tasks/pe_rpm.rake +1 -1
  52. data/ext/packaging/tasks/pe_ship.rake +48 -37
  53. data/ext/packaging/tasks/pe_sign.rake +5 -5
  54. data/ext/packaging/tasks/release.rake +5 -5
  55. data/ext/packaging/tasks/remote_build.rake +27 -27
  56. data/ext/packaging/tasks/retrieve.rake +5 -5
  57. data/ext/packaging/tasks/rpm.rake +27 -10
  58. data/ext/packaging/tasks/rpm_repos.rake +13 -12
  59. data/ext/packaging/tasks/ship.rake +67 -45
  60. data/ext/packaging/tasks/sign.rake +37 -30
  61. data/ext/packaging/tasks/tar.rake +14 -69
  62. data/ext/packaging/tasks/tickets.rake +449 -0
  63. data/ext/packaging/tasks/update.rake +2 -2
  64. data/ext/packaging/tasks/vendor_gems.rake +2 -2
  65. data/ext/packaging/tasks/version.rake +8 -38
  66. data/ext/packaging/tasks/z_data_dump.rake +35 -3
  67. data/ext/packaging/templates/downstream.xml.erb +2 -2
  68. data/ext/packaging/templates/packaging.xml.erb +13 -13
  69. data/ext/packaging/templates/repo.xml.erb +9 -7
  70. data/lib/puppet/indirector/facts/facter.rb +1 -1
  71. data/lib/puppet/version.rb +1 -1
  72. data/spec/unit/indirector/facts/facter_spec.rb +2 -2
  73. metadata +38 -13
  74. data/ext/packaging/spec/tasks/build_object_spec.rb +0 -178
  75. data/ext/packaging/tasks/10_setupvars.rake +0 -135
  76. data/ext/packaging/tasks/20_setupextravars.rake +0 -53
  77. data/ext/packaging/tasks/template.rake +0 -27
@@ -0,0 +1,186 @@
1
+ module Pkg
2
+ class Tar
3
+ require 'fileutils'
4
+ require 'pathname'
5
+ include FileUtils
6
+
7
+ attr_accessor :files, :project, :version, :excludes, :target, :templates
8
+ attr_reader :tar
9
+
10
+ def initialize
11
+ @tar = Pkg::Util::Tool.find_tool('tar', :required => true)
12
+ @project = Pkg::Config.project
13
+ @version = Pkg::Config.version
14
+ @files = Pkg::Config.files
15
+ @target = File.join(Pkg::Config.project_root, "pkg", "#{@project}-#{@version}.tar.gz")
16
+
17
+ # We require that the excludes list be a string (which is space
18
+ # separated, we hope)(deprecated) or an array.
19
+ #
20
+ if Pkg::Config.tar_excludes
21
+ if Pkg::Config.tar_excludes.is_a?(String)
22
+ warn "warning: `tar_excludes` should be an array, not a string"
23
+ @excludes = Pkg::Config.tar_excludes.split(' ')
24
+ elsif Pkg::Config.tar_excludes.is_a?(Array)
25
+ @excludes = Pkg::Config.tar_excludes
26
+ else
27
+ fail "Tarball excludes must either be an array or a string, not #{@excludes.class}"
28
+ end
29
+ else
30
+ @excludes = []
31
+ end
32
+
33
+ # On the other hand, support for explicit templates started with Arrays,
34
+ # so that's all we support.
35
+ #
36
+ if Pkg::Config.templates
37
+ @templates = Pkg::Config.templates.dup
38
+ fail "templates must be an array" unless @templates.is_a?(Array)
39
+ expand_templates
40
+ end
41
+ end
42
+
43
+ def install_files_to(workdir)
44
+ install = []
45
+ # It is nice to use arrays in YAML to represent array content, but we used
46
+ # to support a mode where a space-separated string was used. Support both
47
+ # to allow a gentle migration to a modern style...
48
+ patterns =
49
+ case @files
50
+ when String
51
+ STDERR.puts "warning: `files` should be an array, not a string"
52
+ @files.split(' ')
53
+ when Array
54
+ @files
55
+ else
56
+ raise "`files` must be a string or an array!"
57
+ end
58
+ # We need to add our list of file patterns from the configuration; this
59
+ # used to be a list of "things to copy recursively", which would install
60
+ # editor backup files and other nasty things.
61
+ #
62
+ # This handles that case correctly, with a deprecation warning, to augment
63
+ # our FileList with the right things to put in place.
64
+ #
65
+ # Eventually, when all our projects are migrated to the new standard, we
66
+ # can drop this in favour of just pushing the patterns directly into the
67
+ # FileList and eliminate many lines of code and comment.
68
+ cd Pkg::Config.project_root do
69
+ patterns.each do |pattern|
70
+ if File.directory?(pattern) and not Pkg::Util::File.empty_dir?(pattern)
71
+ install << Dir[pattern + "/**/*"]
72
+ else
73
+ install << Dir[pattern]
74
+ end
75
+ end
76
+ install.flatten!
77
+
78
+ # Transfer all the files and symlinks into the working directory...
79
+ install = install.select { |x| File.file?(x) or File.symlink?(x) or Pkg::Util::File.empty_dir?(x) }
80
+
81
+ install.each do |file|
82
+ if Pkg::Util::File.empty_dir?(file)
83
+ mkpath(File.join(workdir, file), :verbose => false)
84
+ else
85
+ mkpath(File.dirname( File.join(workdir, file) ), :verbose => false)
86
+ cp(file, File.join(workdir, file), :verbose => false, :preserve => true)
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ # The templates of a project can include globs, which may expand to an
93
+ # arbitrary number of files. This method expands all of the templates using
94
+ # Dir.glob and then filters out any templates that live in the packaging
95
+ # tools themselves. If the template is a source/target combination, it is
96
+ # returned to the array untouched.
97
+ def expand_templates
98
+ @templates.map! do |tempfile|
99
+ if tempfile.is_a?(String)
100
+ # Expand possible globs to all matching entries
101
+ Dir.glob(File.join(Pkg::Config::project_root, tempfile))
102
+ elsif tempfile.is_a?(Hash)
103
+ tempfile
104
+ end
105
+ end
106
+ @templates.flatten!
107
+
108
+ # Reject matches that are templates from packaging itself. These will contain the packaging root.
109
+ # These tend to come from the current tar.rake implementation.
110
+ @templates.reject! { |temp| temp.is_a?(String) && temp.match(/#{Pkg::Config::packaging_root}/) }
111
+ end
112
+
113
+ # Given the tar object's template files (assumed to be in Pkg::Config.project_root), transform
114
+ # them, removing the originals. If workdir is passed, assume Pkg::Config.project_root
115
+ # exists in workdir
116
+ def template(workdir=nil)
117
+ workdir ||= Pkg::Config.project_root
118
+ root = Pathname.new(Pkg::Config.project_root)
119
+
120
+ # Templates can be either a string or a hash of source and target. If it
121
+ # is a string, the target is assumed to be the same path as the
122
+ # source,with the extension removed. If it is a hash, we assume nothing
123
+ # and use the provided source and target.
124
+ @templates.each do |cur_template|
125
+ if cur_template.is_a?(String)
126
+ template_file = File.expand_path(cur_template)
127
+ target_file = template_file.sub(File.extname(template_file),"")
128
+ elsif cur_template.is_a?(Hash)
129
+ template_file = File.expand_path(cur_template["source"])
130
+ target_file = File.expand_path(cur_template["target"])
131
+ end
132
+
133
+ # We construct paths to the erb template and its proposed target file
134
+ # relative to the project root, *not* fully qualified. This allows us
135
+ # to, given a temporary workdir containing a copy of the project,
136
+ # construct the full path to the erb and target file inside the
137
+ # temporary workdir.
138
+ #
139
+ rel_path_to_template = Pathname.new(template_file).relative_path_from(root).to_s
140
+ rel_path_to_target = Pathname.new(target_file).relative_path_from(root).to_s
141
+
142
+ # What we pass to Pkg::util::File.erb_file are the paths to the erb
143
+ # and target inside of a temporary project directory. We are, in
144
+ # essence, templating "in place." This is why we remove the original
145
+ # files - they're not the originals in the authoritative project
146
+ # directory, but the originals in the temporary working copy.
147
+ if File.exist?(File.join(workdir,rel_path_to_template))
148
+ mkpath(File.dirname( File.join(workdir, rel_path_to_target) ), :verbose => false)
149
+ Pkg::Util::File.erb_file(File.join(workdir,rel_path_to_template), File.join(workdir, rel_path_to_target), true, :binding => Pkg::Config.get_binding)
150
+ elsif File.exist?(File.join(root,rel_path_to_template))
151
+ mkpath(File.dirname( File.join(workdir, rel_path_to_target) ), :verbose => false)
152
+ Pkg::Util::File.erb_file(File.join(root,rel_path_to_template), File.join(workdir, rel_path_to_target), false, :binding => Pkg::Config.get_binding)
153
+ else
154
+ fail "Expected to find #{template_file} in #{root} for templating. But it was not there. Maybe you deleted it?"
155
+ end
156
+ end
157
+ end
158
+
159
+ def tar(target, source)
160
+ mkpath File.dirname(target)
161
+ cd File.dirname(source) do
162
+ %x[#{@tar} #{@excludes.map{ |x| (" --exclude #{x} ") }.join if @excludes} -zcf '#{File.basename(target)}' '#{File.basename(source)}']
163
+ unless $?.success?
164
+ fail "Failed to create .tar.gz archive with #{@tar}. Please ensure the tar command in your path accepts the flags '-c', '-z', and '-f'"
165
+ end
166
+ mv File.basename(target), target
167
+ end
168
+ end
169
+
170
+ def clean_up(workdir)
171
+ rm_rf workdir
172
+ end
173
+
174
+ def pkg!
175
+ workdir = File.join(Pkg::Util::File.mktemp, "#{@project}-#{@version}")
176
+ mkpath workdir
177
+ self.install_files_to workdir
178
+ self.template(workdir)
179
+ Pkg::Util::Version.versionbump(workdir) if Pkg::Config.update_version_file
180
+ self.tar(@target, workdir)
181
+ self.clean_up workdir
182
+ end
183
+
184
+ end
185
+ end
186
+
@@ -0,0 +1,44 @@
1
+ # Utility methods used by the various rake tasks
2
+
3
+ module Pkg::Util
4
+ require 'erb'
5
+ require 'benchmark'
6
+ require 'packaging/util/date'
7
+ require 'packaging/util/tool'
8
+ require 'packaging/util/file'
9
+ require 'packaging/util/net'
10
+ require 'packaging/util/version'
11
+ require 'packaging/util/serialization'
12
+ require 'packaging/util/rake_utils'
13
+ require 'packaging/util/jira'
14
+
15
+ def self.boolean_value(var)
16
+ return TRUE if (var == TRUE || ( var.is_a?(String) && ( var.downcase == 'true' || var.downcase =~ /^y$|^yes$/ )))
17
+ FALSE
18
+ end
19
+
20
+ def self.in_project_root(&blk)
21
+ result = nil
22
+ fail "Cannot execute in project root if Pkg::Config.project_root is not set" unless Pkg::Config.project_root
23
+
24
+ Dir.chdir Pkg::Config.project_root do
25
+ result = blk.call
26
+ end
27
+ result
28
+ end
29
+
30
+ def self.get_var(var)
31
+ check_var(var, ENV[var])
32
+ ENV[var]
33
+ end
34
+
35
+ def self.require_library_or_fail(library, library_name = nil)
36
+ library_name ||= library
37
+ begin
38
+ require library
39
+ rescue LoadError
40
+ fail "Could not load #{library_name}. #{library_name} is required by the packaging repo for this task"
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,15 @@
1
+ # Utilities for managing/querying date/time
2
+
3
+ module Pkg::Util::Date
4
+
5
+ class << self
6
+ def timestamp(separator=nil)
7
+ if s = separator
8
+ format = "%Y#{s}%m#{s}%d#{s}%H#{s}%M#{s}%S"
9
+ else
10
+ format = "%Y-%m-%d %H:%M:%S"
11
+ end
12
+ Time.now.strftime(format)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,60 @@
1
+ # Utility methods for handling files and directories
2
+
3
+ module Pkg::Util::File
4
+
5
+ class << self
6
+ def mktemp
7
+ mktemp = Pkg::Util::Tool.find_tool('mktemp', :required => true)
8
+ `#{mktemp} -d -t pkgXXXXXX`.strip
9
+ end
10
+
11
+ def empty_dir?(dir)
12
+ File.exist?(dir) and File.directory?(dir) and Dir["#{dir}/**/*"].empty?
13
+ end
14
+
15
+ def file_exists?(file, args={:required => false})
16
+ exists = File.exist? file
17
+ if !exists and args[:required]
18
+ fail "Required file #{file} could not be found"
19
+ end
20
+ exists
21
+ end
22
+
23
+ def file_writable?(file, args={:required => false})
24
+ writable = File.writable? file
25
+ if !writable and args[:required]
26
+ fail "File #{file} is not writable"
27
+ end
28
+ writable
29
+ end
30
+
31
+ alias :get_temp :mktemp
32
+
33
+ def erb_string(erbfile, b = binding)
34
+ template = File.read(erbfile)
35
+ message = ERB.new(template, nil, "-")
36
+ message.result(b)
37
+ end
38
+
39
+ def erb_file(erbfile, outfile=nil, remove_orig = false, opts = { :binding => binding })
40
+ outfile ||= File.join(mktemp, File.basename(erbfile).sub(File.extname(erbfile),""))
41
+ output = erb_string(erbfile, opts[:binding])
42
+ File.open(outfile, 'w') { |f| f.write output }
43
+ puts "Generated: #{outfile}"
44
+ FileUtils.rm_rf erbfile if remove_orig
45
+ outfile
46
+ end
47
+
48
+ def untar_into(source, target = nil, options = "")
49
+ tar = Pkg::Util::Tool.find_tool('tar', :required => true)
50
+ # We only accept a writable directory as a target
51
+ if target and !target.empty? and file_writable?(target) and File.directory?(target)
52
+ target_opts = "-C #{target}"
53
+ end
54
+ if file_exists?(source, :required => true)
55
+ ex(%Q[#{tar} #{options} #{target_opts} -xf #{source}])
56
+ end
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,83 @@
1
+ module Pkg::Util
2
+ class Jira
3
+
4
+ # This class is a very thin wrapper around the jira library. For testability,
5
+ # the small bit of logic that does some prep for the library or processing of its
6
+ # output are extracted into a handful of class methods.
7
+
8
+ def self.jira_client_options(username, password, site)
9
+ {
10
+ :username => username,
11
+ :password => password,
12
+ :site => site,
13
+ :context_path => '',
14
+ :auth_type => :basic,
15
+ :use_ssl => true,
16
+ }
17
+ end
18
+
19
+ def self.jira_project_name(projects, project)
20
+ # projects is an array of objects with key and name methods
21
+ projects.find { |p| p.key == project }.name
22
+ end
23
+
24
+ def self.jira_issue_fields(summary, description, project, parent, assignee)
25
+ # build the fields hash describing the ticket
26
+ fields = {
27
+ 'summary' => summary,
28
+ 'description' => description,
29
+ 'project' => { 'key' => project},
30
+ 'issuetype' => { 'name' => parent ? "Sub-task" : "Task" },
31
+ 'assignee' => { 'name' => assignee },
32
+ }
33
+ if parent
34
+ fields['parent'] = { 'id' => parent }
35
+ end
36
+
37
+ fields
38
+ end
39
+
40
+ # Future improvement, exception handling and more helpful error messages
41
+ #
42
+ def initialize(username, password, site)
43
+ # This library uses the gem called 'jira-ruby' which provides the library 'jira'.
44
+ # Not to be confused with the gem called 'jira'. Be careful out there.
45
+ Pkg::Util.require_library_or_fail('jira', 'jira-ruby')
46
+
47
+ # Construct a jira client
48
+ options = self.class.jira_client_options(username, password, site)
49
+ options[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_PEER
50
+ # only get OpenSSL through the jira library so leave it out of the class method
51
+ @client = JIRA::Client.new(options)
52
+ end
53
+
54
+ def project?(project)
55
+ @client.Project.find(project)
56
+ rescue
57
+ fail "Could not find project: #{project}"
58
+ end
59
+
60
+ def user?(user)
61
+ @client.User.find(user)
62
+ rescue
63
+ fail "Could not find user: #{user}"
64
+ end
65
+
66
+ def project_name(project)
67
+ self.class.jira_project_name(@client.Project.all, project)
68
+ end
69
+
70
+ def create_issue(summary, description, project, parent, assignee)
71
+ fields = self.class.jira_issue_fields(summary, description, project,
72
+ parent, assignee)
73
+
74
+ issue = @client.Issue.build
75
+ issue.save!( {'fields' => fields } )
76
+
77
+ # fetch the issue back so we can report the key and id
78
+ issue.fetch
79
+
80
+ return issue.key, issue.id
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,16 @@
1
+ # Utility methods for handling network calls and interactions
2
+
3
+ module Pkg::Util::Net
4
+
5
+ class << self
6
+
7
+ # This simple method does an HTTP get of a URI and writes it to a file
8
+ # in a slightly more platform agnostic way than curl/wget
9
+ def fetch_uri(uri, target)
10
+ require 'open-uri'
11
+ if Pkg::Util::File.file_writable?(File.dirname(target))
12
+ File.open(target, 'w') { |f| f.puts( open(uri).read ) }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,57 @@
1
+ # Utility methods for working with rake tasks. These utilities will not work
2
+ # if the packaging repo was loaded as a library unless rake has been required
3
+ # explicitly.
4
+
5
+ module Pkg::Util::RakeUtils
6
+ class << self
7
+ def using_rake?
8
+ defined?(Rake::Task)
9
+ end
10
+
11
+ def task_defined?(task_name)
12
+ if using_rake?
13
+ Rake::Task.task_defined?(task_name)
14
+ end
15
+ end
16
+
17
+ # Return the Rake::Task object associated with a task name
18
+ #
19
+ def get_task(task_name)
20
+ if using_rake? and task_defined?(task_name)
21
+ Rake::Task[task_name]
22
+ end
23
+ end
24
+
25
+ # Add a dependency to a rake task. "depender" must be an instance of
26
+ # Rake::Task, but dependency can be either a Rake::Task instance, or a String
27
+ # referring to the name of a Rake::Task instance.
28
+ #
29
+ def add_dependency(depender, dependency)
30
+ if using_rake?
31
+ if !task_defined?(depender)
32
+ fail "Could not locate a Rake task named '#{depender.to_s}' to add a dependency of '#{dependency.to_s}' to"
33
+ elsif !task_defined?(dependency)
34
+ fail "Could not locate a Rake task named '#{dependency.to_s}' to add as a dependency of '#{depender.to_s}'"
35
+ else
36
+ depender_task = Rake::Task[depender]
37
+ depender_task.enhance([dependency])
38
+ end
39
+ end
40
+ end
41
+
42
+ # Evaluate any pre-tasks known by the configuration of this invocation.
43
+ # Again, this is quite pointless if the user has not invoked the packaging
44
+ # repo via rake, so we're just not going to do anything.
45
+ #
46
+ def evaluate_pre_tasks
47
+ if using_rake? and Pkg::Config.pre_tasks
48
+ unless Pkg::Config.pre_tasks.is_a?(Hash)
49
+ fail "The 'pre_tasks' key must be a Hash of depender => dependency pairs"
50
+ end
51
+ Pkg::Config.pre_tasks.each do |depender, dependency|
52
+ add_dependency(depender, dependency)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end