bourdain 1.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/Gemfile +11 -0
- data/Rakefile +19 -0
- data/Readme.md +1 -0
- data/TODO.md +41 -0
- data/VERSION +1 -0
- data/bin/tony +54 -0
- data/bin/tony-bump +3 -0
- data/bin/tony-check +3 -0
- data/bin/tony-generate +3 -0
- data/bourdain.gemspec +25 -0
- data/install-or-upgrade.sh +4 -0
- data/lib/bourdain/helpers/config.rb +12 -0
- data/lib/bourdain/helpers/locals.rb +17 -0
- data/lib/bourdain/helpers/logger.rb +41 -0
- data/lib/bourdain/helpers/parser.rb +76 -0
- data/lib/bourdain/helpers/registry.rb +53 -0
- data/lib/bourdain/helpers.rb +32 -0
- data/lib/bourdain/metadata.rb +19 -0
- data/lib/bourdain/resources/checks/bourdain.rb +71 -0
- data/lib/bourdain/resources/checks/chef.rb +35 -0
- data/lib/bourdain/resources/checks/cookbooks.rb +97 -0
- data/lib/bourdain/resources/checks/hooks.rb +67 -0
- data/lib/bourdain/resources/checks/ssh_config.rb +61 -0
- data/lib/bourdain/resources/checks.rb +36 -0
- data/lib/bourdain/resources/commands/bump.rb +74 -0
- data/lib/bourdain/resources/commands/check.rb +103 -0
- data/lib/bourdain/resources/commands/generate.rb +33 -0
- data/lib/bourdain/resources/commands.rb +10 -0
- data/lib/bourdain/resources/generators/attribute.rb +43 -0
- data/lib/bourdain/resources/generators/cookbook.rb +125 -0
- data/lib/bourdain/resources/generators/recipe.rb +54 -0
- data/lib/bourdain/resources/generators.rb +22 -0
- data/lib/bourdain/resources.rb +104 -0
- data/lib/bourdain.rb +3 -0
- data/templates/chef/environment.json +8 -0
- data/templates/chef/role.json +9 -0
- data/templates/cookbook/Berksfile +3 -0
- data/templates/cookbook/Readme.md +1 -0
- data/templates/cookbook/VERSION +1 -0
- data/templates/cookbook/Vagrantfile +19 -0
- data/templates/cookbook/attributes/example.rb +24 -0
- data/templates/cookbook/busser_minitest.rb +7 -0
- data/templates/cookbook/gitignore +26 -0
- data/templates/cookbook/kitchen.yml +23 -0
- data/templates/cookbook/metadata.rb +10 -0
- data/templates/cookbook/pre-commit +80 -0
- data/templates/cookbook/recipes/example.rb +38 -0
- data/test.sh +12 -0
- metadata +165 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e3811bdc20aa707f202ca15513ada539a93c825d
|
4
|
+
data.tar.gz: 8b158824deaecb5e201fa0e46d2e2cab40e8d9b2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 941638c93c4154d2911b1d4418d65ad65e7727abedc31fb4b4b469e85628e1bf0b900b9e6d69bb64112f21f8be5dedab58bee869cbb8d7a293366b1756b23089
|
7
|
+
data.tar.gz: b29f2437342970e19bd8f9b7ed53333663fef62096159d9a90474e12971476a2662e7697b5245d7b1928aa2077331b539d0b2a911d13a4718c111d129cf93db5
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
require 'yard'
|
6
|
+
YARD::Rake::YardocTask.new do |t|
|
7
|
+
t.files = %w[ --readme Readme.md lib/**/*.rb - VERSION ]
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rake/version_task'
|
11
|
+
Rake::VersionTask.new
|
12
|
+
|
13
|
+
require 'rubygems/tasks'
|
14
|
+
Gem::Tasks.new({
|
15
|
+
sign: {}
|
16
|
+
}) do |tasks|
|
17
|
+
tasks.console.command = 'pry'
|
18
|
+
end
|
19
|
+
Gem::Tasks::Sign::Checksum.new sha2: true
|
data/Readme.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Bourdain
|
data/TODO.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
~/.bourdain.json
|
2
|
+
|
3
|
+
Getting Smarter
|
4
|
+
Considers branch you're on
|
5
|
+
Considers version of branch on origin
|
6
|
+
Excludes changes in **/*.md
|
7
|
+
|
8
|
+
Default <options> are...
|
9
|
+
--help :: Show this message
|
10
|
+
--debug :: Enable debug logging
|
11
|
+
--jk :: Just explain what would happen
|
12
|
+
|
13
|
+
update [<options>]
|
14
|
+
Update the underlying Chef repo, cookbooks, and utilities
|
15
|
+
--pull :: Perform a git pull on resources (default: false)
|
16
|
+
|
17
|
+
generate user [<options>] <name>
|
18
|
+
Generate a new user data bag in the current repo
|
19
|
+
--shell <s> :: Choose a default shell (default: zsh)
|
20
|
+
--password <s> :: Provide a password for authentication
|
21
|
+
--ssh-key <s> :: Provide an SSH key for authentication %(default: intelligent)
|
22
|
+
--groups <s> :: Provide a comma-separated list of groups
|
23
|
+
--comment <s> :: Provide a comment (usually a full name)
|
24
|
+
--phone <s> :: Provide a phone or pager number
|
25
|
+
--email <s> :: Provide an email address
|
26
|
+
|
27
|
+
generate node [<options>] <name>
|
28
|
+
Generate a new node resource in the current repo
|
29
|
+
--environment <s> :: Provide an environment name
|
30
|
+
--run-list <s> :: Provide a run list string
|
31
|
+
|
32
|
+
generate file [<options>] <name> [<source>]
|
33
|
+
Generate a new file in the current cookbook
|
34
|
+
--namespace <s> :: Provide a namespace (default: default)
|
35
|
+
|
36
|
+
generate template [<options>] <name> [<source>]
|
37
|
+
Generate a new template in the current cookbook
|
38
|
+
--namespace <s> :: Provide a namespace (default: default)
|
39
|
+
|
40
|
+
generate data.?bag [<options>] [<namepace>] <name>
|
41
|
+
Generate a new data bag in the current cookbook
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.2.13
|
data/bin/tony
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'trollop'
|
3
|
+
require 'bourdain'
|
4
|
+
|
5
|
+
argv = ARGV.empty? ? [ '--help' ] : ARGV
|
6
|
+
|
7
|
+
commands = Bourdain::Registry.specs('command')
|
8
|
+
command_position = commands.map { |c| argv.index c[:name].to_s }.compact.shift
|
9
|
+
command_position = argv.length if command_position.nil?
|
10
|
+
argv_before_command = argv.slice(0, command_position)
|
11
|
+
|
12
|
+
Trollop::options(argv_before_command) do
|
13
|
+
version Bourdain::VERSION
|
14
|
+
banner Bourdain::ART + "\n\n" + <<-EOS.gsub(/^ /, '')
|
15
|
+
#{Bourdain::SUMMARY}
|
16
|
+
|
17
|
+
Usage: tony [<options>] <command>
|
18
|
+
|
19
|
+
Commands:
|
20
|
+
#{Bourdain::Registry.details('command') * "\n "}
|
21
|
+
|
22
|
+
Options:
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
|
26
|
+
command = argv.shift
|
27
|
+
Trollop::die 'No <command> provided' if command.nil?
|
28
|
+
Trollop::die 'Invalid <command> provided' if command_position.nil?
|
29
|
+
|
30
|
+
bin_dir = File.dirname(File.expand_path(__FILE__))
|
31
|
+
executable = File.join bin_dir, "tony-#{command}"
|
32
|
+
Trollop::die 'Invalid <command> provided' unless File.exists? executable
|
33
|
+
|
34
|
+
log = Bourdain::Logger.new
|
35
|
+
|
36
|
+
exec(executable, *argv) if File.exists? Bourdain::CONFIG
|
37
|
+
|
38
|
+
log.info <<-EOLOG.gsub(/^ /, '').strip
|
39
|
+
Hey, looks like you've never run Bourdain before.
|
40
|
+
|
41
|
+
Before I we can get started, you'll need to create a config file for Bourdain
|
42
|
+
at #{Bourdain::CONFIG}. It should look something like this:
|
43
|
+
EOLOG
|
44
|
+
puts
|
45
|
+
log.warn <<-EOLOG.gsub(/^ /, '').strip
|
46
|
+
{
|
47
|
+
"gitlab": {
|
48
|
+
"token": "your_gitlab_token"
|
49
|
+
}
|
50
|
+
}
|
51
|
+
EOLOG
|
52
|
+
puts
|
53
|
+
log.info 'You can find your GitLab token here: http://git.bluejeansnet.com/profile/account'
|
54
|
+
exit 1
|
data/bin/tony-bump
ADDED
data/bin/tony-check
ADDED
data/bin/tony-generate
ADDED
data/bourdain.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path(File.join('..', 'lib'), __FILE__)
|
3
|
+
require 'bourdain/metadata'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'bourdain'
|
7
|
+
s.version = Bourdain::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.author = Bourdain::AUTHOR
|
10
|
+
s.email = Bourdain::EMAIL
|
11
|
+
s.homepage = Bourdain::HOMEPAGE
|
12
|
+
s.summary = Bourdain::SUMMARY
|
13
|
+
s.description = Bourdain::SUMMARY + '.'
|
14
|
+
|
15
|
+
s.add_runtime_dependency 'pmap'
|
16
|
+
s.add_runtime_dependency 'gitlab'
|
17
|
+
s.add_runtime_dependency 'trollop'
|
18
|
+
s.add_runtime_dependency 'colorize'
|
19
|
+
s.add_runtime_dependency 'activesupport'
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File::basename(f) }
|
24
|
+
s.require_paths = %w[ lib ]
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Bourdain
|
2
|
+
module Helpers
|
3
|
+
class Locals
|
4
|
+
def initialize locals
|
5
|
+
locals.each do |name, value|
|
6
|
+
instance_variable_set "@#{name}", value
|
7
|
+
metaclass = class << self ; self ; end
|
8
|
+
metaclass.send(:define_method, name) do
|
9
|
+
instance_variable_get("@#{name}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def bind ; binding end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
require 'colorize'
|
5
|
+
|
6
|
+
|
7
|
+
module Bourdain
|
8
|
+
module Logger
|
9
|
+
SEVERITY_COLORS = {
|
10
|
+
'DEBUG' => [ :blue, :default ],
|
11
|
+
'INFO' => [ :green, :default ],
|
12
|
+
'WARN' => [ :yellow, :default ],
|
13
|
+
'ERROR' => [ :red, :default ],
|
14
|
+
'FATAL' => [ :red, :black ]
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.new level=::Logger::INFO, file=STDOUT
|
18
|
+
logger = ::Logger.new file
|
19
|
+
logger.level = level
|
20
|
+
logger.formatter = proc do |severity, datetime, _, msg|
|
21
|
+
if level == 1
|
22
|
+
msg.to_s.colorize(
|
23
|
+
color: SEVERITY_COLORS[severity.to_s][0],
|
24
|
+
background: SEVERITY_COLORS[severity.to_s][1]
|
25
|
+
) + "\n"
|
26
|
+
else
|
27
|
+
"%s [%s] %s -- %s\n".colorize(
|
28
|
+
color: SEVERITY_COLORS[severity.to_s][0],
|
29
|
+
background: SEVERITY_COLORS[severity.to_s][1]
|
30
|
+
) % [
|
31
|
+
severity,
|
32
|
+
datetime.iso8601(6),
|
33
|
+
File::basename(caller[4]),
|
34
|
+
msg
|
35
|
+
]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
return logger
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Bourdain
|
4
|
+
module Helpers
|
5
|
+
class UsageParser
|
6
|
+
def self.parse spec
|
7
|
+
lines = spec.lines.map(&:strip)
|
8
|
+
desc = lines.shift
|
9
|
+
usage = lines.shift
|
10
|
+
name = usage.split(' ').first
|
11
|
+
args = lines.select { |l| l =~ /^--/ }
|
12
|
+
resources = lines.select { |l| l =~ /^</ }
|
13
|
+
resources = resources.map { |r| r.gsub(/\W/, '') }
|
14
|
+
{
|
15
|
+
name: name,
|
16
|
+
usage: usage,
|
17
|
+
desc: desc,
|
18
|
+
resources: resources,
|
19
|
+
opts: args.map { |a| parse_arg a }
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def self.parse_arg arg_spec
|
25
|
+
matches = arg_spec.match(/^--(.*?)( \(.*?\))?( <.*?>)? :: (.*?)$/)
|
26
|
+
|
27
|
+
long = matches[1]
|
28
|
+
short = matches[2]
|
29
|
+
type = matches[3]
|
30
|
+
desc = matches[4]
|
31
|
+
|
32
|
+
short.gsub!(/[^a-z]/, '') unless short.nil?
|
33
|
+
|
34
|
+
type.gsub!(/[^a-z]/, '') unless type.nil?
|
35
|
+
|
36
|
+
type = case type
|
37
|
+
when 'i' ; :integer
|
38
|
+
when 'd' ; :double
|
39
|
+
when 'f' ; :float
|
40
|
+
when 's' ; :string
|
41
|
+
when 'o' ; :io
|
42
|
+
when nil ; nil
|
43
|
+
else raise "unkown type '#{type}'"
|
44
|
+
end
|
45
|
+
|
46
|
+
matches = desc.match(/(.*?)( \((default|required): .*?\))?$/)
|
47
|
+
unless matches.nil?
|
48
|
+
desc = matches[1]
|
49
|
+
opts = matches[2]
|
50
|
+
end
|
51
|
+
|
52
|
+
unless opts.nil?
|
53
|
+
if matches = opts.match(/default: (.*?)(,|\))/)
|
54
|
+
default = matches[1]
|
55
|
+
default = !!(default =~ /true/) unless default.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
if matches = opts.match(/required: (true|false)(,|\))/)
|
59
|
+
required = matches[1]
|
60
|
+
required = !!(required =~ /true/) unless required.nil?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
long = long.gsub('-', '_').to_sym
|
65
|
+
|
66
|
+
token = { long: long, desc: desc, opts: {} }
|
67
|
+
token[:opts][:type] = type unless type.nil?
|
68
|
+
token[:opts][:short] = short unless short.nil?
|
69
|
+
token[:opts][:default] = default unless default.nil?
|
70
|
+
token[:opts][:required] = required unless required.nil?
|
71
|
+
|
72
|
+
return token
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
|
4
|
+
module Bourdain
|
5
|
+
module Helpers
|
6
|
+
class Registry
|
7
|
+
attr_reader :name, :config
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@config = Hash.new { |default, key| default[key] = Set.new }
|
11
|
+
end
|
12
|
+
|
13
|
+
def register namespace, klass
|
14
|
+
@config[namespace].add(klass)
|
15
|
+
end
|
16
|
+
|
17
|
+
def namespace namespace
|
18
|
+
@config[namespace].to_a
|
19
|
+
end
|
20
|
+
|
21
|
+
def map namespace, &block
|
22
|
+
@config[namespace].map(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def specs namespace
|
26
|
+
@config[namespace].map do |klass|
|
27
|
+
Bourdain::Helpers::UsageParser.parse klass.raw_usage
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def klass namespace, name
|
32
|
+
@config[namespace].select do |klass|
|
33
|
+
Bourdain::Helpers::UsageParser.parse(klass.raw_usage)[:name] == name
|
34
|
+
end.shift
|
35
|
+
end
|
36
|
+
|
37
|
+
def spec namespace, name
|
38
|
+
specs(namespace).select do |spec|
|
39
|
+
spec[:name] == name
|
40
|
+
end.shift
|
41
|
+
end
|
42
|
+
|
43
|
+
def details namespace
|
44
|
+
specs = specs(namespace)
|
45
|
+
max_name_width = specs.sort_by { |s| s[:name].to_s.length }.last[:name].length
|
46
|
+
max_name_width += 2
|
47
|
+
specs.map do |spec|
|
48
|
+
"#{spec[:name].rjust(max_name_width)}: #{spec[:desc]}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
CWD = Dir.pwd
|
4
|
+
PATH = File.expand_path(__FILE__)
|
5
|
+
DIR = File.dirname(PATH)
|
6
|
+
ROOT = File.expand_path(File.join(DIR, '..', '..'))
|
7
|
+
BASE = Pathname.new(ROOT).relative_path_from(Pathname.new(CWD)).to_s
|
8
|
+
|
9
|
+
def gem_path *dir
|
10
|
+
Pathname.new(File.join(BASE, *dir)).cleanpath.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def apply_template file, opts
|
14
|
+
template_name, locals = opts[:template], opts[:locals]
|
15
|
+
locals = Bourdain::Helpers::Locals.new(locals).bind unless locals.nil?
|
16
|
+
template_path = gem_path('templates', *template_name)
|
17
|
+
template = ERB.new File.read(template_path)
|
18
|
+
contents = template.result(locals)
|
19
|
+
File.open(file, 'w') { |f| f.puts contents }
|
20
|
+
end
|
21
|
+
|
22
|
+
require_relative 'helpers/config'
|
23
|
+
require_relative 'helpers/locals'
|
24
|
+
require_relative 'helpers/logger'
|
25
|
+
require_relative 'helpers/parser'
|
26
|
+
require_relative 'helpers/registry'
|
27
|
+
|
28
|
+
module Bourdain
|
29
|
+
Config = Bourdain::Helpers::Config.new(CONFIG)
|
30
|
+
Registry = Bourdain::Helpers::Registry.new
|
31
|
+
GITLAB_HOST = 'git.bluejeansnet.com'
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bourdain
|
2
|
+
CONFIG = File.join(ENV['HOME'], '.bourdain.json')
|
3
|
+
VERSION = File.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION')).strip
|
4
|
+
SUMMARY = 'Tools for badass chefs'
|
5
|
+
AUTHOR = 'Sean Clemmer'
|
6
|
+
EMAIL = 'sclemmer@bluejeans.com'
|
7
|
+
HOMEPAGE = 'http://wiki.bluejeansnet.com/operations/bourdain'
|
8
|
+
ART = <<-'EOART' % VERSION
|
9
|
+
|
10
|
+
__ __
|
11
|
+
/\ \ /\ \ __
|
12
|
+
\ \ \____ ___ __ __ _ __ \_\ \ __ /\_\ ___
|
13
|
+
\ \ '__`\ / __`\/\ \/\ \/\`'__\/'_` \ /'__`\ \/\ \ /' _ `\
|
14
|
+
\ \ \L\ \/\ \L\ \ \ \_\ \ \ \//\ \L\ \/\ \L\.\_\ \ \/\ \/\ \
|
15
|
+
\ \_,__/\ \____/\ \____/\ \_\\ \___,_\ \__/.\_\\ \_\ \_\ \_\
|
16
|
+
\/___/ \/___/ \/___/ \/_/ \/__,_ /\/__/\/_/ \/_/\/_/\/_/
|
17
|
+
v%s
|
18
|
+
EOART
|
19
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Bourdain
|
2
|
+
module Checks
|
3
|
+
|
4
|
+
class BourdainCheck < Check
|
5
|
+
usage :check, <<-END
|
6
|
+
Check the local copy of Bourdain
|
7
|
+
bourdain
|
8
|
+
END
|
9
|
+
|
10
|
+
|
11
|
+
def initialize cookbook_config
|
12
|
+
super []
|
13
|
+
return unless require_chef!
|
14
|
+
check_bourdain!
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
private
|
20
|
+
def check_bourdain!
|
21
|
+
# Ensure we have an up-to-date copy of Bourdain
|
22
|
+
bourdain = File.join('utils', 'bourdain')
|
23
|
+
|
24
|
+
ahead_of_remote = false
|
25
|
+
unless Dir.exists? bourdain
|
26
|
+
log.warn "Hm, I don't see a copy of Bourdain. I'll fix that for you..."
|
27
|
+
%x| git clone git@git.bluejeansnet.com:chef/bourdain.git #{bourdain} |
|
28
|
+
log.info "Your copy of Bourdain is now up-to-date."
|
29
|
+
|
30
|
+
else
|
31
|
+
if youre_dirty? bourdain
|
32
|
+
log.warn "Your copy of Bourdain is dirty."
|
33
|
+
elsif youre_ahead? bourdain
|
34
|
+
log.warn "Your copy of Bourdain is ahead of the remote."
|
35
|
+
ahead_of_remote = true
|
36
|
+
elsif youre_behind? bourdain
|
37
|
+
log.warn "Hey, looks like your copy of Bourdain is out-of-date. I'll fix that for you..."
|
38
|
+
Dir.chdir(bourdain) { %x| git pull | }
|
39
|
+
log.info "Your copy of Bourdain is now up-to-date."
|
40
|
+
else
|
41
|
+
log.info "Your copy of Bourdain looks up-to-date."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
matches = File.read('Gemfile.lock').match(/bourdain \((.*?)\)$/)
|
46
|
+
|
47
|
+
if matches.nil?
|
48
|
+
log.warn "Couldn't find Kitchen hooks in your Gemfile lock. Something is amiss..."
|
49
|
+
error!
|
50
|
+
|
51
|
+
else
|
52
|
+
repo_version = matches[1].strip
|
53
|
+
local_version = File.read(File.join(bourdain, 'VERSION')).strip
|
54
|
+
|
55
|
+
if repo_version == local_version
|
56
|
+
log.info "Your Chef repo is bundled with the latest Bourdain."
|
57
|
+
elsif ahead_of_remote
|
58
|
+
# Don't worry about it, we've already warned them
|
59
|
+
elsif local_version < repo_version
|
60
|
+
log.error 'Your Chef repo is bundled with an older Bourdain. Try "bundle update".'
|
61
|
+
error!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Remove pre-commit hook if installed
|
66
|
+
pre_commit_hook = File.join(*bourdain, '.git', 'hooks', 'pre-commit')
|
67
|
+
FileUtils.rm_rf pre_commit_hook
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bourdain
|
2
|
+
module Checks
|
3
|
+
|
4
|
+
class ChefCheck < Check
|
5
|
+
usage :check, <<-END
|
6
|
+
Check the underlying Kitchen
|
7
|
+
chef
|
8
|
+
END
|
9
|
+
|
10
|
+
|
11
|
+
def initialize cookbook_config
|
12
|
+
super []
|
13
|
+
return unless require_chef!
|
14
|
+
check_chef_repo!
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
private
|
20
|
+
def check_chef_repo!
|
21
|
+
# Check if we have an up-to-date copy of the Kitchen
|
22
|
+
if youre_dirty? '.'
|
23
|
+
log.warn "Your Kitchen is dirty."
|
24
|
+
elsif youre_ahead? '.'
|
25
|
+
log.warn "Your Kitchen is ahead of the remote."
|
26
|
+
elsif youre_behind? '.'
|
27
|
+
log.error "Looks like your Kitchen is behind the remote."
|
28
|
+
error!
|
29
|
+
else
|
30
|
+
log.info "Your Kitchen looks up-to-date."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Bourdain
|
2
|
+
module Checks
|
3
|
+
|
4
|
+
class CookbooksCheck < Check
|
5
|
+
usage :check, <<-END
|
6
|
+
Check all the underlying cookbooks
|
7
|
+
cookbooks
|
8
|
+
END
|
9
|
+
|
10
|
+
|
11
|
+
def initialize cookbook_config
|
12
|
+
super []
|
13
|
+
return unless require_chef!
|
14
|
+
check_gitlab_cookbooks! cookbook_config
|
15
|
+
check_local_cookbooks! cookbook_config
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
private
|
21
|
+
def check_cookbook_freshness cookbook
|
22
|
+
notifications = []
|
23
|
+
path = cookbook[:path]
|
24
|
+
|
25
|
+
if Dir.exists? path
|
26
|
+
if youre_dirty? path
|
27
|
+
notifications.push [ path, :warn, "Your cookbook %{path} is dirty." % cookbook ]
|
28
|
+
elsif youre_ahead? path
|
29
|
+
notifications.push [ path, :warn, "Your cookbook %{path} is ahead of %{repo}." % cookbook ]
|
30
|
+
elsif youre_behind? path
|
31
|
+
notifications.push [ path, :error, "Hey, looks like your cookbook %{path} is behind %{repo}. Try pulling." % cookbook ]
|
32
|
+
error!
|
33
|
+
else
|
34
|
+
notifications.push [ path, :info, "Your cookbook %{path} looks up-to-date." % cookbook ]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
notifications
|
39
|
+
end
|
40
|
+
|
41
|
+
def check_cookbook_exists cookbook
|
42
|
+
unless Dir.exists? cookbook[:path]
|
43
|
+
log.warn "Populating cookbook %{path} with %{repo}" % cookbook
|
44
|
+
%x| git clone git@#{GITLAB_HOST}:#{cookbook[:repo]} #{cookbook[:path]} |
|
45
|
+
log.info "Your cookbook %{path} is now up-to-date." % cookbook
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def log_notifications notifications
|
50
|
+
ns = notifications.map { |n| n.first rescue nil }.compact.select { |n| !n.empty? }
|
51
|
+
ns.sort_by(&:first).each do |n|
|
52
|
+
next if n.empty?
|
53
|
+
_, severity, message = n
|
54
|
+
log.send severity, message
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def ensure_pre_commit_installed cookbook
|
59
|
+
pre_commit_hook = File.join(cookbook[:path], '.git', 'hooks', 'pre-commit')
|
60
|
+
apply_template pre_commit_hook, template: %w[ cookbook pre-commit ]
|
61
|
+
FileUtils.chmod 0755, pre_commit_hook
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
def check_gitlab_cookbooks! cookbook_configs
|
67
|
+
notifications = cookbook_configs.pmap do |cookbook|
|
68
|
+
check_cookbook_freshness cookbook
|
69
|
+
end
|
70
|
+
unless notifications.first.empty?
|
71
|
+
log_notifications notifications
|
72
|
+
end
|
73
|
+
|
74
|
+
cookbook_configs.sort_by { |cc| cc[:path] }.each do |cookbook|
|
75
|
+
check_cookbook_exists cookbook
|
76
|
+
end
|
77
|
+
|
78
|
+
cookbook_configs.each do |cookbook|
|
79
|
+
ensure_pre_commit_installed cookbook
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def check_local_cookbooks! cookbook_configs
|
85
|
+
known_cookbook_paths = cookbook_configs.map { |cc| cc[:path].sub('forks/bjn_', 'forks/') }
|
86
|
+
local_cookbook_paths = Dir[File.join('{apps,bases,forks,libs,realms}', '*')]
|
87
|
+
unknown_cookbook_paths = local_cookbook_paths - known_cookbook_paths
|
88
|
+
unless unknown_cookbook_paths.empty?
|
89
|
+
log.warn "Head's up, I see some cookbooks aren't on GitLab:"
|
90
|
+
unknown_cookbook_paths.each do |cookbook_path|
|
91
|
+
log.warn " #{cookbook_path}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|