kuzushi 0.0.21 → 0.0.22

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.
Files changed (4) hide show
  1. data/VERSION +1 -1
  2. data/lib/kuzushi.rb +59 -62
  3. data/spec/kuzushi_spec.rb +73 -3
  4. metadata +2 -2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.21
1
+ 0.0.22
@@ -11,6 +11,8 @@ require 'erb'
11
11
  ## ruby 1.9 compatibility
12
12
 
13
13
  class Kuzushi
14
+ attr_accessor :config, :config_names
15
+
14
16
  def initialize(url)
15
17
  @base_url = File.dirname(url)
16
18
  @name = File.basename(url)
@@ -18,8 +20,6 @@ class Kuzushi
18
20
  @configs = []
19
21
  @packages = []
20
22
  @tasks = []
21
- load_config_stack(@name)
22
- @config = @configs.reverse.inject({}) { |i,c| i.merge(c) }
23
23
  end
24
24
 
25
25
  def init
@@ -28,13 +28,14 @@ class Kuzushi
28
28
  end
29
29
 
30
30
  def start
31
+ load_config_stack(@name)
31
32
  process_stack
32
- puts "----"
33
+ log "----"
33
34
  @tasks.each do |t|
34
- puts "TASK: #{t[:description]}"
35
+ log "TASK: #{t[:description]}"
35
36
  t[:blk].call
36
37
  end
37
- puts "----"
38
+ log "----"
38
39
  end
39
40
 
40
41
  protected
@@ -45,11 +46,17 @@ class Kuzushi
45
46
  ohai
46
47
  end
47
48
 
49
+ def http_get(url)
50
+ RestClient.get("#{@base_url}/#{name}")
51
+ end
52
+
48
53
  def load_config_stack(name)
49
54
  @config_names << name
50
- @configs << JSON.parse(RestClient.get("#{@base_url}/#{name}"))
55
+ @configs << JSON.parse(http_get("#{@base_url}/#{name}"))
51
56
  if import = @configs.last["import"]
52
57
  load_config_stack(import)
58
+ else
59
+ @config = @configs.reverse.inject({}) { |i,c| i.merge(c) }
53
60
  end
54
61
  end
55
62
 
@@ -175,53 +182,24 @@ class Kuzushi
175
182
  `dpkg --print-architecture`.chomp
176
183
  end
177
184
 
178
- def process_files(f)
179
- if f.template
180
- write_file("/templates/#{f.template}", f.file) do |file|
181
- @system = system
182
- t = ERB.new File.read(file), 0, '<>'
183
- t.result(binding)
184
- end
185
- else
186
- src = f.source || File.basename(f.file)
187
- write_file("/files/#{src}", f.file) do |file|
188
- File.read(file)
189
- end
190
- end
191
- end
192
-
193
- def write_file(src, dest, &blk)
194
- fetch(src) do |file|
195
- task "write #{dest}" do
196
- FileUtils.mkdir_p(File.dirname(dest))
197
- File.open(dest,"w") { |f| f.write(blk.call(file)) }
198
- end
199
- end
185
+ def erb(data)
186
+ @system = system
187
+ ERB.new(data, 0, '<>').result(binding)
200
188
  end
201
189
 
202
- def handle_crontab(src, user = "root", &blk)
203
- ## FIXME - this is getting a little silly calling tmpfile twice - should be able to pass erb to fetch as an opton...
204
- ## unify code for process crontabs + process files
205
- fetch(src) do |file|
206
- tmpfile(blk.call(file)) do |tmp|
207
- task "process crontab for #{user}" do
208
- shell "crontab -u #{user} #{tmp}"
209
- end
190
+ def process_files(f)
191
+ file(f) do |tmp|
192
+ task "write #{f.file}" do
193
+ cp_file(tmp, f.file)
210
194
  end
211
195
  end
212
196
  end
213
197
 
214
198
  def process_crontab(cron)
215
- if cron.template
216
- handle_crontab("/templates/#{cron.template}", cron.user) do |file|
217
- @system = system
218
- t = ERB.new File.read(file), 0, '<>'
219
- t.result(binding)
220
- end
221
- else
222
- src = cron.source || File.basename(cron.file)
223
- handle_crontab("/files/#{src}", cron.user) do |file|
224
- File.read(file)
199
+ user = cron.user || "root"
200
+ file(cron) do |tmp|
201
+ task "process crontab for #{user}" do
202
+ shell "crontab -u #{user} #{tmp}"
225
203
  end
226
204
  end
227
205
  end
@@ -285,22 +263,23 @@ class Kuzushi
285
263
  end
286
264
 
287
265
  def tmpfile(content, file = "tmp_#{rand(1_000_000_000)}", &block)
288
- tmp_dir = "/tmp/kuzushi"
289
- Dir.mkdir(tmp_dir) unless File.exists?(tmp_dir)
290
- file = "#{tmp_dir}/#{File.basename(file)}"
291
- File.open(file,"w") do |f|
292
- f.write(content)
293
- f.chmod(0700)
294
- end if content
295
- block.call(file) if block
296
- file
266
+ path = "/tmp/kuzushi/#{File.basename(file)}"
267
+ put_file(content, path)
268
+ block.call(path) if block
269
+ path
270
+ end
271
+
272
+ def file(f, &blk)
273
+ ## no magic here - move along
274
+ fetch("/templates/#{f.template}", lambda { |data| erb data }, &blk) if f.template
275
+ fetch("/files/#{f.source || File.basename(f.file)}", &blk) unless f.template
297
276
  end
298
277
 
299
- def fetch(file, &block)
300
- names = @config_names.clone
278
+ def fetch(file, filter = lambda { |d| d }, &block)
279
+ names = config_names.clone
301
280
  begin
302
281
  ## its important that we try each name for the script - allows for polymorphic scripts
303
- tmpfile RestClient.get("#{@base_url}/#{names.first}#{file}"), file do |tmp|
282
+ tmpfile(filter.call(http_get("#{@base_url}/#{names.first}#{file}")), file) do |tmp|
304
283
  block.call(tmp)
305
284
  end
306
285
  rescue RestClient::ResourceNotFound
@@ -314,10 +293,11 @@ class Kuzushi
314
293
 
315
294
  def error(message, exception = nil)
316
295
  puts "ERROR :#{message}"
296
+ puts exception.message
317
297
  end
318
298
 
319
299
  def get(key)
320
- @config[key.to_s]
300
+ config[key.to_s]
321
301
  end
322
302
 
323
303
  def get_array(key)
@@ -327,14 +307,14 @@ class Kuzushi
327
307
  def wait_for_volume(vol)
328
308
  ## Maybe use ohai here instead -- FIXME
329
309
  until dev_exists? vol do
330
- puts "waiting for volume #{vol}"
310
+ log "waiting for volume #{vol}"
331
311
  sleep 2
332
312
  end
333
313
  end
334
314
 
335
315
  def shell(cmd)
336
- puts "# #{cmd}"
337
- puts Kernel.system cmd ## FIXME - need to handle/report exceptions here
316
+ log "# #{cmd}"
317
+ Kernel.system cmd ## FIXME - need to handle/report exceptions here
338
318
  end
339
319
 
340
320
  def init?
@@ -349,4 +329,21 @@ class Kuzushi
349
329
  def dev_exists?(dev)
350
330
  File.exists?("/sys/block/#{File.basename(dev)}")
351
331
  end
332
+
333
+ def cp_file(src, dest)
334
+ FileUtils.mkdir_p(File.dirname(dest))
335
+ FileUtils.cp(src, dest)
336
+ end
337
+
338
+ def put_file(data, dest)
339
+ FileUtils.mkdir_p(File.dirname(dest))
340
+ File.open(dest,"w") do |f|
341
+ f.write(data)
342
+ f.chmod(0700)
343
+ end
344
+ end
345
+
346
+ def log(message)
347
+ puts message
348
+ end
352
349
  end
@@ -2,10 +2,80 @@ require File.dirname(__FILE__) + '/base'
2
2
 
3
3
  describe Kuzushi do
4
4
  before do
5
- # hello
5
+ @url = "http://myurl/foo"
6
+ @kuzushi = Kuzushi.new(@url)
7
+ @kuzushi.stubs(:log)
8
+ @kuzushi.stubs(:config_names).returns(["foo"])
9
+ @kuzushi.stubs(:load_config_stack)
6
10
  end
7
11
 
8
- it "is a class" do
9
- Kuzushi.class.should == Class
12
+ it "processes a simple file" do
13
+ @kuzushi.stubs(:config).returns( {
14
+ "files" => [ {
15
+ "file" => "/var/lib/zing.conf"
16
+ } ] } )
17
+ @kuzushi.expects(:http_get).with("#{@url}/files/zing.conf").returns( "123" )
18
+ @kuzushi.expects(:put_file).with("123", "/tmp/kuzushi/zing.conf")
19
+ @kuzushi.expects(:cp_file).with("/tmp/kuzushi/zing.conf", "/var/lib/zing.conf")
20
+ should.not.raise { @kuzushi.start }
21
+ end
22
+
23
+ it "processes a simple file with a different source" do
24
+ @kuzushi.stubs(:config).returns( {
25
+ "files" => [ {
26
+ "file" => "/var/lib/zing.conf",
27
+ "source" => "zing-8.2"
28
+ } ] } )
29
+ @kuzushi.expects(:http_get).with("#{@url}/files/zing-8.2").returns( "123" )
30
+ @kuzushi.expects(:put_file).with("123", "/tmp/kuzushi/zing-8.2")
31
+ @kuzushi.expects(:cp_file).with("/tmp/kuzushi/zing-8.2", "/var/lib/zing.conf")
32
+ should.not.raise { @kuzushi.start }
33
+ end
34
+
35
+ it "processes a file from an erb template" do
36
+ @kuzushi.stubs(:config).returns( {
37
+ "files" => [ {
38
+ "file" => "/var/lib/zing.conf",
39
+ "template" => "zing-8.2.erb"
40
+ } ] } )
41
+ @kuzushi.expects(:http_get).with("#{@url}/templates/zing-8.2.erb").returns( "I love <%= ['e','r','b'].join('') %>" )
42
+ @kuzushi.expects(:put_file).with("I love erb", "/tmp/kuzushi/zing-8.2.erb")
43
+ @kuzushi.expects(:cp_file).with("/tmp/kuzushi/zing-8.2.erb", "/var/lib/zing.conf")
44
+ should.not.raise { @kuzushi.start }
45
+ end
46
+
47
+ it "can handle a basic crontab with a specified file" do
48
+ @kuzushi.stubs(:config).returns( {
49
+ "crontab" => [ {
50
+ "file" => "mycrontab",
51
+ } ] } )
52
+ @kuzushi.expects(:http_get).with("#{@url}/files/mycrontab").returns("abc123")
53
+ @kuzushi.expects(:put_file).with("abc123", tmpfile = "/tmp/kuzushi/mycrontab")
54
+ @kuzushi.expects(:shell).with("crontab -u root #{tmpfile}")
55
+ should.not.raise { @kuzushi.start }
56
+ end
57
+
58
+ it "can handle a basic crontab with a specified source or a different user" do
59
+ @kuzushi.stubs(:config).returns( {
60
+ "crontab" => [ {
61
+ "source" => "mycrontab",
62
+ "user" => "bob",
63
+ } ] } )
64
+ @kuzushi.expects(:http_get).with("#{@url}/files/mycrontab").returns("abc123")
65
+ @kuzushi.expects(:put_file).with("abc123", tmpfile = "/tmp/kuzushi/mycrontab")
66
+ @kuzushi.expects(:shell).with("crontab -u bob #{tmpfile}")
67
+ should.not.raise { @kuzushi.start }
68
+ end
69
+
70
+ it "can handle a basic crontab with a specified source" do
71
+ @kuzushi.stubs(:config).returns( {
72
+ "crontab" => [ {
73
+ "template" => "mycrontab.erb",
74
+ } ] } )
75
+ @kuzushi.expects(:http_get).with("#{@url}/templates/mycrontab.erb").returns("Hello <%= 'world' %>")
76
+ @kuzushi.expects(:put_file).with("Hello world", tmpfile = "/tmp/kuzushi/mycrontab.erb")
77
+ @kuzushi.expects(:shell).with("crontab -u root #{tmpfile}")
78
+ should.not.raise { @kuzushi.start }
10
79
  end
11
80
  end
81
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kuzushi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.21
4
+ version: 0.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Orion Henry
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-24 00:00:00 -05:00
12
+ date: 2010-02-25 00:00:00 -05:00
13
13
  default_executable: kuzushi
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency