batali 0.4.10 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +5 -0
- data/CONTRIBUTING.md +2 -2
- data/LICENSE +1 -1
- data/README.md +6 -5
- data/batali.gemspec +26 -25
- data/bin/batali +1 -0
- data/lib/batali.rb +23 -26
- data/lib/batali/b_file.rb +116 -98
- data/lib/batali/chefspec.rb +14 -16
- data/lib/batali/command.rb +32 -27
- data/lib/batali/command/cache.rb +9 -11
- data/lib/batali/command/configure.rb +1 -3
- data/lib/batali/command/display.rb +2 -4
- data/lib/batali/command/install.rb +13 -15
- data/lib/batali/command/resolve.rb +49 -51
- data/lib/batali/command/supermarket.rb +42 -45
- data/lib/batali/command/update.rb +2 -5
- data/lib/batali/config.rb +1 -2
- data/lib/batali/git.rb +10 -11
- data/lib/batali/manifest.rb +5 -6
- data/lib/batali/monkey.rb +6 -4
- data/lib/batali/origin.rb +12 -9
- data/lib/batali/origin/chef_server.rb +12 -14
- data/lib/batali/origin/git.rb +7 -9
- data/lib/batali/origin/path.rb +14 -15
- data/lib/batali/origin/remote_site.rb +17 -18
- data/lib/batali/requirement_list.rb +6 -7
- data/lib/batali/score_keeper.rb +12 -13
- data/lib/batali/source.rb +19 -21
- data/lib/batali/source/chef_server.rb +8 -10
- data/lib/batali/source/git.rb +11 -7
- data/lib/batali/source/path.rb +16 -12
- data/lib/batali/source/site.rb +23 -25
- data/lib/batali/tag_lines.rb +4 -5
- data/lib/batali/unit.rb +13 -16
- data/lib/batali/unit_loader.rb +12 -15
- data/lib/batali/utility.rb +42 -14
- data/lib/batali/version.rb +1 -1
- data/lib/chef/knife/batali_sync.rb +66 -72
- metadata +29 -16
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "batali"
|
2
|
+
require "tempfile"
|
3
|
+
require "rubygems/package"
|
4
|
+
require "zlib"
|
5
5
|
|
6
6
|
module Batali
|
7
7
|
class Command
|
@@ -10,25 +10,25 @@ module Batali
|
|
10
10
|
|
11
11
|
# Generate supermarket
|
12
12
|
def execute!
|
13
|
-
ui.info "Batali supermarket generator #{ui.color(
|
14
|
-
if
|
15
|
-
ui.warn
|
13
|
+
ui.info "Batali supermarket generator #{ui.color("started", :bold)}"
|
14
|
+
if config[:skip_install]
|
15
|
+
ui.warn "Skipping cookbook installation."
|
16
16
|
else
|
17
17
|
Install.new(config.merge(:ui => ui, :install => {}), arguments).execute!
|
18
18
|
end
|
19
|
-
run_action
|
20
|
-
FileUtils.mkdir_p(
|
19
|
+
run_action "Prepare supermarket destination directory" do
|
20
|
+
FileUtils.mkdir_p(Utility.join_path(config[:supermarket_path], "api", "v1", "cookbooks"))
|
21
21
|
FileUtils.mkdir_p(config[:assets_path])
|
22
22
|
nil
|
23
23
|
end
|
24
24
|
new_universe = new_universe_file = universe_diff = nil
|
25
|
-
run_action
|
25
|
+
run_action "Generate supermarket universe.json file" do
|
26
26
|
new_universe, new_universe_file = generate_universe
|
27
27
|
nil
|
28
28
|
end
|
29
|
-
unless
|
30
|
-
if
|
31
|
-
Dir.glob(
|
29
|
+
unless config[:universe_only]
|
30
|
+
if config[:clean_assets]
|
31
|
+
Dir.glob(Utility.join_path(config[:assets_path], "*")).each do |old_asset|
|
32
32
|
FileUtils.rm(old_asset)
|
33
33
|
end
|
34
34
|
end
|
@@ -39,16 +39,16 @@ module Batali
|
|
39
39
|
prune_universe(valid_items)
|
40
40
|
populate_universe(valid_items)
|
41
41
|
end
|
42
|
-
run_action
|
42
|
+
run_action "Write supermarket universe file" do
|
43
43
|
FileUtils.cp(
|
44
44
|
new_universe_file.path,
|
45
|
-
|
45
|
+
Utility.join_path(config[:supermarket_path], "universe")
|
46
46
|
)
|
47
|
-
FileUtils.chmod(0644,
|
47
|
+
FileUtils.chmod(0644, Utility.join_path(config[:supermarket_path], "universe"))
|
48
48
|
new_universe_file.delete
|
49
49
|
nil
|
50
50
|
end
|
51
|
-
ui.info "Batali supermarket generator #{ui.color(
|
51
|
+
ui.info "Batali supermarket generator #{ui.color("complete!", :bold, :green)}"
|
52
52
|
ui.puts " Supermarket content written to: #{config[:supermarket_path]}"
|
53
53
|
end
|
54
54
|
|
@@ -58,24 +58,24 @@ module Batali
|
|
58
58
|
base_name = "#{ckbk.name}-#{ckbk.version}.tgz"
|
59
59
|
ckbk_name = infrastructure? ? "#{ckbk.name}-#{ckbk.version}" : ckbk.name
|
60
60
|
tar_ckbk_name = "#{ckbk.name}-#{ckbk.version}"
|
61
|
-
ckbk_content_path =
|
62
|
-
ckbk_path =
|
63
|
-
unless
|
64
|
-
ckbk_io = File.open(ckbk_path,
|
61
|
+
ckbk_content_path = Utility.join_path("cookbooks", ckbk_name)
|
62
|
+
ckbk_path = Utility.join_path(config[:assets_path], base_name)
|
63
|
+
unless File.exist?(ckbk_path)
|
64
|
+
ckbk_io = File.open(ckbk_path, "wb")
|
65
65
|
gz_io = Zlib::GzipWriter.new(ckbk_io, Zlib::BEST_COMPRESSION)
|
66
66
|
begin
|
67
67
|
gz_io.mtime = Time.now
|
68
68
|
Gem::Package::TarWriter.new(gz_io) do |tar|
|
69
|
-
unless
|
69
|
+
unless File.directory?(ckbk_content_path)
|
70
70
|
raise "Cookbook path not found! Run `install`. (#{ckbk_content_path})"
|
71
71
|
end
|
72
|
-
Dir.glob(
|
72
|
+
Dir.glob(Utility.join_path(ckbk_content_path, "**", "**", "*")).each do |c_file|
|
73
73
|
next unless File.file?(c_file)
|
74
74
|
stat = File.stat(c_file)
|
75
|
-
c_path = c_file.sub(
|
75
|
+
c_path = c_file.sub(Utility.join_path(ckbk_content_path, ""), "")
|
76
76
|
tar.add_file_simple(File.join(tar_ckbk_name, c_path), stat.mode, stat.size) do |dst|
|
77
|
-
File.open(c_file,
|
78
|
-
until
|
77
|
+
File.open(c_file, "rb") do |src|
|
78
|
+
until src.eof?
|
79
79
|
dst.write src.read(4096)
|
80
80
|
end
|
81
81
|
end
|
@@ -108,35 +108,32 @@ module Batali
|
|
108
108
|
#
|
109
109
|
# @return [Smash, File] universe content hash, universe file
|
110
110
|
def generate_universe
|
111
|
+
supermarket_url = config[:remote_supermarket_url].sub(%r{/$}, "")
|
111
112
|
universe = Smash.new.tap do |uni|
|
112
113
|
manifest.cookbook.each do |ckbk|
|
113
|
-
uni.set(ckbk.name, ckbk.version.to_s,
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
)
|
128
|
-
)
|
114
|
+
uni.set(ckbk.name, ckbk.version.to_s, Smash.new(
|
115
|
+
:location_type => config[:location_type],
|
116
|
+
:location_path => [supermarket_url, "api", "v1"].join("/"),
|
117
|
+
:download_url => [
|
118
|
+
supermarket_url,
|
119
|
+
config[:download_prefix],
|
120
|
+
"#{ckbk.name}-#{ckbk.version}.tgz",
|
121
|
+
].map { |i| i.to_s.gsub(%r{(^/|/$)}, "") }.join("/"),
|
122
|
+
:dependencies => Smash[
|
123
|
+
ckbk.dependencies.map do |dep|
|
124
|
+
[dep.name, dep.requirement]
|
125
|
+
end
|
126
|
+
],
|
127
|
+
))
|
129
128
|
end
|
130
129
|
end
|
131
130
|
|
132
|
-
new_universe_file = Tempfile.new(
|
131
|
+
new_universe_file = Tempfile.new("batali-universe")
|
133
132
|
new_universe_file.puts MultiJson.dump(universe, :pretty => !!config[:pretty_universe])
|
134
133
|
new_universe_file.flush
|
135
134
|
new_universe_file.rewind
|
136
135
|
[universe, new_universe_file]
|
137
136
|
end
|
138
|
-
|
139
137
|
end
|
140
|
-
|
141
138
|
end
|
142
139
|
end
|
@@ -1,19 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "batali"
|
2
2
|
|
3
3
|
module Batali
|
4
4
|
class Command
|
5
5
|
|
6
6
|
# Update cookbook manifest
|
7
7
|
class Update < Batali::Command
|
8
|
-
|
9
8
|
def execute!
|
10
9
|
Resolve.new(config.merge(:ui => ui), arguments).execute!
|
11
|
-
if
|
10
|
+
if opts[:install]
|
12
11
|
Install.new(config.merge(:ui => ui, :install => {}), arguments).execute!
|
13
12
|
end
|
14
13
|
end
|
15
|
-
|
16
14
|
end
|
17
|
-
|
18
15
|
end
|
19
16
|
end
|
data/lib/batali/config.rb
CHANGED
data/lib/batali/git.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "git"
|
2
|
+
require "batali"
|
3
3
|
|
4
4
|
# Batali namespace
|
5
5
|
module Batali
|
@@ -8,16 +8,16 @@ module Batali
|
|
8
8
|
|
9
9
|
# @return [String] path to repository clone
|
10
10
|
def base_path
|
11
|
-
|
11
|
+
Utility.join_path(cache_path, Base64.urlsafe_encode64(url))
|
12
12
|
end
|
13
13
|
|
14
14
|
# Clone the repository to the local machine
|
15
15
|
#
|
16
16
|
# @return [TrueClass]
|
17
17
|
def clone_repository
|
18
|
-
if
|
18
|
+
if File.directory?(base_path)
|
19
19
|
repo = ::Git.open(base_path)
|
20
|
-
repo.checkout(
|
20
|
+
repo.checkout("master")
|
21
21
|
repo.pull
|
22
22
|
repo.fetch
|
23
23
|
else
|
@@ -33,13 +33,13 @@ module Batali
|
|
33
33
|
def ref_dup
|
34
34
|
git = ::Git.open(base_path)
|
35
35
|
git.checkout(ref)
|
36
|
-
git.pull(
|
36
|
+
git.pull("origin", ref)
|
37
37
|
self.ref = git.log.first.sha
|
38
|
-
self.path =
|
39
|
-
unless
|
38
|
+
self.path = Utility.join_path(cache_path, "git", ref)
|
39
|
+
unless File.directory?(path)
|
40
40
|
FileUtils.mkdir_p(path)
|
41
|
-
FileUtils.cp_r(
|
42
|
-
FileUtils.rm_rf(
|
41
|
+
FileUtils.cp_r(Utility.join_path(base_path, "."), path)
|
42
|
+
FileUtils.rm_rf(Utility.join_path(path, ".git"))
|
43
43
|
end
|
44
44
|
path
|
45
45
|
end
|
@@ -51,6 +51,5 @@ module Batali
|
|
51
51
|
attribute :ref, String, :required => true, :equivalent => true
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
55
54
|
end
|
56
55
|
end
|
data/lib/batali/manifest.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
require
|
1
|
+
require "batali"
|
2
2
|
|
3
3
|
module Batali
|
4
4
|
# Collection of resolved units
|
5
5
|
class Manifest < Utility
|
6
|
-
|
7
6
|
include Bogo::Memoization
|
8
7
|
|
9
8
|
attribute :path, String
|
10
9
|
attribute :infrastructure, [TrueClass, FalseClass]
|
11
|
-
attribute :cookbook, Batali::Unit, :multiple => true, :coerce => lambda{|v| Batali::Unit.new(v)}, :default => []
|
10
|
+
attribute :cookbook, Batali::Unit, :multiple => true, :coerce => lambda { |v| Batali::Unit.new(v) }, :default => []
|
12
11
|
|
13
12
|
# Build manifest from given path. If no file exists, empty
|
14
13
|
# manifest will be provided.
|
@@ -16,7 +15,8 @@ module Batali
|
|
16
15
|
# @param path [String] path to manifest
|
17
16
|
# @return [Manifest]
|
18
17
|
def self.build(path)
|
19
|
-
|
18
|
+
path = Utility.join_path(path)
|
19
|
+
if File.exist?(path)
|
20
20
|
new(Bogo::Config.new(path).data.merge(:path => path))
|
21
21
|
else
|
22
22
|
new(:path => path)
|
@@ -29,7 +29,7 @@ module Batali
|
|
29
29
|
# @return [TrueClass, FalseClass]
|
30
30
|
def include?(unit)
|
31
31
|
memoize(unit.inspect) do
|
32
|
-
if
|
32
|
+
if cookbook
|
33
33
|
!!cookbook.detect do |ckbk|
|
34
34
|
ckbk.name == unit.name &&
|
35
35
|
ckbk.version == unit.version
|
@@ -39,6 +39,5 @@ module Batali
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
43
42
|
end
|
44
43
|
end
|
data/lib/batali/monkey.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
require
|
1
|
+
require "bogo/http_proxy"
|
2
2
|
|
3
3
|
# Batali namespace
|
4
4
|
module Batali
|
5
5
|
# Custom named unit version
|
6
6
|
class UnitVersion < Grimoire::VERSION_CLASS; end
|
7
|
+
|
7
8
|
# Custom named unit requirement
|
8
9
|
class UnitRequirement < Grimoire::REQUIREMENT_CLASS; end
|
10
|
+
|
9
11
|
# Custom named unit dependency
|
10
12
|
class UnitDependency < Grimoire::DEPENDENCY_CLASS
|
11
13
|
# Override to properly convert to JSON
|
@@ -13,12 +15,12 @@ module Batali
|
|
13
15
|
result = [
|
14
16
|
name,
|
15
17
|
*requirement.requirements.map do |req|
|
16
|
-
req.join(
|
17
|
-
end
|
18
|
+
req.join(" ")
|
19
|
+
end,
|
18
20
|
]
|
19
21
|
# Prevent stupid conversion errors of
|
20
22
|
# JSON::Ext::Generator::State into Hash
|
21
|
-
args.map!{|v| v.respond_to?(:to_h) ? v.to_h : v}
|
23
|
+
args.map! { |v| v.respond_to?(:to_h) ? v.to_h : v }
|
22
24
|
MultiJson.dump(result, *args)
|
23
25
|
end
|
24
26
|
end
|
data/lib/batali/origin.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
|
-
require
|
1
|
+
require "batali"
|
2
2
|
|
3
|
-
module
|
3
|
+
module Batali
|
4
4
|
# Cookbook source origin
|
5
5
|
class Origin < Utility
|
6
|
-
|
7
|
-
autoload :
|
8
|
-
autoload :
|
9
|
-
autoload :
|
10
|
-
autoload :Path, 'batali/origin/path'
|
6
|
+
autoload :ChefServer, "batali/origin/chef_server"
|
7
|
+
autoload :RemoteSite, "batali/origin/remote_site"
|
8
|
+
autoload :Git, "batali/origin/git"
|
9
|
+
autoload :Path, "batali/origin/path"
|
11
10
|
|
12
11
|
attribute :name, String, :required => true
|
13
12
|
attribute :cache_path, String, :required => true
|
14
13
|
attribute :identifier, String
|
15
14
|
|
15
|
+
def initialize(*_, &block)
|
16
|
+
super
|
17
|
+
self.cache_path = Utility.clean_path(cache_path)
|
18
|
+
end
|
19
|
+
|
16
20
|
# @return [Array<Unit>] all units
|
17
21
|
def units
|
18
|
-
raise NotImplementedError.new
|
22
|
+
raise NotImplementedError.new "Abstract class"
|
19
23
|
end
|
20
|
-
|
21
24
|
end
|
22
25
|
end
|
@@ -1,14 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "batali"
|
2
|
+
require "digest/sha2"
|
3
|
+
require "securerandom"
|
4
|
+
require "http"
|
5
|
+
require "fileutils"
|
6
6
|
|
7
7
|
module Batali
|
8
8
|
class Origin
|
9
9
|
# Fetch unit information from chef server
|
10
10
|
class ChefServer < Origin
|
11
|
-
|
12
11
|
include Bogo::Memoization
|
13
12
|
include Utility::Chef
|
14
13
|
|
@@ -19,7 +18,7 @@ module Batali
|
|
19
18
|
super
|
20
19
|
init_chef!
|
21
20
|
self.identifier = Digest::SHA256.hexdigest(endpoint)
|
22
|
-
unless
|
21
|
+
unless name?
|
23
22
|
self.name = identifier
|
24
23
|
end
|
25
24
|
end
|
@@ -28,13 +27,13 @@ module Batali
|
|
28
27
|
def units
|
29
28
|
memoize(:units) do
|
30
29
|
debug "Fetching units from chef server: #{endpoint}"
|
31
|
-
units = api_service.get_rest(
|
32
|
-
meta[
|
33
|
-
"#{c_name}/#{info[
|
30
|
+
units = api_service.get_rest("cookbooks?num_versions=all").map do |c_name, meta|
|
31
|
+
meta["versions"].map do |info|
|
32
|
+
"#{c_name}/#{info["version"]}"
|
34
33
|
end
|
35
34
|
end.flatten.map do |ckbk|
|
36
35
|
debug "Unit information from #{endpoint}: #{ckbk.inspect}"
|
37
|
-
c_name, c_version = ckbk.split(
|
36
|
+
c_name, c_version = ckbk.split("/", 2)
|
38
37
|
c_deps = api_service.get_rest(
|
39
38
|
"cookbooks/#{c_name}/#{c_version}"
|
40
39
|
).metadata.dependencies.to_a
|
@@ -49,13 +48,12 @@ module Batali
|
|
49
48
|
:endpoint => endpoint,
|
50
49
|
:client_key => client_key,
|
51
50
|
:client_name => client_name,
|
52
|
-
:cache_path => cache_path
|
53
|
-
)
|
51
|
+
:cache_path => cache_path,
|
52
|
+
),
|
54
53
|
)
|
55
54
|
end.flatten
|
56
55
|
end
|
57
56
|
end
|
58
|
-
|
59
57
|
end
|
60
58
|
end
|
61
59
|
end
|
data/lib/batali/origin/git.rb
CHANGED
@@ -1,23 +1,22 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "git"
|
2
|
+
require "batali"
|
3
3
|
|
4
4
|
module Batali
|
5
5
|
class Origin
|
6
6
|
# Fetch unit from local path
|
7
7
|
class Git < Path
|
8
|
-
|
9
8
|
include Batali::Git
|
10
9
|
attribute :path, String, :required => false
|
11
10
|
attribute :subdirectory, String
|
12
11
|
|
13
|
-
def initialize(args={})
|
12
|
+
def initialize(args = {})
|
14
13
|
super
|
15
14
|
self.identifier = Smash.new(
|
16
15
|
:url => url,
|
17
16
|
:ref => ref,
|
18
|
-
:subdirectory => subdirectory
|
17
|
+
:subdirectory => subdirectory,
|
19
18
|
).checksum
|
20
|
-
unless
|
19
|
+
unless name?
|
21
20
|
self.name = identifier
|
22
21
|
end
|
23
22
|
end
|
@@ -30,7 +29,7 @@ module Batali
|
|
30
29
|
:url => url,
|
31
30
|
:ref => ref,
|
32
31
|
:subdirectory => subdirectory,
|
33
|
-
:cache_path => cache_path
|
32
|
+
:cache_path => cache_path,
|
34
33
|
)
|
35
34
|
items
|
36
35
|
end
|
@@ -40,7 +39,7 @@ module Batali
|
|
40
39
|
def load_metadata
|
41
40
|
fetch_repo
|
42
41
|
original_path = path.dup
|
43
|
-
self.path =
|
42
|
+
self.path = Utility.path_join(*[path, subdirectory].compact)
|
44
43
|
result = super
|
45
44
|
self.path = original_path
|
46
45
|
result
|
@@ -53,7 +52,6 @@ module Batali
|
|
53
52
|
ref_dup
|
54
53
|
end
|
55
54
|
end
|
56
|
-
|
57
55
|
end
|
58
56
|
end
|
59
57
|
end
|