dust-deploy 0.11.1 → 0.12.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.
data/changelog.md CHANGED
@@ -1,6 +1,13 @@
1
1
  Changelog
2
2
  =============
3
3
 
4
+ 0.12.0
5
+ ------------
6
+
7
+ - introduces basic openwrt support!
8
+ - fixes duplicity status bug
9
+
10
+
4
11
  0.11.1
5
12
  ------------
6
13
 
@@ -85,9 +85,9 @@ class Duplicity < Recipe
85
85
  ::Dust.print_result( (ret[:exit_code] == 0 and ret[:stdout].length > 0) )
86
86
 
87
87
  if options.long?
88
- ::Dust.print_msg "#{::Dust.black}#{ret[:stdout]}#{::Dust.none}", :indent => 0
88
+ ::Dust.print_msg ret[:stdout], :indent => 0
89
89
  else
90
- ::Dust.print_msg "\t#{::Dust.black}#{ret[:stdout].sub(/^\s+([a-zA-Z]+)\s+(\w+\s+\w+\s+\d+\s+\d+:\d+:\d+\s+\d+)\s+(\d+)$/, 'Last backup: \1 (\3 sets) on \2')}#{::Dust.none}", :indent => 0
90
+ ::Dust.print_msg "\t" + ret[:stdout].sub(/^\s+([a-zA-Z]+)\s+(\w+\s+\w+\s+\d+\s+\d+:\d+:\d+\s+\d+)\s+(\d+)$/, 'Last backup: \1 (\3 sets) on \2'), :indent => 0
91
91
  end
92
92
 
93
93
  puts
@@ -259,6 +259,14 @@ class Iptables < Recipe
259
259
  prepend_cmd
260
260
  prepend_header
261
261
 
262
+ # overwrite openwrt firewall configuration
263
+ # and only use our script
264
+ if @node.uses_opkg?
265
+ @node.write '/etc/config/firewall',
266
+ "config include\n\toption path /etc/iptables\n\n" +
267
+ "config include\n\toption path /etc/ip6tables\n\n"
268
+ end
269
+
262
270
  @node.write target, @script, :quiet => true
263
271
 
264
272
  if @node.uses_rpm?
@@ -276,7 +284,7 @@ class Iptables < Recipe
276
284
 
277
285
  # prepend iptables command on non-centos-like machines
278
286
  def prepend_cmd
279
- @script.gsub! /^/, "#{cmd} " unless @node.uses_rpm?
287
+ @script.gsub! /^/, "#{cmd_path} " unless @node.uses_rpm?
280
288
  end
281
289
 
282
290
  # apply newly pushed rules
@@ -314,4 +322,16 @@ class Iptables < Recipe
314
322
  return 'ip6tables' if @ip_version == 6
315
323
  end
316
324
 
325
+ def cmd_path
326
+ # get full iptables/ip6tables path using which
327
+ ret = @node.exec("which #{cmd}")
328
+ return ret[:stdout].chomp if ret[:exit_code] == 0
329
+
330
+ # PATH is not set correctly when executing stuff via ssh on openwrt
331
+ # thus returning full path manually
332
+ return "/usr/sbin/#{cmd}" if @node.uses_opkg?
333
+
334
+ # if nothing was found, just use "iptables" resp. "ip6tables"
335
+ return cmd
336
+ end
317
337
  end
data/lib/dust/server.rb CHANGED
@@ -8,11 +8,11 @@ require 'tempfile'
8
8
  module Dust
9
9
  class Server
10
10
  attr_reader :ssh
11
-
11
+
12
12
  def default_options options = {}
13
13
  { :quiet => false, :indent => 1 }.merge options
14
14
  end
15
-
15
+
16
16
  def initialize node
17
17
  @node = node
18
18
  @node['user'] ||= 'root'
@@ -21,7 +21,7 @@ module Dust
21
21
  @node['sudo'] ||= false
22
22
  end
23
23
 
24
- def connect
24
+ def connect
25
25
  Dust.print_hostname @node['hostname']
26
26
  begin
27
27
  # connect to proxy if given
@@ -45,11 +45,11 @@ module Dust
45
45
 
46
46
  true
47
47
  end
48
-
48
+
49
49
  def disconnect
50
50
  @ssh.close
51
51
  end
52
-
52
+
53
53
  def exec command, options={:live => false, :as_user => false}
54
54
  sudo_authenticated = false
55
55
  stdout = ''
@@ -67,14 +67,14 @@ module Dust
67
67
  # command is wrapped in ", escapes " in the command string
68
68
  # and then executed using "sh -c", so that
69
69
  # the use of > < && || | and ; doesn't screw things up
70
- if @node['sudo']
70
+ if @node['sudo']
71
71
  channel.request_pty
72
72
  command = "sudo sh -c \"#{command.gsub('"','\\"')}\""
73
73
  end
74
74
 
75
75
  channel.exec command do |ch, success|
76
76
  abort "FAILED: couldn't execute command (ssh.channel.exec)" unless success
77
-
77
+
78
78
  channel.on_data do |ch, data|
79
79
  # only send password if sudo mode is enabled,
80
80
  # sudo password string matches
@@ -97,11 +97,11 @@ module Dust
97
97
  channel.on_request('exit-signal') { |ch, data| exit_signal = data.read_long }
98
98
  end
99
99
  end
100
-
100
+
101
101
  @ssh.loop
102
102
 
103
103
  # sudo usage provokes a heading newline that's unwanted.
104
- stdout.sub! /^(\r\n|\n|\r)/, '' if @node['sudo']
104
+ stdout.sub! /^(\r\n|\n|\r)/, '' if @node['sudo']
105
105
 
106
106
  { :stdout => stdout, :stderr => stderr, :exit_code => exit_code, :exit_signal => exit_signal }
107
107
  end
@@ -123,15 +123,15 @@ module Dust
123
123
 
124
124
  def append destination, newcontent, options = {}
125
125
  options = default_options.merge options
126
-
126
+
127
127
  Dust.print_msg "appending to #{File.basename destination}", options
128
-
128
+
129
129
  content = exec("cat #{destination}")[:stdout]
130
130
  content.concat newcontent
131
-
132
- Dust.print_result write(destination, content, :quiet => true), options
131
+
132
+ Dust.print_result write(destination, content, :quiet => true), options
133
133
  end
134
-
134
+
135
135
  def scp source, destination, options = {}
136
136
  options = default_options.merge options
137
137
 
@@ -141,7 +141,7 @@ module Dust
141
141
  Dust.print_msg "deploying #{File.basename source}", options
142
142
 
143
143
  # save permissions if the file already exists
144
- ret = exec "stat -c %a:%u:%g #{destination}"
144
+ ret = exec "stat -c %a:%u:%g #{destination}"
145
145
  if ret[:exit_code] == 0
146
146
  permissions, user, group = ret[:stdout].chomp.split ':'
147
147
  else
@@ -150,8 +150,8 @@ module Dust
150
150
  end
151
151
 
152
152
  # if in sudo mode, copy file to temporary place, then move using sudo
153
- if @node['sudo']
154
- ret = exec 'mktemp --tmpdir dust.XXXXXXXXXX'
153
+ if @node['sudo']
154
+ ret = exec 'mktemp --tmpdir dust.XXXXXXXXXX'
155
155
  if ret[:exit_code] != 0
156
156
  ::Dust.print_failed 'could not create temporary file (needed for sudo)'
157
157
  return false
@@ -188,7 +188,7 @@ module Dust
188
188
  Dust.print_msg "downloading #{File.basename source}", options
189
189
  Dust.print_result @ssh.scp.download!(source, destination), options
190
190
  end
191
-
191
+
192
192
  def symlink source, destination, options = {}
193
193
  options = default_options.merge options
194
194
 
@@ -197,7 +197,7 @@ module Dust
197
197
  restorecon destination, options # restore SELinux labels
198
198
  ret
199
199
  end
200
-
200
+
201
201
  def chmod mode, file, options = {}
202
202
  options = default_options.merge options
203
203
 
@@ -262,10 +262,10 @@ module Dust
262
262
  Dust.print_msg "restoring selinux labels for #{path}", options
263
263
  Dust.print_result exec("#{ret[:stdout].chomp} -R #{path}")[:exit_code], options
264
264
  end
265
-
265
+
266
266
  def get_system_users options = {}
267
267
  options = default_options.merge options
268
-
268
+
269
269
  Dust.print_msg "getting all system users", options
270
270
  ret = exec 'getent passwd |cut -d: -f1'
271
271
  Dust.print_result ret[:exit_code], options
@@ -294,16 +294,18 @@ module Dust
294
294
  return Dust.print_ok '', options if exec("rpm -q #{package}")[:exit_code] == 0
295
295
  elsif uses_pacman?
296
296
  return Dust.print_ok '', options if exec("pacman -Q #{package}")[:exit_code] == 0
297
+ elsif uses_opkg?
298
+ return Dust.print_ok '', options unless exec("opkg status #{package}")[:stdout].empty?
297
299
  end
298
300
  end
299
301
 
300
302
  Dust.print_failed '', options
301
303
  end
302
-
304
+
303
305
  def install_package package, options = {}
304
306
  options = default_options.merge options
305
307
  options[:env] ||= ''
306
-
308
+
307
309
  if package_installed? package, :quiet => true
308
310
  return Dust.print_ok "package #{package} already installed", options
309
311
  end
@@ -318,6 +320,8 @@ module Dust
318
320
  exec "yum install -y #{package}"
319
321
  elsif uses_pacman?
320
322
  exec "echo y |pacman -S #{package}"
323
+ elsif uses_opkg?
324
+ exec "opkg install #{package}"
321
325
  else
322
326
  puts
323
327
  return Dust.print_failed "install_package only supports apt, emerge and yum systems at the moment",
@@ -344,6 +348,8 @@ module Dust
344
348
  Dust.print_result exec("yum erase -y #{package}")[:exit_code], options
345
349
  elsif uses_pacman?
346
350
  Dust.print_result exec("echo y |pacman -R #{package}")[:exit_code], options
351
+ elsif uses_opkg?
352
+ Dust.print_result exec("opkg remove #{package}")[:exit_code], options
347
353
  else
348
354
  Dust.print_failed '', options
349
355
  end
@@ -367,6 +373,8 @@ module Dust
367
373
  ret[:exit_code] = 0 if ret[:exit_code] == 100
368
374
  elsif uses_pacman?
369
375
  ret = exec 'pacman -Sy', options
376
+ elsif uses_opkg?
377
+ ret = exec 'opkg update', options
370
378
  else
371
379
  return Dust.print_failed '', options
372
380
  end
@@ -376,15 +384,15 @@ module Dust
376
384
  else
377
385
  Dust.print_result ret[:exit_code], options
378
386
  end
379
-
387
+
380
388
  ret[:exit_code]
381
389
  end
382
390
 
383
391
  def system_update options = {}
384
392
  options = default_options.merge(:live => true).merge(options)
385
-
393
+
386
394
  update_repos
387
-
395
+
388
396
  Dust.print_msg 'installing system updates', options
389
397
  puts if options[:live]
390
398
 
@@ -397,12 +405,15 @@ module Dust
397
405
  elsif uses_pacman?
398
406
  # pacman has no --yes option that i know of, so echoing y
399
407
  ret = exec 'echo y |pacman -Su', options
408
+ elsif uses_opkg?
409
+ # upgrading openwrt is very experimental, and should not used normally
410
+ ret = exec 'opkg upgrade $(echo $(opkg list-upgradable |cut -d' ' -f1 |grep -v Multiple))', options
400
411
  else
401
412
  Dust.print_failed 'system not (yet) supported', options
402
413
  return false
403
414
  end
404
415
 
405
- if options[:live]
416
+ if options[:live]
406
417
  puts
407
418
  else
408
419
  Dust.print_result ret[:exit_code], options
@@ -444,11 +455,19 @@ module Dust
444
455
  Dust.print_msg 'determining whether node uses pacman', options
445
456
  @uses_pacman = Dust.print_result exec('test -e /etc/arch-release')[:exit_code], options
446
457
  end
447
-
458
+
459
+ def uses_opkg? options = {}
460
+ options = default_options(:quiet => true).merge options
461
+
462
+ return @uses_opkg if defined? @uses_opkg
463
+ Dust.print_msg 'determining whether node uses opkg', options
464
+ @uses_opkg = Dust.print_result exec('test -e /etc/opkg.conf')[:exit_code], options
465
+ end
466
+
448
467
  def is_os? os_list, options = {}
449
468
  options = default_options(:quiet => true).merge options
450
469
 
451
- Dust.print_msg "checking if this machine runs #{os_list.join(' or ')}", options
470
+ Dust.print_msg "checking if this machine runs #{os_list.join(' or ')}", options
452
471
  return Dust.print_failed '', options unless collect_facts options
453
472
 
454
473
  os_list.each do |os|
@@ -460,35 +479,35 @@ module Dust
460
479
  Dust.print_failed '', options
461
480
  false
462
481
  end
463
-
482
+
464
483
  def is_debian? options = {}
465
484
  options = default_options(:quiet => true).merge options
466
485
 
467
486
  return false unless uses_apt?
468
487
  is_os? ['debian'], options
469
488
  end
470
-
489
+
471
490
  def is_ubuntu? options = {}
472
491
  options = default_options(:quiet => true).merge options
473
492
 
474
493
  return false unless uses_apt?
475
494
  is_os? ['ubuntu'], options
476
495
  end
477
-
496
+
478
497
  def is_gentoo? options = {}
479
498
  options = default_options(:quiet => true).merge options
480
499
 
481
500
  return false unless uses_emerge?
482
501
  is_os? ['gentoo'], options
483
502
  end
484
-
503
+
485
504
  def is_centos? options = {}
486
505
  options = default_options(:quiet => true).merge options
487
506
 
488
507
  return false unless uses_rpm?
489
508
  is_os? ['centos'], options
490
509
  end
491
-
510
+
492
511
  def is_scientific? options = {}
493
512
  options = default_options(:quiet => true).merge options
494
513
 
@@ -509,14 +528,14 @@ module Dust
509
528
  return false unless uses_pacman?
510
529
  is_os? ['archlinux'], options
511
530
  end
512
-
531
+
513
532
  def is_executable? file, options = {}
514
533
  options = default_options.merge options
515
534
 
516
535
  Dust.print_msg "checking if file #{file} exists and is executeable", options
517
536
  Dust.print_result exec("test -x $(which #{file})")[:exit_code], options
518
537
  end
519
-
538
+
520
539
  def file_exists? file, options = {}
521
540
  options = default_options.merge options
522
541
 
@@ -530,7 +549,7 @@ module Dust
530
549
  Dust.print_msg "checking if directory #{dir} exists", options
531
550
  Dust.print_result exec("test -d #{dir}")[:exit_code], options
532
551
  end
533
-
552
+
534
553
  def autostart_service service, options = {}
535
554
  options = default_options.merge options
536
555
 
@@ -557,7 +576,7 @@ module Dust
557
576
  end
558
577
  end
559
578
 
560
- # invoke 'command' on the service (e.g. @node.service 'postgresql', 'restart')
579
+ # invoke 'command' on the service (e.g. @node.service 'postgresql', 'restart')
561
580
  def service service, command, options = {}
562
581
  options = default_options.merge options
563
582
 
@@ -621,7 +640,7 @@ module Dust
621
640
  options = default_options.merge options
622
641
  options[:home] ||= nil
623
642
  options[:shell] ||= nil
624
-
643
+
625
644
  return true if user_exists? user, options
626
645
 
627
646
  Dust.print_msg "creating user #{user}", :indent => options[:indent]
@@ -634,7 +653,7 @@ module Dust
634
653
  # returns the home directory of this user
635
654
  def get_home user, options = {}
636
655
  options = default_options(:quiet => true).merge options
637
-
656
+
638
657
  Dust.print_msg "getting home directory of #{user}", options
639
658
  ret = exec "getent passwd |cut -d':' -f1,6 |grep '^#{user}' |head -n1 |cut -d: -f2"
640
659
  if Dust.print_result ret[:exit_code], options
@@ -687,27 +706,27 @@ module Dust
687
706
  # if it's an file.erb exists, render template and push to server
688
707
  def deploy_file file, destination, options = {}
689
708
  options = default_options(:binding => binding).merge options
690
-
709
+
691
710
  if File.exists? file
692
711
  scp file, destination, options
693
-
712
+
694
713
  elsif File.exists? "#{file}.erb"
695
714
  template = ERB.new( File.read("#{file}.erb"), nil, '%<>')
696
715
  write destination, template.result(options[:binding]), options
697
-
716
+
698
717
  else
699
718
  ::Dust.print_failed "'#{file}' was not found."
700
719
  end
701
720
  end
702
-
703
-
721
+
722
+
704
723
  private
705
-
724
+
706
725
  def method_missing method, *args, &block
707
726
  # make server nodeibutes accessible via server.nodeibute
708
727
  if @node[method.to_s]
709
728
  @node[method.to_s]
710
-
729
+
711
730
  # and as server['nodeibute']
712
731
  elsif @node[args.first]
713
732
  @node[args.first]
data/lib/dust/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dust
2
- VERSION = "0.11.1"
2
+ VERSION = "0.12.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dust-deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.1
4
+ version: 0.12.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-07 00:00:00.000000000 Z
12
+ date: 2012-05-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json