vagabond 0.2.0 → 0.2.2
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.
- data/CHANGELOG.md +18 -0
- data/README.md +125 -4
- data/bin/vagabond +43 -16
- data/lib/vagabond/actions/cluster.rb +66 -0
- data/lib/vagabond/actions/create.rb +12 -7
- data/lib/vagabond/actions/destroy.rb +69 -15
- data/lib/vagabond/actions/init.rb +75 -0
- data/lib/vagabond/actions/provision.rb +4 -2
- data/lib/vagabond/actions/status.rb +33 -22
- data/lib/vagabond/actions/up.rb +8 -1
- data/lib/vagabond/bootstraps/server-zero.erb +20 -0
- data/lib/vagabond/bootstraps/server.erb +3 -2
- data/lib/vagabond/constants.rb +0 -15
- data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +16 -0
- data/lib/vagabond/cookbooks/lxc/Gemfile +3 -2
- data/lib/vagabond/cookbooks/lxc/Gemfile.lock +30 -121
- data/lib/vagabond/cookbooks/lxc/README.md +43 -14
- data/lib/vagabond/cookbooks/lxc/attributes/default.rb +3 -3
- data/lib/vagabond/cookbooks/lxc/files/default/lxc-awesome-ephemeral +499 -0
- data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +223 -58
- data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +3 -0
- data/lib/vagabond/cookbooks/lxc/libraries/monkey.rb +51 -0
- data/lib/vagabond/cookbooks/lxc/metadata.rb +6 -5
- data/lib/vagabond/cookbooks/lxc/providers/config.rb +9 -16
- data/lib/vagabond/cookbooks/lxc/providers/container.rb +241 -229
- data/lib/vagabond/cookbooks/lxc/providers/default.rb +57 -0
- data/lib/vagabond/cookbooks/lxc/providers/ephemeral.rb +40 -0
- data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +13 -54
- data/lib/vagabond/cookbooks/lxc/providers/interface.rb +13 -67
- data/lib/vagabond/cookbooks/lxc/providers/service.rb +14 -14
- data/lib/vagabond/cookbooks/lxc/recipes/default.rb +17 -4
- data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +1 -1
- data/lib/vagabond/cookbooks/lxc/resources/config.rb +2 -2
- data/lib/vagabond/cookbooks/lxc/resources/container.rb +31 -6
- data/lib/vagabond/cookbooks/lxc/resources/default.rb +12 -0
- data/lib/vagabond/cookbooks/lxc/resources/ephemeral.rb +13 -0
- data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +2 -1
- data/lib/vagabond/cookbooks/lxc/resources/interface.rb +6 -3
- data/lib/vagabond/cookbooks/lxc/resources/service.rb +1 -1
- data/lib/vagabond/cookbooks/lxc/templates/default/file_content.erb +2 -0
- data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +9 -3
- data/lib/vagabond/cookbooks/vagabond/README.md +10 -0
- data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +1 -0
- data/lib/vagabond/cookbooks/vagabond/files/default/lxc-centos +13 -6
- data/lib/vagabond/cookbooks/vagabond/metadata.rb +1 -0
- data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +46 -4
- data/lib/vagabond/cookbooks/vagabond/recipes/zero.rb +9 -0
- data/lib/vagabond/errors.rb +23 -0
- data/lib/vagabond/helpers.rb +41 -14
- data/lib/vagabond/internal_configuration.rb +120 -27
- data/lib/vagabond/kitchen.rb +143 -63
- data/lib/vagabond/knife.rb +8 -5
- data/lib/vagabond/layout.rb +16 -0
- data/lib/vagabond/monkey/kitchen_config.rb +23 -0
- data/lib/vagabond/server.rb +79 -63
- data/lib/vagabond/spec.rb +345 -0
- data/lib/vagabond/uploader.rb +30 -0
- data/lib/vagabond/uploader/berkshelf.rb +53 -0
- data/lib/vagabond/uploader/knife.rb +24 -0
- data/lib/vagabond/uploader/librarian.rb +31 -0
- data/lib/vagabond/vagabond.rb +30 -11
- data/lib/vagabond/vagabondfile.rb +40 -5
- data/lib/vagabond/version.rb +1 -1
- data/vagabond.gemspec +5 -2
- metadata +75 -15
- data/lib/vagabond/cookbooks/lxc/resources/#container.rb# +0 -28
- data/lib/vagabond/cookbooks/lxc/test/kitchen/Kitchenfile +0 -7
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/metadata.rb +0 -2
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/centos_lxc.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/chef-bootstrap.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_files.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_templates.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/ubuntu_lxc.rb +0 -0
@@ -0,0 +1,345 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require File.join(File.dirname(__FILE__), 'cookbooks/lxc/libraries/lxc.rb')
|
3
|
+
|
4
|
+
%w(layout vagabond server helpers vagabondfile internal_configuration actions/status).each do |dep|
|
5
|
+
require "vagabond/#{dep}"
|
6
|
+
end
|
7
|
+
|
8
|
+
module Vagabond
|
9
|
+
class Spec < Thor
|
10
|
+
|
11
|
+
include Thor::Actions
|
12
|
+
include Helpers
|
13
|
+
include Actions::Status
|
14
|
+
|
15
|
+
attr_accessor :layout
|
16
|
+
|
17
|
+
self.class_exec(&Vagabond::CLI_OPTIONS)
|
18
|
+
|
19
|
+
def self.basename
|
20
|
+
'vagabond spec'
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(*args)
|
24
|
+
@name = nil
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
method_option(:irl,
|
29
|
+
:type => :boolean,
|
30
|
+
:default => false,
|
31
|
+
:desc => 'Test In Real Life'
|
32
|
+
)
|
33
|
+
method_option(:environment,
|
34
|
+
:type => :string,
|
35
|
+
:desc => 'Specify environment to restrict node detection'
|
36
|
+
)
|
37
|
+
method_option(:auto_destroy,
|
38
|
+
:type => :boolean,
|
39
|
+
:desc => 'Automatically destroy created nodes after spec tests (not valid with --irl)',
|
40
|
+
:default => true
|
41
|
+
)
|
42
|
+
desc 'start [CLUSTER]', 'Run specs for cluster'
|
43
|
+
def start(cluster=nil)
|
44
|
+
@options = options.dup
|
45
|
+
setup_ui(nil, :no_class_set)
|
46
|
+
error = nil
|
47
|
+
begin
|
48
|
+
if(options[:irl])
|
49
|
+
irl_spec(cluster)
|
50
|
+
else
|
51
|
+
cluster_spec(cluster)
|
52
|
+
end
|
53
|
+
rescue => error
|
54
|
+
ensure
|
55
|
+
cluster_destroy(cluster) if options[:auto_destroy] && !options[:irl]
|
56
|
+
result = error ? ui.color('FAILED', :red, :bold) : ui.color('PASSED', :green, :bold)
|
57
|
+
ui.info "--> Specs for cluster #{cluster}: #{result}"
|
58
|
+
raise VagabondError::SpecFailed.new(error) if error
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
method_option(:node,
|
63
|
+
:type => :string,
|
64
|
+
:desc => 'Destroy named node within cluster cluster'
|
65
|
+
)
|
66
|
+
desc 'destroy NAME', 'Destroy the given cluster/node'
|
67
|
+
def destroy(cluster)
|
68
|
+
base_setup
|
69
|
+
options[:node] ? node_destroy(cluster, options[:node]) : cluster_destroy(cluster)
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'status [NAME]', 'Show status of existing nodes'
|
73
|
+
def status(name=nil)
|
74
|
+
base_setup
|
75
|
+
_status
|
76
|
+
end
|
77
|
+
|
78
|
+
desc 'init', 'Initalize spec configuration'
|
79
|
+
def init
|
80
|
+
setup_ui(nil, :no_class_set)
|
81
|
+
ui.info "Initializing spec configuration..."
|
82
|
+
make_spec_directory
|
83
|
+
populate_spec_directory
|
84
|
+
# - dump empty layout
|
85
|
+
ui.info " -> #{ui.color('COMPLETE!', :green)}"
|
86
|
+
end
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
90
|
+
def cluster_destroy(cluster)
|
91
|
+
ui.info "#{ui.color('Destroying cluster:', :bold)} #{ui.color(cluster, :red)}"
|
92
|
+
Array(internal_config[:spec_clusters][cluster]).each do |n|
|
93
|
+
node_destroy(cluster, n)
|
94
|
+
end
|
95
|
+
ui.info ui.color(" --> Cluster #{cluster} DESTROYED", :red)
|
96
|
+
end
|
97
|
+
|
98
|
+
def node_destroy(cluster, node_name)
|
99
|
+
v_n = vagabond_instance(:destroy, :cluster => cluster, :name => node_name)
|
100
|
+
v_n.send(:execute)
|
101
|
+
remove_node_from_cluster(cluster, node_name)
|
102
|
+
end
|
103
|
+
|
104
|
+
def make_spec_directory
|
105
|
+
%w(role recipe).each do |leaf|
|
106
|
+
FileUtils.mkdir_p(File.join(spec_directory, leaf))
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def spec_directory
|
111
|
+
File.join(vagabondfile.directory, 'spec')
|
112
|
+
end
|
113
|
+
|
114
|
+
def populate_spec_directory
|
115
|
+
write_default_file('Layout')
|
116
|
+
write_default_file('spec_helper.rb')
|
117
|
+
end
|
118
|
+
|
119
|
+
def write_default_file(file)
|
120
|
+
write = true
|
121
|
+
if(File.exists?(path = File.join(spec_directory, file)))
|
122
|
+
answer = ''
|
123
|
+
until(%w(y n).include?(answer))
|
124
|
+
answer = ui.ask_question("Overwrite existing #{file} ", :default => 'y').downcase
|
125
|
+
end
|
126
|
+
write = answer == 'y'
|
127
|
+
end
|
128
|
+
if(write)
|
129
|
+
File.open(path, 'w') do |file|
|
130
|
+
file.write self.class.const_get("CONTENT_DEFAULT_#{File.basename(path).upcase.sub(%r{\..*$}, '')}")
|
131
|
+
end
|
132
|
+
ui.info "New file has been written: #{file}"
|
133
|
+
else
|
134
|
+
ui.warn "Skipping file: #{file}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def mappings_key
|
139
|
+
:spec_mappings
|
140
|
+
end
|
141
|
+
|
142
|
+
def irl_spec(cluster)
|
143
|
+
if(cluster && load_layout[cluster])
|
144
|
+
valid_runlists = layout[:clusters][cluster][:nodes]
|
145
|
+
# Runlists composed of role AND/OR recipe
|
146
|
+
valid_runlists.each do |r_l|
|
147
|
+
runlist = r_l.map{|r| Chef::RunList::RunListItem.new(r)}
|
148
|
+
roles = runlist.find_all do |i|
|
149
|
+
i.role?
|
150
|
+
end
|
151
|
+
recipes = runlist.find_all do |i|
|
152
|
+
i.recipe?
|
153
|
+
end
|
154
|
+
terms = roles.map{|r| "role:#{r.name}"} + recipes.map{|r| "recipes:#{r.name}"}
|
155
|
+
query = terms.join(' AND ')
|
156
|
+
if(options[:environment])
|
157
|
+
query = "chef_environment:#{options[:environment]} AND (#{query})"
|
158
|
+
end
|
159
|
+
search(:node, query).each do |node|
|
160
|
+
n_r = node.run_list.map(&:to_s)
|
161
|
+
next unless n_r.size == r_l.size && (n_r - r_l).empty?
|
162
|
+
test_node!(node.name, node.ipaddress, node.run_list)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
else
|
166
|
+
query = %w(*:*)
|
167
|
+
if(options[:environment])
|
168
|
+
query << "chef_environment:#{options[:environment]}"
|
169
|
+
end
|
170
|
+
Chef::Search::Query.new(:node, query.join(' AND ')) do |nodes|
|
171
|
+
nodes.each do |node|
|
172
|
+
test_node!(node.name, node.ipaddress, node.run_list)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def vagabondfile
|
179
|
+
unless(@vagabondfile)
|
180
|
+
@vagabondfile = Vagabondfile.new(options[:vagabond_file])
|
181
|
+
end
|
182
|
+
@vagabondfile
|
183
|
+
end
|
184
|
+
|
185
|
+
def cluster_spec(cluster)
|
186
|
+
@options[:auto_provision] = true
|
187
|
+
options[:sudo] = sudo
|
188
|
+
Lxc.use_sudo = vagabondfile[:sudo].nil? ? true : vagabondfile[:sudo]
|
189
|
+
@internal_config = InternalConfiguration.new(vagabondfile, nil, options)
|
190
|
+
# First, setup server
|
191
|
+
if(vagabondfile[:local_chef_server][:enabled])
|
192
|
+
require 'vagabond/server'
|
193
|
+
srv = ::Vagabond::Server.new
|
194
|
+
srv.send(:setup, 'up')
|
195
|
+
srv.send(:execute)
|
196
|
+
end
|
197
|
+
|
198
|
+
load_layout
|
199
|
+
default_config = Chef::Mixin::DeepMerge.merge(
|
200
|
+
Mash.new(:platform => 'ubuntu_1204'), layout[:defaults]
|
201
|
+
)
|
202
|
+
test_nodes = []
|
203
|
+
layout[:clusters][cluster][:nodes].each_with_index do |node, index|
|
204
|
+
config = Chef::Mixin::DeepMerge.merge(default_config, layout[:definitions][node])
|
205
|
+
config = Chef::Mixin::DeepMerge.merge(config, layout[:clusters][cluster][:overrides] || {})
|
206
|
+
v_n = vagabond_instance(:up,
|
207
|
+
:platform => config[:platform],
|
208
|
+
:cluster => cluster,
|
209
|
+
:base_name => "s-#{node}-#{index}"
|
210
|
+
)
|
211
|
+
v_n.config = Chef::Mixin::DeepMerge.merge(v_n.config, config)
|
212
|
+
v_n.send(:execute)
|
213
|
+
test_nodes << [v_n.name, v_n.lxc.name, config]
|
214
|
+
end
|
215
|
+
test_nodes.each do |node|
|
216
|
+
name, lxc_name, config = node
|
217
|
+
lxc = Lxc.new(lxc_name)
|
218
|
+
test_node!(name, lxc.container_ip, config[:run_list])
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_node!(name, ip_address, run_list)
|
223
|
+
run_list.each do |item|
|
224
|
+
r_item = item.is_a?(Chef::RunList::RunListItem) ? item : Chef::RunList::RunListItem.new(item)
|
225
|
+
dir = File.join(File.dirname(vagabondfile.path), "spec/#{r_item.type}/#{r_item.name.sub('::', '/')}")
|
226
|
+
dir << '/default' if r_item.type.to_sym == :recipe && !r_item.name.include?('::')
|
227
|
+
Dir.glob(File.join(dir, '*.rb')).each do |path|
|
228
|
+
com = "#{sudo}VAGABOND_TEST_HOST='#{ip_address}' rspec #{path}"
|
229
|
+
debug(com)
|
230
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => STDOUT, :env => {'VAGABOND_TEST_HOST' => ip_address})
|
231
|
+
cmd.run_command
|
232
|
+
cmd.error!
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def load_layout
|
238
|
+
# Load up layouts and set defaults
|
239
|
+
@layout = Layout.new(File.dirname(vagabondfile.path))
|
240
|
+
end
|
241
|
+
|
242
|
+
def vagabond_instance(action, args={})
|
243
|
+
@options[:disable_name_validate] = true
|
244
|
+
v = Vagabond.new
|
245
|
+
v.options = @options
|
246
|
+
v.send(:setup, action, args[:name] || generated_name(args[:base_name]),
|
247
|
+
:ui => ui,
|
248
|
+
:template => args[:platform],
|
249
|
+
:disable_name_validate => true,
|
250
|
+
:ui => ui
|
251
|
+
)
|
252
|
+
if(args[:platform])
|
253
|
+
v.internal_config.force_bases = args[:platform]
|
254
|
+
v.internal_config.ensure_state
|
255
|
+
end
|
256
|
+
v.mappings_key = :spec_mappings
|
257
|
+
v.config = Mash.new(
|
258
|
+
:template => args[:platform],
|
259
|
+
:run_list => args[:run_list]
|
260
|
+
)
|
261
|
+
v.lxc = Lxc.new(
|
262
|
+
v.internal_config[v.mappings_key][v.name]
|
263
|
+
) if v.internal_config[v.mappings_key][v.name]
|
264
|
+
add_node_to_cluster(v.name, args[:cluster])
|
265
|
+
v
|
266
|
+
end
|
267
|
+
|
268
|
+
def _status
|
269
|
+
status = []
|
270
|
+
if(name)
|
271
|
+
clusters = [name]
|
272
|
+
else
|
273
|
+
load_layout
|
274
|
+
clusters = layout[:clusters].keys.sort
|
275
|
+
end
|
276
|
+
clusters.each do |cluster|
|
277
|
+
ui.info "#{ui.color('Status of spec cluster:', :bold)} #{ui.color(cluster, :yellow)}"
|
278
|
+
status = [
|
279
|
+
ui.color('Name', :bold),
|
280
|
+
ui.color('State', :bold),
|
281
|
+
ui.color('PID', :bold),
|
282
|
+
ui.color('IP', :bold)
|
283
|
+
]
|
284
|
+
Array(internal_config[:spec_clusters][cluster]).sort.each do |n|
|
285
|
+
status += status_for(n)
|
286
|
+
end
|
287
|
+
puts ui.list(status, :uneven_columns_across, 4)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def add_node_to_cluster(node_name, cluster)
|
292
|
+
internal_config[:spec_clusters][cluster] ||= []
|
293
|
+
internal_config[:spec_clusters][cluster] |= [node_name]
|
294
|
+
internal_config.save
|
295
|
+
end
|
296
|
+
|
297
|
+
def remove_node_from_cluster(cluster, node_name)
|
298
|
+
internal_config[:spec_clusters][cluster] ||= []
|
299
|
+
internal_config[:spec_clusters][cluster] -= [node_name]
|
300
|
+
internal_config[mappings_key].delete(node_name)
|
301
|
+
internal_config.save
|
302
|
+
end
|
303
|
+
|
304
|
+
CONTENT_DEFAULT_LAYOUT = <<-EOF
|
305
|
+
{
|
306
|
+
:defaults => {
|
307
|
+
:platform => 'ubuntu_1204',
|
308
|
+
:environment => nil
|
309
|
+
},
|
310
|
+
:definitions => {
|
311
|
+
:example_node => {
|
312
|
+
:run_list => %w(role[example])
|
313
|
+
}
|
314
|
+
},
|
315
|
+
:clusters => {
|
316
|
+
:example_cluster => {
|
317
|
+
:nodes => ['example_node']
|
318
|
+
}
|
319
|
+
}
|
320
|
+
}
|
321
|
+
EOF
|
322
|
+
CONTENT_DEFAULT_SPEC_HELPER = <<-EOF
|
323
|
+
require 'serverspec'
|
324
|
+
require 'pathname'
|
325
|
+
require 'net/ssh'
|
326
|
+
|
327
|
+
include Serverspec::Helper::Ssh
|
328
|
+
|
329
|
+
RSpec.configure do |c|
|
330
|
+
c.before do
|
331
|
+
host = ENV['VAGABOND_TEST_HOST']
|
332
|
+
if(c.host != host)
|
333
|
+
c.ssh.close if c.ssh
|
334
|
+
c.host = host
|
335
|
+
options = Net::SSH::Config.for(c.host)
|
336
|
+
c.ssh = Net::SSH.start(c.host, 'root', options.update(:keys => ['/opt/hw-lxc-config/id_rsa']))
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
EOF
|
341
|
+
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Dir.new(File.join(File.dirname(__FILE__), 'uploader')).each do |file|
|
2
|
+
next if file.start_with?('.') || !file.end_with?('.rb')
|
3
|
+
require "vagabond/uploader/#{file}"
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'vagabond/helpers'
|
7
|
+
|
8
|
+
module Vagabond
|
9
|
+
class Uploader
|
10
|
+
|
11
|
+
attr_reader :store
|
12
|
+
attr_reader :options
|
13
|
+
attr_reader :ui
|
14
|
+
|
15
|
+
include Helpers
|
16
|
+
|
17
|
+
def initialize(base_directory, options={})
|
18
|
+
@store = base_directory
|
19
|
+
@options = Mash.new(options)
|
20
|
+
@ui = options[:ui]
|
21
|
+
end
|
22
|
+
|
23
|
+
def prepare
|
24
|
+
end
|
25
|
+
|
26
|
+
def upload
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'vagabond/uploader/berkshelf'
|
2
|
+
|
3
|
+
module Vagabond
|
4
|
+
class Uploader
|
5
|
+
class Berkshelf < Uploader
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
super
|
9
|
+
%w(berksfile chef_server_url).each do |k|
|
10
|
+
unless(options[k])
|
11
|
+
raise ArgumentError.new "Option '#{k}' must be provided!"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def prepare
|
17
|
+
path = File.join(store, 'berks.json')
|
18
|
+
if(File.exists?(path))
|
19
|
+
cur = Mash.new(JSON.load(File.read(path)))
|
20
|
+
else
|
21
|
+
cur = Mash.new
|
22
|
+
end
|
23
|
+
url = options[:chef_server_url]
|
24
|
+
if(cur[:chef].nil? || cur[:chef][:chef_server_url] != url)
|
25
|
+
cur[:chef] = Mash.new(:chef_server_url => url)
|
26
|
+
cur[:ssl] = Mash.new(:verify => false)
|
27
|
+
File.open(path, 'w') do |file|
|
28
|
+
file.write(JSON.dump(cur))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def upload(*args)
|
34
|
+
prepare unless args.include?(:no_prepare)
|
35
|
+
com = "berks upload -b #{options[:berksfile]} -c #{File.join(store, 'berks.json')}#{" #{Array(options[:berks_opts]).join(' ')}"}"
|
36
|
+
debug(com)
|
37
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => options[:debug], :env => {'HOME' => ENV['HOME']})
|
38
|
+
cmd.run_command
|
39
|
+
cmd.error!
|
40
|
+
end
|
41
|
+
|
42
|
+
def vendor(*args)
|
43
|
+
prepare unless args.include?(:no_prepare)
|
44
|
+
FileUtils.mkdir_p(ckbk_store = File.join(store, 'cookbooks'))
|
45
|
+
com = "berks install -b #{options[:berksfile]} -p #{ckbk_store}"
|
46
|
+
debug(com)
|
47
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => options[:debug])
|
48
|
+
cmd.run_command
|
49
|
+
cmd.error!
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'vagabond/uploader'
|
2
|
+
|
3
|
+
module Vagabond
|
4
|
+
class Uploader
|
5
|
+
class Knife < Uploader
|
6
|
+
|
7
|
+
def upload(*args)
|
8
|
+
prepare unless args.include?(:no_prepare)
|
9
|
+
com = "knife cookbook upload#{options[:knife_opts]} --all"
|
10
|
+
if(options[:cookbook_paths])
|
11
|
+
com << " --cookbook-path #{Array(options[:cookbook_paths]).join(':')}"
|
12
|
+
end
|
13
|
+
debug(com)
|
14
|
+
cmd = Mixlib::ShellOut.new(com,
|
15
|
+
:live_stream => options[:debug],
|
16
|
+
:cwd => store
|
17
|
+
)
|
18
|
+
cmd.run_command
|
19
|
+
cmd.error!
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|