batali 0.2.12 → 0.2.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +20 -0
- data/batali.gemspec +1 -0
- data/lib/batali/b_file.rb +17 -1
- data/lib/batali/origin/chef_server.rb +60 -0
- data/lib/batali/origin.rb +1 -0
- data/lib/batali/source/chef_server.rb +86 -0
- data/lib/batali/source.rb +1 -0
- data/lib/batali/unit_loader.rb +1 -1
- data/lib/batali/utility.rb +58 -0
- data/lib/batali/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a858775a739465f30069ecf5ce22dee5b8e1a24
|
4
|
+
data.tar.gz: 59eb2bf5517829257bbdd9d2b9afacca2633fded
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebd131450fdb5ba57f570f89795663f912c44237b04609576ed44890ffbe54623e8b65fcbb3b355ddb98d2c4c95c8bcf82c7c7244b3ca987b56d6741a40671dc
|
7
|
+
data.tar.gz: 4e2daaec6765cd360e821978e717e50b45cc98a3badf9b30e66952508da359e16729f927827f777ba9b7f8b7c8bc3c35c887402ffabcf961c612b228f8747742
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
![Batali](img/batali-logo.png)
|
2
|
+
|
1
3
|
# Batali
|
2
4
|
|
3
5
|
Batali is a light weight cookbook resolver. It is now in
|
@@ -50,6 +52,7 @@ Currently supported "origins":
|
|
50
52
|
* RemoteSite
|
51
53
|
* Path
|
52
54
|
* Git
|
55
|
+
* ChefServer
|
53
56
|
|
54
57
|
#### RemoteSite
|
55
58
|
|
@@ -67,6 +70,23 @@ source 'https://supermarket.chef.io', :name => 'opscode'
|
|
67
70
|
source 'https://cookbooks.example.com', :name => 'example'
|
68
71
|
```
|
69
72
|
|
73
|
+
##### ChefServer
|
74
|
+
|
75
|
+
This is a Chef Server endpoint:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
chef_server 'https://chef-server.example.com'
|
79
|
+
```
|
80
|
+
|
81
|
+
It will use the `node_name` and `client_key` defined within the
|
82
|
+
`.chef/knife.rb` configuration by default. To use the Chef Server
|
83
|
+
URL defined within the configuration, just declare it with no
|
84
|
+
arguments:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
chef_server
|
88
|
+
```
|
89
|
+
|
70
90
|
##### Path
|
71
91
|
|
72
92
|
Paths are defined via cookbook entries:
|
data/batali.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_runtime_dependency 'git'
|
22
22
|
s.add_development_dependency 'minitest'
|
23
23
|
s.add_development_dependency 'pry'
|
24
|
+
s.add_development_dependency 'chef'
|
24
25
|
s.executables << 'batali'
|
25
26
|
s.files = Dir['{lib,bin}/**/**/*'] + %w(batali.gemspec README.md CHANGELOG.md CONTRIBUTING.md LICENSE)
|
26
27
|
end
|
data/lib/batali/b_file.rb
CHANGED
@@ -22,6 +22,15 @@ module Batali
|
|
22
22
|
self
|
23
23
|
end
|
24
24
|
|
25
|
+
def chef_server(*args)
|
26
|
+
unless(self[:chef_server])
|
27
|
+
set!(:chef_server, ::AttributeStruct::CollapseArray.new.push(args))
|
28
|
+
else
|
29
|
+
self[:chef_server].push(args)
|
30
|
+
end
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
25
34
|
def restrict(*args)
|
26
35
|
unless(self[:restrict])
|
27
36
|
set!(:restrict, ::AttributeStruct::CollapseArray.new.push(args))
|
@@ -88,13 +97,20 @@ module Batali
|
|
88
97
|
attribute :restrict, Restriction, :multiple => true, :coerce => lambda{|v|
|
89
98
|
Restriction.new(:cookbook => v.first, :source => v.last.to_smash[:source])
|
90
99
|
}
|
91
|
-
attribute :source, Origin::RemoteSite, :multiple => true, :coerce => lambda{|v|
|
100
|
+
attribute :source, Origin::RemoteSite, :multiple => true, :default => [], :coerce => lambda{|v|
|
92
101
|
args = Smash.new(:endpoint => v.first)
|
93
102
|
if(v.last.is_a?(Hash))
|
94
103
|
args.merge!(v.last)
|
95
104
|
end
|
96
105
|
Origin::RemoteSite.new(args)
|
97
106
|
}
|
107
|
+
attribute :chef_server, Origin::ChefServer, :multiple => true, :default => [], :coerce => lambda{|v|
|
108
|
+
args = Smash.new(:endpoint => v.first)
|
109
|
+
if(v.last.is_a?(Hash))
|
110
|
+
args.merge!(v.last)
|
111
|
+
end
|
112
|
+
Origin::ChefServer.new(args)
|
113
|
+
}
|
98
114
|
attribute :group, Group, :multiple => true, :coerce => lambda{|v| Group.new()}
|
99
115
|
attribute :cookbook, Cookbook, :multiple => true, :coerce => BFile.cookbook_coerce, :default => []
|
100
116
|
attribute :metadata, Cookbook, :coerce => lambda{ |v, b_file|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'batali'
|
2
|
+
require 'digest/sha2'
|
3
|
+
require 'securerandom'
|
4
|
+
require 'http'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module Batali
|
8
|
+
class Origin
|
9
|
+
# Fetch unit information from chef server
|
10
|
+
class ChefServer < Origin
|
11
|
+
|
12
|
+
include Bogo::Memoization
|
13
|
+
include Utility::Chef
|
14
|
+
|
15
|
+
attribute :name, String
|
16
|
+
attribute :identifier, String
|
17
|
+
|
18
|
+
def initialize(*_)
|
19
|
+
super
|
20
|
+
init_chef!
|
21
|
+
self.identifier = Digest::SHA256.hexdigest(endpoint)
|
22
|
+
unless(name?)
|
23
|
+
self.name = self.identifier
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Array<Unit>] all units
|
28
|
+
def units
|
29
|
+
memoize(:units) do
|
30
|
+
debug "Fetching units from chef server: #{endpoint}"
|
31
|
+
units = api_service.get_rest('cookbooks?num_versions=all').map do |c_name, meta|
|
32
|
+
meta['versions'].map do |info|
|
33
|
+
"#{c_name}/#{info['version']}"
|
34
|
+
end
|
35
|
+
end.flatten.map do |ckbk|
|
36
|
+
debug "Unit information from #{endpoint}: #{ckbk.inspect}"
|
37
|
+
c_name, c_version = ckbk.split('/', 2)
|
38
|
+
c_deps = api_service.get_rest(
|
39
|
+
"cookbooks/#{c_name}/#{c_version}"
|
40
|
+
).metadata.dependencies.to_a
|
41
|
+
Unit.new(
|
42
|
+
:name => c_name,
|
43
|
+
:version => c_version,
|
44
|
+
:dependencies => c_deps,
|
45
|
+
:source => Smash.new(
|
46
|
+
:type => :chef_server,
|
47
|
+
:version => c_version,
|
48
|
+
:dependencies => c_deps,
|
49
|
+
:endpoint => endpoint,
|
50
|
+
:client_key => client_key,
|
51
|
+
:client_name => client_name
|
52
|
+
)
|
53
|
+
)
|
54
|
+
end.flatten
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/batali/origin.rb
CHANGED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'batali'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
module Batali
|
5
|
+
class Source
|
6
|
+
# Chef Server based source
|
7
|
+
class ChefServer < Source
|
8
|
+
|
9
|
+
include Bogo::Memoization
|
10
|
+
include Utility::Chef
|
11
|
+
|
12
|
+
# @return [Array<Hash>] dependency strings
|
13
|
+
attr_reader :dependencies
|
14
|
+
# @return [String] local cache path
|
15
|
+
attr_accessor :cache
|
16
|
+
# @return [string] unique identifier
|
17
|
+
attr_reader :identifier
|
18
|
+
|
19
|
+
attribute :version, String, :required => true, :equivalent => true
|
20
|
+
|
21
|
+
# Extract extra info before allowing super to load data
|
22
|
+
#
|
23
|
+
# @param args [Hash]
|
24
|
+
# @return [self]
|
25
|
+
def initialize(args={})
|
26
|
+
@deps = args.delete(:dependencies) || {}
|
27
|
+
super
|
28
|
+
init_chef!
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Chef::Rest]
|
32
|
+
def api_service
|
33
|
+
memoize(:api_service) do
|
34
|
+
Chef::Rest.new(endpoint)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [String]
|
39
|
+
def unit_version
|
40
|
+
version
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Array<Array<name, constraints>>]
|
44
|
+
def unit_dependencies
|
45
|
+
deps.to_a
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [String] path to cache
|
49
|
+
def cache_directory
|
50
|
+
memoize(:cache_directory) do
|
51
|
+
unless(@cache)
|
52
|
+
@cache = File.join(Dir.home, '.batali/cache/chef_server', endpoint)
|
53
|
+
end
|
54
|
+
cache
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [String] directory
|
59
|
+
def asset
|
60
|
+
path = File.join(cache_directory, name, version)
|
61
|
+
begin
|
62
|
+
FileUtils.mkdir_p(path)
|
63
|
+
cookbook = rest.get_rest("cookbooks/#{name}/#{version}")
|
64
|
+
manifest = cookbook.manifest
|
65
|
+
Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segement|
|
66
|
+
if(manifest.has_key?(segment))
|
67
|
+
manifest[segement].each do |s_file|
|
68
|
+
new_path = File.join(path, s_file['path'].gsub('/', File::SEPARATOR))
|
69
|
+
FileUtils.mkdir_p(File.dirname(new_path))
|
70
|
+
api_service.sign_on_redirect = false
|
71
|
+
t_file = api_service.get_rest(s_file['url'], true)
|
72
|
+
FilUtils.mv(t_file.path, new_path)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
rescue => e
|
77
|
+
debug "Failed to fully download cookbook [#{name}<#{version}>] - #{e.class}: #{e}"
|
78
|
+
FileUtils.rm_rf(path)
|
79
|
+
raise
|
80
|
+
end
|
81
|
+
path
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/batali/source.rb
CHANGED
data/lib/batali/unit_loader.rb
CHANGED
@@ -15,7 +15,7 @@ module Batali
|
|
15
15
|
# @return [self]
|
16
16
|
def populate!
|
17
17
|
memoize(:populate) do
|
18
|
-
file.source.each do |src|
|
18
|
+
(file.source + file.chef_server).each do |src|
|
19
19
|
src.units.find_all do |unit|
|
20
20
|
if(restrictions[unit.name])
|
21
21
|
restrictions[unit.name] == src.identifier
|
data/lib/batali/utility.rb
CHANGED
@@ -3,5 +3,63 @@ require 'batali'
|
|
3
3
|
module Batali
|
4
4
|
class Utility < Grimoire::Utility
|
5
5
|
|
6
|
+
# Helper module for enabling chef server support
|
7
|
+
module Chef
|
8
|
+
|
9
|
+
# Provide common required attribute
|
10
|
+
def self.included(klass)
|
11
|
+
klass.class_eval do
|
12
|
+
attribute :client_name, String
|
13
|
+
attribute :client_key, String
|
14
|
+
attribute :endpoint, String
|
15
|
+
attr_accessor :c_name
|
16
|
+
attr_accessor :c_key
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Load and configure chef
|
21
|
+
def init_chef!
|
22
|
+
debug 'Loading chef into the runtime'
|
23
|
+
begin
|
24
|
+
require 'chef'
|
25
|
+
debug 'Successfully loaded chef into the runtime'
|
26
|
+
rescue LoadError => e
|
27
|
+
debug "Failed to load the chef gem: #{e.class}: #{e}"
|
28
|
+
raise 'The `chef` gem was not found. Please `gem install chef` or add `chef` to your bundle.'
|
29
|
+
end
|
30
|
+
Smash.new(
|
31
|
+
:endpoint => :chef_server_url,
|
32
|
+
:c_name => :node_name,
|
33
|
+
:c_key => :client_key
|
34
|
+
).each do |local_attr, config_key|
|
35
|
+
unless(self.send(local_attr))
|
36
|
+
memoize(:knife_configure, :global) do
|
37
|
+
require 'chef/knife'
|
38
|
+
::Chef::Knife.new.configure_chef
|
39
|
+
end
|
40
|
+
debug "Settting #{config_key} from knife configuration file for #{self.class} <#{endpoint}>"
|
41
|
+
self.send("#{local_attr}=", ::Chef::Config[config_key])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
c_name ||= client_name
|
45
|
+
c_key ||= client_key
|
46
|
+
end
|
47
|
+
|
48
|
+
# Make request to api service
|
49
|
+
#
|
50
|
+
# @yieldparam service [Chef::Rest]
|
51
|
+
# @return [Object] result
|
52
|
+
def api_service
|
53
|
+
memoize(:api_service) do
|
54
|
+
::Chef::REST.new(
|
55
|
+
endpoint,
|
56
|
+
c_name,
|
57
|
+
c_key
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
6
64
|
end
|
7
65
|
end
|
data/lib/batali/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: batali
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: attribute_struct
|
@@ -164,6 +164,20 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: chef
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
167
181
|
description: Magic
|
168
182
|
email: code@chrisroberts.org
|
169
183
|
executables:
|
@@ -190,12 +204,14 @@ files:
|
|
190
204
|
- lib/batali/manifest.rb
|
191
205
|
- lib/batali/monkey.rb
|
192
206
|
- lib/batali/origin.rb
|
207
|
+
- lib/batali/origin/chef_server.rb
|
193
208
|
- lib/batali/origin/git.rb
|
194
209
|
- lib/batali/origin/path.rb
|
195
210
|
- lib/batali/origin/remote_site.rb
|
196
211
|
- lib/batali/requirement_list.rb
|
197
212
|
- lib/batali/score_keeper.rb
|
198
213
|
- lib/batali/source.rb
|
214
|
+
- lib/batali/source/chef_server.rb
|
199
215
|
- lib/batali/source/git.rb
|
200
216
|
- lib/batali/source/path.rb
|
201
217
|
- lib/batali/source/site.rb
|