batali 0.3.14 → 0.4.0
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 +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +25 -0
- data/bin/batali +20 -0
- data/lib/batali/command/supermarket.rb +141 -0
- data/lib/batali/command.rb +1 -0
- data/lib/batali/origin/remote_site.rb +3 -2
- data/lib/batali/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0415b35e7fad280740b21548ef140b5c12f98c96
|
4
|
+
data.tar.gz: 4afcc45cb368ebf1c156f0b9d96aa0f33ebb0ce1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 567206dc928b7c3040bafe757ac18565a932c822f0d8d4301ec611035c01bcf773f4b982c52c7b2333432c8f5bebd9e45027e406c6bc1aef99736f8323a5e0d1
|
7
|
+
data.tar.gz: 9ecde47ac49072af4a436a39b11a465f43785482980e60f74dbd51c16c6aa33127709da278f604f58c87f565222311e81e0f30493ba123a55e00614a18cfd23d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -425,6 +425,31 @@ within the `batali.manifest` file. If cookbooks are defined within the
|
|
425
425
|
`batali.manifest` file that have not been uploaded to the Chef server, those
|
426
426
|
cookbooks will be uploaded.
|
427
427
|
|
428
|
+
## Supermarket
|
429
|
+
|
430
|
+
Batali can generate a static supermarket repository from a `batali.manifest`. The resultant
|
431
|
+
directory can then be hosted with an httpd of choice. To generate a supermarket repository,
|
432
|
+
first run `resolve`:
|
433
|
+
|
434
|
+
```
|
435
|
+
$ batali resolve
|
436
|
+
```
|
437
|
+
|
438
|
+
Next, run the `supermarket` command to generate the repository:
|
439
|
+
|
440
|
+
```
|
441
|
+
$ batali supermarket
|
442
|
+
```
|
443
|
+
|
444
|
+
A new directory will be created (`./supermarket`) which contains the newly generated
|
445
|
+
supermarket respository. The generated `universe` file will contain URLs pointing
|
446
|
+
to `localhost`, which is the default behavior. In practice, it will be desirable to
|
447
|
+
update the URL to provide the customized location:
|
448
|
+
|
449
|
+
```
|
450
|
+
$ batali supermarket --remote-supermarket-url="http://supermarket.example.com"
|
451
|
+
```
|
452
|
+
|
428
453
|
# Info
|
429
454
|
|
430
455
|
* Repository: https://github.com/hw-labs/batali
|
data/bin/batali
CHANGED
@@ -80,4 +80,24 @@ Bogo::Cli::Setup.define do
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
+
command 'supermarket' do
|
84
|
+
description 'Generate a supermarket'
|
85
|
+
self.instance_exec(&global_opts)
|
86
|
+
on :p, 'path=', 'Cookbook install path'
|
87
|
+
on :I, 'infrastructure', 'Resolve infrastructure cookbooks'
|
88
|
+
on :s, 'skip-install', 'Skip cookbook installation'
|
89
|
+
on :S, 'supermarket-path=', 'Supermarket output directory', :default => 'supermarket'
|
90
|
+
on :A, 'assets-path=', 'Supermarket assets storage path', :default => File.join('supermarket', 'assets')
|
91
|
+
on :R, 'remote-supermarket-url=', 'Custom remote supermarket URL (https://myhost.com:443/supermarket)', :default => 'http://localhost'
|
92
|
+
on :D, 'download-prefix=', 'Remote location prefixed to asset name', :default => '/assets'
|
93
|
+
on :T, 'location-type=', 'Name of location type', :default => 'batali'
|
94
|
+
on :P, 'pretty-universe', 'Output formatted universe JSON'
|
95
|
+
on :U, 'universe-only', 'Only generate the supermarket universe.json file'
|
96
|
+
on :C, 'clean-assets', 'Replace any existing compressed assets'
|
97
|
+
|
98
|
+
run do |opts, args|
|
99
|
+
Batali::Command::Supermarket.new(opts, args).execute!
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
83
103
|
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'batali'
|
2
|
+
require 'rubygems/package'
|
3
|
+
require 'zlib'
|
4
|
+
|
5
|
+
module Batali
|
6
|
+
class Command
|
7
|
+
# Generate a supermarket
|
8
|
+
class Supermarket < Batali::Command
|
9
|
+
|
10
|
+
# Generate supermarket
|
11
|
+
def execute!
|
12
|
+
ui.info "Batali supermarket generator #{ui.color('started', :bold)}"
|
13
|
+
if(config[:skip_install])
|
14
|
+
ui.warn 'Skipping cookbook installation.'
|
15
|
+
else
|
16
|
+
Install.new(config.merge(:ui => ui, :install => {}), arguments).execute!
|
17
|
+
end
|
18
|
+
run_action 'Prepare supermarket destination directory' do
|
19
|
+
FileUtils.mkdir_p(File.join(config[:supermarket_path], 'api', 'v1', 'cookbooks'))
|
20
|
+
FileUtils.mkdir_p(config[:assets_path])
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
new_universe = new_universe_file = universe_diff = nil
|
24
|
+
run_action 'Generate supermarket universe.json file' do
|
25
|
+
new_universe, new_universe_file = generate_universe
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
unless(config[:universe_only])
|
29
|
+
if(config[:clean_assets])
|
30
|
+
Dir.glob(File.join(config[:assets_path], '*')).each do |old_asset|
|
31
|
+
FileUtils.rm(old_asset)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
new_assets = generate_cookbook_assets
|
35
|
+
valid_items = new_universe.values.map(&:values).flatten.map do |info|
|
36
|
+
File.basename(info[:download_url])
|
37
|
+
end
|
38
|
+
prune_universe(valid_items)
|
39
|
+
populate_universe(valid_items)
|
40
|
+
end
|
41
|
+
run_action 'Write supermarket universe file' do
|
42
|
+
FileUtils.cp(
|
43
|
+
new_universe_file.path,
|
44
|
+
File.join(config[:supermarket_path], 'universe')
|
45
|
+
)
|
46
|
+
FileUtils.chmod(0644, File.join(config[:supermarket_path], 'universe'))
|
47
|
+
new_universe_file.delete
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
ui.info "Batali supermarket generator #{ui.color('complete!', :bold, :green)}"
|
51
|
+
ui.puts " Supermarket content written to: #{config[:supermarket_path]}"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Generate compressed cookbook assets
|
55
|
+
def generate_cookbook_assets
|
56
|
+
manifest.cookbook.map do |ckbk|
|
57
|
+
base_name = "#{ckbk.name}-#{ckbk.version}.tgz"
|
58
|
+
ckbk_name = infrastructure? ? "#{ckbk.name}-#{ckbk.version}" : ckbk.name
|
59
|
+
tar_ckbk_name = "#{ckbk.name}-#{ckbk.version}"
|
60
|
+
ckbk_content_path = File.join('cookbooks', ckbk_name)
|
61
|
+
ckbk_path = File.join(config[:assets_path], base_name)
|
62
|
+
unless(File.exist?(ckbk_path))
|
63
|
+
ckbk_io = File.open(ckbk_path, 'wb')
|
64
|
+
gz_io = Zlib::GzipWriter.new(ckbk_io, Zlib::BEST_COMPRESSION)
|
65
|
+
begin
|
66
|
+
gz_io.mtime = Time.now
|
67
|
+
Gem::Package::TarWriter.new(gz_io) do |tar|
|
68
|
+
unless(File.directory?(ckbk_content_path))
|
69
|
+
raise "Cookbook path not found! Run `install`. (#{ckbk_content_path})"
|
70
|
+
end
|
71
|
+
Dir.glob(File.join(ckbk_content_path, '**', '**', '*')).each do |c_file|
|
72
|
+
next unless File.file?(c_file)
|
73
|
+
stat = File.stat(c_file)
|
74
|
+
c_path = c_file.sub(File.join(ckbk_content_path, ''), '')
|
75
|
+
tar.add_file_simple(File.join(tar_ckbk_name, c_path), stat.mode, stat.size) do |dst|
|
76
|
+
File.open(c_file, 'rb') do |src|
|
77
|
+
until(src.eof?)
|
78
|
+
dst.write src.read(4096)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
ensure
|
85
|
+
gz_io.close
|
86
|
+
end
|
87
|
+
base_name
|
88
|
+
end
|
89
|
+
end.compact
|
90
|
+
end
|
91
|
+
|
92
|
+
# Prune assets from universe
|
93
|
+
#
|
94
|
+
# @param items [Array<String>] names of assets
|
95
|
+
# TODO: This is a stub for custom action
|
96
|
+
def prune_universe(items)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Add assets to universe
|
100
|
+
#
|
101
|
+
# @param items [Array<String>] names of assets
|
102
|
+
# TODO: This is a stub for custom action
|
103
|
+
def populate_universe(items)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Generate the supermarket universe.json file
|
107
|
+
#
|
108
|
+
# @return [Smash, File] universe content hash, universe file
|
109
|
+
def generate_universe
|
110
|
+
universe = Smash.new.tap do |uni|
|
111
|
+
manifest.cookbook.each do |ckbk|
|
112
|
+
uni.set(ckbk.name, ckbk.version.to_s,
|
113
|
+
Smash.new(
|
114
|
+
:location_type => config[:location_type],
|
115
|
+
:location_path => File.join(config[:remote_supermarket_url], 'api', 'v1'),
|
116
|
+
:download_url => File.join(
|
117
|
+
config[:remote_supermarket_url],
|
118
|
+
config[:download_prefix],
|
119
|
+
"#{ckbk.name}-#{ckbk.version}.tgz"
|
120
|
+
),
|
121
|
+
:dependencies => Smash[
|
122
|
+
ckbk.dependencies.map do |dep|
|
123
|
+
[dep.name, dep.requirement]
|
124
|
+
end
|
125
|
+
]
|
126
|
+
)
|
127
|
+
)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
new_universe_file = Tempfile.new('batali-universe')
|
132
|
+
new_universe_file.puts MultiJson.dump(universe, :pretty => !!config[:pretty_universe])
|
133
|
+
new_universe_file.flush
|
134
|
+
new_universe_file.rewind
|
135
|
+
[universe, new_universe_file]
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
data/lib/batali/command.rb
CHANGED
@@ -14,6 +14,7 @@ module Batali
|
|
14
14
|
autoload :Display, 'batali/command/display'
|
15
15
|
autoload :Install, 'batali/command/install'
|
16
16
|
autoload :Resolve, 'batali/command/resolve'
|
17
|
+
autoload :Supermarket, 'batali/command/supermarket'
|
17
18
|
autoload :Update, 'batali/command/update'
|
18
19
|
|
19
20
|
# Set UI when loading via command
|
@@ -10,7 +10,7 @@ module Batali
|
|
10
10
|
class RemoteSite < Origin
|
11
11
|
|
12
12
|
# Site suffix for API endpoint
|
13
|
-
|
13
|
+
API_SUFFIX = 'api/v1/'
|
14
14
|
|
15
15
|
include Bogo::Memoization
|
16
16
|
|
@@ -22,7 +22,8 @@ module Batali
|
|
22
22
|
|
23
23
|
def initialize(*_)
|
24
24
|
super
|
25
|
-
|
25
|
+
# NOTE: We currently don't require API_SUFFIX information
|
26
|
+
# self.endpoint = URI.join(endpoint, API_SUFFIX).to_s
|
26
27
|
self.identifier = Digest::SHA256.hexdigest(endpoint)
|
27
28
|
unless(name?)
|
28
29
|
self.name = identifier
|
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.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: attribute_struct
|
@@ -220,6 +220,7 @@ files:
|
|
220
220
|
- lib/batali/command/display.rb
|
221
221
|
- lib/batali/command/install.rb
|
222
222
|
- lib/batali/command/resolve.rb
|
223
|
+
- lib/batali/command/supermarket.rb
|
223
224
|
- lib/batali/command/update.rb
|
224
225
|
- lib/batali/config.rb
|
225
226
|
- lib/batali/git.rb
|