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 +7 -0
- data/lib/dust/recipes/duplicity.rb +2 -2
- data/lib/dust/recipes/iptables.rb +21 -1
- data/lib/dust/server.rb +66 -47
- data/lib/dust/version.rb +1 -1
- metadata +2 -2
data/changelog.md
CHANGED
@@ -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
|
88
|
+
::Dust.print_msg ret[:stdout], :indent => 0
|
89
89
|
else
|
90
|
-
::Dust.print_msg "\t
|
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! /^/, "#{
|
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
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.
|
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-
|
12
|
+
date: 2012-05-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|