Class: Onceover::CLI::Run::Diff

Inherits:
Object
  • Object
show all
Defined in:
lib/onceover/octocatalog/diff/cli.rb

Class Method Summary collapse

Class Method Details

.commandObject



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 "This uses octocatalog-diff to run diffs on all things in the test matrix\ninstead of actually testing them. Requires two branches, tags or\nrevisions to compare between.\n    DESCRIPTION\n\n    option :f,  :from, 'branch to compare from', argument: :required\n    option :t,  :to,   'branch to compare to', argument: :required\n\n    run do |opts, args, cmd|\n      require 'facter'\n      require 'colored'\n\n      #TODO: Allow for custom arguments\n      repo        = Onceover::Controlrepo.new(opts)\n      test_config = Onceover::TestConfig.new(repo.onceover_yaml, opts)\n      num_threads = (Facter.value('processors')['count'] / 2)\n      tests = test_config.run_filters(Onceover::Test.deduplicate(test_config.spec_tests))\n\n      @queue = tests.inject(Queue.new, :push)\n      @results = []\n\n      @threads = Array.new(num_threads) do\n        Thread.new do\n          r10k_cache_dir = Dir.mktmpdir('r10k_cache')\n          r10k_config = {\n            'cachedir' => r10k_cache_dir,\n          }\n          logger.debug \"Creating r10k cache for thread at \#{r10k_cache_dir}\"\n          File.write(\"\#{r10k_cache_dir}/r10k.yaml\",r10k_config.to_yaml)\n\n          until @queue.empty?\n            test = @queue.shift\n\n            logger.info \"Preparing environment for \#{test.classes[0].name} on \#{test.nodes[0].name}\"\n            logger.debug \"Creating temp directory\"\n            tempdir = Dir.mktmpdir(test.to_s)\n            logger.debug \"Temp directory created at \#{tempdir}\"\n\n            logger.debug \"Copying controlrepo to \#{tempdir}\"\n            FileUtils.copy_entry(repo.root,tempdir)\n\n            # Copy all of the factsets over in reverse order so that\n            # local ones override vendored ones\n            logger.debug \"Deploying vendored factsets\"\n            deduped_factsets = repo.facts_files.reverse.inject({}) do |hash, file|\n              hash[File.basename(file)] = file\n              hash\n            end\n\n            deduped_factsets.each do |basename,path|\n              facts = JSON.load(File.read(path))\n              File.open(\"\#{tempdir}/spec/factsets/\#{File.basename(path,'.*')}.yaml\", 'w') { |f| f.write facts.to_yaml }\n            end\n\n            if File.directory?(\"\#{r10k_cache_dir}/modules\")\n              logger.debug \"Copying modules from thread cache to \#{tempdir}\"\n              FileUtils.copy_entry(\"\#{r10k_cache_dir}/modules\",\"\#{tempdir}/modules\")\n            end\n\n            logger.info \"Deploying Puppetfile for \#{test.classes[0].name} on \#{test.nodes[0].name}\"\n            r10k_cmd = \"r10k puppetfile install --verbose --color --puppetfile \#{repo.puppetfile} --config \#{r10k_cache_dir}/r10k.yaml\"\n            Open3.popen3(r10k_cmd, :chdir => tempdir) do |stdin, stdout, stderr, wait_thr|\n              exit_status = wait_thr.value\n              if exit_status.exitstatus != 0\n                STDOUT.puts stdout.read\n                STDERR.puts stderr.read\n                abort \"R10k encountered an error, see the logs for details\"\n              end\n            end\n\n            # TODO: Improve the way this works so that it doesn't blat site.pp\n            logger.debug \"Creating before script that overwrites site.pp\"\n            class_name = test.classes[0].name\n            template_dir = File.expand_path('../../../../templates',File.dirname(__FILE__))\n            template = File.read(File.expand_path(\"./change_manifest.rb.erb\",template_dir))\n            File.write(\"\#{tempdir}/bootstrap_script.rb\",ERB.new(template, nil, '-').result(binding))\n            FileUtils.chmod(\"u=rwx\",\"\#{tempdir}/bootstrap_script.rb\")\n\n            logger.debug \"Getting Puppet binary\"\n            binary = `which puppet`.chomp\n\n            logger.debug \"Running Octocatalog diff\"\n            logger.info \"Compiling catalogs for \#{test.classes[0].name} on \#{test.nodes[0].name}\"\n\n            command_prefix = ENV['BUNDLE_GEMFILE'] ? 'bundle exec ' : ''\n\n            command_args = [\n              '--fact-file',\n              \"\#{tempdir}/spec/factsets/\#{test.nodes[0].name}.yaml\",\n              '--from',\n              opts[:from],\n              '--to',\n              opts[:to],\n              '--basedir',\n              tempdir,\n              '--puppet-binary',\n              binary,\n              '--bootstrap-script',\n              \"'\#{tempdir}/bootstrap_script.rb'\",\n              '--hiera-config',\n              repo.hiera_config_file,\n              '--pass-env-vars',\n              ENV.keys.keep_if {|k| k =~ /^RUBY|^BUNDLE/ }.join(',')\n            ]\n\n            cmd = \"\#{command_prefix}octocatalog-diff \#{command_args.join(' ')}\"\n            logger.debug \"Running: \#{cmd}\"\n            Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|\n              exit_status = wait_thr.value\n              @results << {\n                stdout: stdout.read,\n                stderr: stderr.read,\n                exit_status: exit_status.exitstatus,\n                test: test\n              }\n            end\n            logger.info \"Storing results for \#{test.classes[0].name} on \#{test.nodes[0].name}\"\n\n            logger.debug \"Backing up modules to thread cache \#{tempdir}\"\n            FileUtils.mv(\"\#{tempdir}/modules\",\"\#{r10k_cache_dir}/modules\",:force => true)\n\n            logger.debug \"Removing temporary build cache\"\n            FileUtils.rm_r(tempdir)\n          end\n\n          FileUtils.rm_r(r10k_cache_dir)\n        end\n      end\n\n      @threads.each(&:join)\n      @results.each do |result|\n        puts \"\#{\"Test:\".bold} \#{result[:test].classes[0].name} on \#{result[:test].nodes[0].name}\"\n        puts \"\#{\"Exit:\".bold} \#{result[:exit_status]}\"\n        puts \"\#{\"Status:\".bold} \#{\"changes\".yellow}\" if result[:exit_status] == 2\n        puts \"\#{\"Status:\".bold} \#{\"no differences\".green}\" if result[:exit_status] == 0\n        puts \"\#{\"Status:\".bold} \#{\"failed\".red}\" if result[:exit_status] == 1\n        puts \"\#{\"Results:\".bold}\\n\#{result[:stdout]}\\n\" if result[:exit_status] == 2\n        puts \"\#{\"Errors:\".bold}\\n\#{result[:stderr]}\\n\" if result[:exit_status] == 1\n        puts \"\"\n      end\n    end\n  end\nend\n"