5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/onceover/octocatalog/diff/cli.rb', line 5
def self.command
@cmd ||= Cri::Command.define do
name 'diff'
usage 'diff'
summary "Diff two versions of the controlrepo's compiled catalogs"
description <<-DESCRIPTION
This uses octocatalog-diff to run diffs on all things in the test matrix
instead of actually testing them. Requires two branches, tags or
revisions to compare between.
DESCRIPTION
option :f, :from, 'branch to compare from', argument: :required
option :t, :to, 'branch to compare to', argument: :required
run do |opts, args, cmd|
require 'facter'
require 'colored'
repo = Onceover::Controlrepo.new(opts)
test_config = Onceover::TestConfig.new(repo.onceover_yaml, opts)
num_threads = (Facter.value('processors')['count'] / 2)
tests = test_config.run_filters(Onceover::Test.deduplicate(test_config.spec_tests))
@queue = tests.inject(Queue.new, :push)
@results = []
@threads = Array.new(num_threads) do
Thread.new do
r10k_cache_dir = Dir.mktmpdir('r10k_cache')
r10k_config = {
'cachedir' => r10k_cache_dir,
}
logger.debug "Creating r10k cache for thread at #{r10k_cache_dir}"
File.write("#{r10k_cache_dir}/r10k.yaml",r10k_config.to_yaml)
until @queue.empty?
test = @queue.shift
logger.info "Preparing environment for #{test.classes[0].name} on #{test.nodes[0].name}"
logger.debug "Creating temp directory"
tempdir = Dir.mktmpdir(test.to_s)
logger.debug "Temp directory created at #{tempdir}"
logger.debug "Copying controlrepo to #{tempdir}"
FileUtils.copy_entry(repo.root,tempdir)
logger.debug "Deploying vendored factsets"
deduped_factsets = repo.facts_files.reverse.inject({}) do |hash, file|
hash[File.basename(file)] = file
hash
end
deduped_factsets.each do |basename,path|
facts = JSON.load(File.read(path))
File.open("#{tempdir}/spec/factsets/#{File.basename(path,'.*')}.yaml", 'w') { |f| f.write facts.to_yaml }
end
if File.directory?("#{r10k_cache_dir}/modules")
logger.debug "Copying modules from thread cache to #{tempdir}"
FileUtils.copy_entry("#{r10k_cache_dir}/modules","#{tempdir}/modules")
end
logger.info "Deploying Puppetfile for #{test.classes[0].name} on #{test.nodes[0].name}"
r10k_cmd = "r10k puppetfile install --verbose --color --puppetfile #{repo.puppetfile} --config #{r10k_cache_dir}/r10k.yaml"
Open3.popen3(r10k_cmd, :chdir => tempdir) do |stdin, stdout, stderr, wait_thr|
exit_status = wait_thr.value
if exit_status.exitstatus != 0
STDOUT.puts stdout.read
STDERR.puts stderr.read
abort "R10k encountered an error, see the logs for details"
end
end
logger.debug "Creating before script that overwrites site.pp"
class_name = test.classes[0].name
template_dir = File.expand_path('../../../../templates',File.dirname(__FILE__))
template = File.read(File.expand_path("./change_manifest.rb.erb",template_dir))
File.write("#{tempdir}/bootstrap_script.rb",ERB.new(template, nil, '-').result(binding))
FileUtils.chmod("u=rwx","#{tempdir}/bootstrap_script.rb")
logger.debug "Getting Puppet binary"
binary = `which puppet`.chomp
logger.debug "Running Octocatalog diff"
logger.info "Compiling catalogs for #{test.classes[0].name} on #{test.nodes[0].name}"
command_prefix = ENV['BUNDLE_GEMFILE'] ? 'bundle exec ' : ''
command_args = [
'--fact-file',
"#{tempdir}/spec/factsets/#{test.nodes[0].name}.yaml",
'--from',
opts[:from],
'--to',
opts[:to],
'--basedir',
tempdir,
'--puppet-binary',
binary,
'--bootstrap-script',
"'#{tempdir}/bootstrap_script.rb'",
'--hiera-config',
repo.hiera_config_file,
'--pass-env-vars',
ENV.keys.keep_if {|k| k =~ /^RUBY|^BUNDLE/ }.join(',')
]
cmd = "#{command_prefix}octocatalog-diff #{command_args.join(' ')}"
logger.debug "Running: #{cmd}"
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
exit_status = wait_thr.value
@results << {
stdout: stdout.read,
stderr: stderr.read,
exit_status: exit_status.exitstatus,
test: test
}
end
logger.info "Storing results for #{test.classes[0].name} on #{test.nodes[0].name}"
logger.debug "Backing up modules to thread cache #{tempdir}"
FileUtils.mv("#{tempdir}/modules","#{r10k_cache_dir}/modules",:force => true)
logger.debug "Removing temporary build cache"
FileUtils.rm_r(tempdir)
end
FileUtils.rm_r(r10k_cache_dir)
end
end
@threads.each(&:join)
@results.each do |result|
puts "#{"Test:".bold} #{result[:test].classes[0].name} on #{result[:test].nodes[0].name}"
puts "#{"Exit:".bold} #{result[:exit_status]}"
puts "#{"Status:".bold} #{"changes".yellow}" if result[:exit_status] == 2
puts "#{"Status:".bold} #{"no differences".green}" if result[:exit_status] == 0
puts "#{"Status:".bold} #{"failed".red}" if result[:exit_status] == 1
puts "#{"Results:".bold}\n#{result[:stdout]}\n" if result[:exit_status] == 2
puts "#{"Errors:".bold}\n#{result[:stderr]}\n" if result[:exit_status] == 1
puts ""
end
end
end
end
|