dust-deploy 0.6.2 → 0.7.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 +22 -0
- data/lib/dust/print_status.rb +9 -0
- data/lib/dust/recipes/aliases.rb +8 -0
- data/lib/dust/recipes/cups_client.rb +7 -0
- data/lib/dust/recipes/etc_hosts.rb +8 -0
- data/lib/dust/recipes/hash_check.rb +1 -1
- data/lib/dust/recipes/iptables.rb +9 -1
- data/lib/dust/recipes/locale.rb +16 -0
- data/lib/dust/recipes/motd.rb +8 -0
- data/lib/dust/recipes/mysql.rb +7 -1
- data/lib/dust/recipes/nginx.rb +8 -2
- data/lib/dust/recipes/pacemaker.rb +8 -0
- data/lib/dust/recipes/postgres.rb +7 -1
- data/lib/dust/recipes/rc_local.rb +8 -0
- data/lib/dust/recipes/redis.rb +6 -2
- data/lib/dust/recipes/resolv_conf.rb +8 -0
- data/lib/dust/recipes/zabbix_agent.rb +8 -0
- data/lib/dust/server.rb +102 -21
- data/lib/dust/version.rb +1 -1
- metadata +4 -4
data/changelog.md
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
Changelog
|
2
2
|
=============
|
3
3
|
|
4
|
+
0.7.0
|
5
|
+
------------
|
6
|
+
|
7
|
+
- adds sudo support, you can now connect using an unpriviledged user. needs sudo rights, e.g.:
|
8
|
+
<username> ALL=(ALL) ALL
|
9
|
+
|
10
|
+
hostname: myhost
|
11
|
+
port: 22
|
12
|
+
user: myuser
|
13
|
+
password: mypass # not needed when connecting using ssh keys
|
14
|
+
sudo: true
|
15
|
+
|
16
|
+
|
17
|
+
- adds status command to most recipes (you can now watch the status of current recipes/daemons with 'dust status'
|
18
|
+
- node.restart/reload now tries systemd, upstart, sysvconfig and then uses initscript as fallback
|
19
|
+
- node.autostart_service now uses systemd on rpm systems (if available), falls back to chkconfig
|
20
|
+
- adds node.print_service_status method, used to retrieve daemon status
|
21
|
+
- adds new ::Dust.print_ret method, used to print stderr/stdout from node.exec in different colors
|
22
|
+
- mysql recipe now defaults to 0.7 of system ram for innodb buffer size, because 0.8 sometimes lead to oom situations
|
23
|
+
|
24
|
+
|
4
25
|
0.6.2
|
5
26
|
------------
|
6
27
|
|
@@ -11,6 +32,7 @@ Changelog
|
|
11
32
|
port: 6379
|
12
33
|
daemonize: yes
|
13
34
|
|
35
|
+
- the redis recipe also supports the 'status' command
|
14
36
|
- fixes hash_check recipe, now works with centos-like machines as well
|
15
37
|
- improves mysql recipe: now sets shm sysctls as well (like the postgresql recipe does)
|
16
38
|
- small improvements to automatic innodb tuning
|
data/lib/dust/print_status.rb
CHANGED
@@ -50,6 +50,15 @@ module Dust
|
|
50
50
|
print_msg "#{green}|#{recipe}|#{none}\n", options
|
51
51
|
end
|
52
52
|
|
53
|
+
# prints stdout in grey and stderr in red (if existend)
|
54
|
+
def self.print_ret ret, options={:quiet => false, :indent => -1}
|
55
|
+
opts = options.clone
|
56
|
+
|
57
|
+
opts[:indent] += 1
|
58
|
+
print_msg "#{grey}#{ret[:stdout].chomp}#{none}\n", opts unless ret[:stdout].empty?
|
59
|
+
print_msg "#{red}#{ret[:stderr].chomp}#{none}\n", opts unless ret[:stderr].empty?
|
60
|
+
end
|
61
|
+
|
53
62
|
# indent according to options[:indent]
|
54
63
|
# indent 0
|
55
64
|
# - indent 1
|
data/lib/dust/recipes/aliases.rb
CHANGED
@@ -8,5 +8,13 @@ class Aliases < Recipe
|
|
8
8
|
::Dust.print_msg 'running newaliases'
|
9
9
|
::Dust.print_result @node.exec('newaliases')[:exit_code]
|
10
10
|
end
|
11
|
+
|
12
|
+
desc 'aliases:status', 'shows current aliases'
|
13
|
+
def status
|
14
|
+
::Dust.print_msg 'getting /etc/aliases'
|
15
|
+
ret = @node.exec 'cat /etc/aliases'
|
16
|
+
::Dust.print_result ret[:exit_code]
|
17
|
+
::Dust.print_ret ret
|
18
|
+
end
|
11
19
|
end
|
12
20
|
|
@@ -9,6 +9,13 @@ class CupsClient < Recipe
|
|
9
9
|
@node.write '/etc/cups/client.conf', "ServerName #{@config}\n"
|
10
10
|
end
|
11
11
|
|
12
|
+
desc 'cups_client:status', 'shows current /etc/cups/client.conf'
|
13
|
+
def status
|
14
|
+
::Dust.print_msg 'getting /etc/cups/client.conf'
|
15
|
+
ret = @node.exec 'cat /etc/cups/client.conf'
|
16
|
+
::Dust.print_result ret[:exit_code]
|
17
|
+
::Dust.print_ret ret
|
18
|
+
end
|
12
19
|
|
13
20
|
private
|
14
21
|
|
@@ -9,5 +9,13 @@ class EtcHosts < Recipe
|
|
9
9
|
@node.restart_service @config
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
desc 'etc_hosts:status', 'shows current /etc/hosts'
|
14
|
+
def status
|
15
|
+
::Dust.print_msg 'getting /etc/hosts'
|
16
|
+
ret = @node.exec 'cat /etc/hosts'
|
17
|
+
::Dust.print_result ret[:exit_code]
|
18
|
+
::Dust.print_ret ret
|
19
|
+
end
|
12
20
|
end
|
13
21
|
|
@@ -6,8 +6,8 @@ class HashCheck < Recipe
|
|
6
6
|
keys = [ '*', '!', '!!', '', 'LK', 'NP' ]
|
7
7
|
|
8
8
|
weak_passwords = File.open "#{@template_path}/weak_passwords", 'r'
|
9
|
-
shadow = @node.exec('cat /etc/shadow')[:stdout]
|
10
9
|
|
10
|
+
shadow = @node.exec('getent shadow')[:stdout]
|
11
11
|
::Dust.print_msg "checking for weak password hashes\n"
|
12
12
|
|
13
13
|
found_weak = false
|
@@ -37,13 +37,21 @@ class Iptables < Recipe
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
desc 'iptables:status', 'displays iptables rules'
|
41
|
+
def status
|
42
|
+
::Dust.print_ok 'displaying iptables rules (ipv4)'
|
43
|
+
::Dust.print_msg @node.exec('iptables -L -v -n')[:stdout], :indent => 0
|
44
|
+
puts
|
45
|
+
::Dust.print_ok 'displaying iptables rules (ipv6)'
|
46
|
+
::Dust.print_msg @node.exec('ip6tables -L -v -n')[:stdout], :indent => 0
|
47
|
+
end
|
40
48
|
|
41
49
|
private
|
42
50
|
|
43
51
|
# install iptables
|
44
52
|
def install
|
45
53
|
return false unless @node.install_package 'iptables'
|
46
|
-
return false unless @node.install_package 'iptables-ipv6' if @node.uses_rpm?
|
54
|
+
return false unless @node.install_package 'iptables-ipv6' if @node.uses_rpm? and not @node.is_fedora?
|
47
55
|
true
|
48
56
|
end
|
49
57
|
|
data/lib/dust/recipes/locale.rb
CHANGED
@@ -17,5 +17,21 @@ class Locale < Recipe
|
|
17
17
|
::Dust.print_failed 'os not supported'
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
21
|
+
desc 'locale:status', 'shows current locale'
|
22
|
+
def status
|
23
|
+
::Dust.print_msg 'getting current locale'
|
24
|
+
|
25
|
+
if @node.uses_apt?
|
26
|
+
ret = @node.exec 'cat /etc/default/locale'
|
27
|
+
elsif @node.uses_rpm?
|
28
|
+
ret = @node.exec 'cat /etc/sysconfig/i18n'
|
29
|
+
else
|
30
|
+
return ::Dust.print_failed
|
31
|
+
end
|
32
|
+
|
33
|
+
::Dust.print_result ret[:exit_code]
|
34
|
+
::Dust.print_ret ret
|
35
|
+
end
|
20
36
|
end
|
21
37
|
|
data/lib/dust/recipes/motd.rb
CHANGED
@@ -3,4 +3,12 @@ class Motd < Recipe
|
|
3
3
|
def deploy
|
4
4
|
@node.deploy_file "#{@template_path}/motd", '/etc/motd', :binding => binding
|
5
5
|
end
|
6
|
+
|
7
|
+
desc 'motd:status', 'shows current message of the day'
|
8
|
+
def status
|
9
|
+
::Dust.print_msg 'getting /etc/motd'
|
10
|
+
ret = @node.exec 'cat /etc/motd'
|
11
|
+
::Dust.print_result ret[:exit_code]
|
12
|
+
::Dust.print_ret ret
|
13
|
+
end
|
6
14
|
end
|
data/lib/dust/recipes/mysql.rb
CHANGED
@@ -21,6 +21,12 @@ class Mysql < Recipe
|
|
21
21
|
@node.reload_service 'mysql' if options.reload?
|
22
22
|
end
|
23
23
|
|
24
|
+
desc 'mysql:status', 'displays status of the mysql daemon'
|
25
|
+
def status
|
26
|
+
return unless @node.package_installed? 'mysql-server'
|
27
|
+
@node.print_service_status 'mysql'
|
28
|
+
end
|
29
|
+
|
24
30
|
|
25
31
|
private
|
26
32
|
|
@@ -82,7 +88,7 @@ class Mysql < Recipe
|
|
82
88
|
system_mem = ::Dust.convert_size @node['memorysize']
|
83
89
|
|
84
90
|
# allocate 80% of the available ram to mysql
|
85
|
-
buffer_pool = (system_mem * 0.
|
91
|
+
buffer_pool = (system_mem * 0.7).to_i
|
86
92
|
|
87
93
|
::Dust.print_ok
|
88
94
|
"#{buffer_pool / 1024}M"
|
data/lib/dust/recipes/nginx.rb
CHANGED
@@ -2,9 +2,9 @@ class Nginx < Recipe
|
|
2
2
|
desc 'nginx:deploy', 'installs and configures nginx web server'
|
3
3
|
def deploy
|
4
4
|
# abort if nginx cannot be installed
|
5
|
-
return unless @node.install_package
|
5
|
+
return unless @node.install_package 'nginx'
|
6
6
|
|
7
|
-
@node.scp
|
7
|
+
@node.scp "#{@template_path}/nginx.conf", '/etc/nginx/nginx.conf'
|
8
8
|
|
9
9
|
# remove old sites that may be present
|
10
10
|
::Dust.print_msg 'deleting old sites in /etc/nginx/sites-*'
|
@@ -31,5 +31,11 @@ class Nginx < Recipe
|
|
31
31
|
::Dust.print_failed
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
35
|
+
desc 'nginx:status', 'displays nginx status'
|
36
|
+
def status
|
37
|
+
return unless @node.package_installed? 'nginx'
|
38
|
+
@node.print_service_status 'nginx'
|
39
|
+
end
|
34
40
|
end
|
35
41
|
|
@@ -32,4 +32,12 @@ class Pacemaker < Recipe
|
|
32
32
|
# not restarting automatically, because it provokes switching of ha services
|
33
33
|
#@node.restart_service 'corosync' if @options.restart
|
34
34
|
end
|
35
|
+
|
36
|
+
desc 'pacemaker:status', 'shows status of pacemaker/corosync cluster'
|
37
|
+
def status
|
38
|
+
::Dust.print_msg 'running crm_mon'
|
39
|
+
ret = @node.exec 'crm_mon -1'
|
40
|
+
::Dust.print_result ret[:exit_code]
|
41
|
+
::Dust.print_ret ret
|
42
|
+
end
|
35
43
|
end
|
@@ -22,7 +22,13 @@ class Postgres < Recipe
|
|
22
22
|
@node.restart_service @config['service_name'] if options.restart?
|
23
23
|
@node.reload_service @config['service_name'] if options.reload?
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
|
+
desc 'postgres:status', 'displays status of postgres cluster'
|
27
|
+
def status
|
28
|
+
return unless @node.package_installed? [ 'postgresql-server', "postgresql-#{@config['version']}" ]
|
29
|
+
set_default_directories
|
30
|
+
@node.print_service_status @config['service_name']
|
31
|
+
end
|
26
32
|
|
27
33
|
private
|
28
34
|
|
@@ -20,5 +20,13 @@ class RcLocal < Recipe
|
|
20
20
|
::Dust.print_failed 'os not supported'
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
desc 'rc_local:status', 'shows current /etc/rc.local'
|
25
|
+
def status
|
26
|
+
::Dust.print_msg 'getting /etc/rc.local'
|
27
|
+
ret = @node.exec 'cat /etc/rc.local'
|
28
|
+
::Dust.print_result ret[:exit_code]
|
29
|
+
::Dust.print_ret ret
|
30
|
+
end
|
23
31
|
end
|
24
32
|
|
data/lib/dust/recipes/redis.rb
CHANGED
@@ -10,7 +10,11 @@ class Redis < Recipe
|
|
10
10
|
desc 'redis:status', 'displays redis-cli info'
|
11
11
|
def status
|
12
12
|
return false unless @node.package_installed? 'redis-server'
|
13
|
-
|
13
|
+
::Dust.print_msg 'running "redis-cli info"'
|
14
|
+
ret = @node.exec 'redis-cli info'
|
15
|
+
::Dust.print_result ret[:exit_code]
|
16
|
+
|
17
|
+
::Dust.print_msg ret[:stdout], :indent => 0 unless ret[:stdout].empty?
|
14
18
|
end
|
15
19
|
|
16
20
|
|
@@ -88,4 +92,4 @@ class Redis < Recipe
|
|
88
92
|
::Dust.print_warning 'sysctl configuration not supported for your os'
|
89
93
|
end
|
90
94
|
end
|
91
|
-
end
|
95
|
+
end
|
@@ -38,5 +38,13 @@ class ResolvConf < Recipe
|
|
38
38
|
|
39
39
|
@node.write '/etc/resolv.conf', config_file
|
40
40
|
end
|
41
|
+
|
42
|
+
desc 'resolv_conf:status', 'shows current /etc/resolv.conf'
|
43
|
+
def status
|
44
|
+
::Dust.print_msg 'getting /etc/resolv.conf'
|
45
|
+
ret = @node.exec 'cat /etc/resolv.conf'
|
46
|
+
::Dust.print_result ret[:exit_code]
|
47
|
+
::Dust.print_ret ret
|
48
|
+
end
|
41
49
|
end
|
42
50
|
|
@@ -13,6 +13,14 @@ class ZabbixAgent < Recipe
|
|
13
13
|
@node.restart_service daemon if options.restart?
|
14
14
|
end
|
15
15
|
|
16
|
+
desc 'zabbix_agent:status', 'displays status of the zabbix agent'
|
17
|
+
def status
|
18
|
+
daemon = @node.uses_emerge? ? 'zabbix-agentd' : 'zabbix-agent'
|
19
|
+
return unless @node.package_installed? daemon
|
20
|
+
@node.print_service_status daemon
|
21
|
+
end
|
22
|
+
|
23
|
+
|
16
24
|
private
|
17
25
|
# installs zabbix and its dependencies
|
18
26
|
def install_zabbix
|
data/lib/dust/server.rb
CHANGED
@@ -18,6 +18,7 @@ module Dust
|
|
18
18
|
@node['user'] ||= 'root'
|
19
19
|
@node['port'] ||= 22
|
20
20
|
@node['password'] ||= ''
|
21
|
+
@node['sudo'] ||= false
|
21
22
|
end
|
22
23
|
|
23
24
|
def connect
|
@@ -50,15 +51,36 @@ module Dust
|
|
50
51
|
end
|
51
52
|
|
52
53
|
def exec command
|
54
|
+
sudo_authenticated = false
|
53
55
|
stdout = ''
|
54
56
|
stderr = ''
|
55
57
|
exit_code = nil
|
56
58
|
exit_signal = nil
|
57
|
-
|
59
|
+
|
58
60
|
@ssh.open_channel do |channel|
|
61
|
+
|
62
|
+
# request a terminal (sudo needs it)
|
63
|
+
# and prepend "sudo"
|
64
|
+
if @node['sudo']
|
65
|
+
channel.request_pty
|
66
|
+
command = "sudo #{command}"
|
67
|
+
end
|
68
|
+
|
59
69
|
channel.exec command do |ch, success|
|
60
70
|
abort "FAILED: couldn't execute command (ssh.channel.exec)" unless success
|
61
|
-
|
71
|
+
|
72
|
+
channel.on_data do |ch, data|
|
73
|
+
# only send password if sudo mode is enabled,
|
74
|
+
# sudo password string matches
|
75
|
+
# and only send password once in a session (trying to prevent attacks reading out the password)
|
76
|
+
if @node['sudo'] and data =~ /^\[sudo\] password for #{@node['user']}/ and not sudo_authenticated
|
77
|
+
channel.send_data "#{@node['password']}\n"
|
78
|
+
sudo_authenticated = true
|
79
|
+
else
|
80
|
+
stdout += data
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
62
84
|
channel.on_extended_data { |ch, type, data| stderr += data }
|
63
85
|
channel.on_request('exit-status') { |ch, data| exit_code = data.read_long }
|
64
86
|
channel.on_request('exit-signal') { |ch, data| exit_signal = data.read_long }
|
@@ -66,10 +88,12 @@ module Dust
|
|
66
88
|
end
|
67
89
|
|
68
90
|
@ssh.loop
|
69
|
-
|
91
|
+
|
92
|
+
# sudo usage provokes a heading newline that's unwanted.
|
93
|
+
stdout.sub! /^(\r\n|\n|\r)/, '' if @node['sudo']
|
94
|
+
|
70
95
|
{ :stdout => stdout, :stderr => stderr, :exit_code => exit_code, :exit_signal => exit_signal }
|
71
96
|
end
|
72
|
-
|
73
97
|
|
74
98
|
def write destination, content, options = {}
|
75
99
|
options = default_options.merge options
|
@@ -101,8 +125,29 @@ module Dust
|
|
101
125
|
options = default_options.merge options
|
102
126
|
|
103
127
|
Dust.print_msg "deploying #{File.basename source}", options
|
104
|
-
|
105
|
-
|
128
|
+
|
129
|
+
# if in sudo mode, copy file to temporary place, then move using sudo
|
130
|
+
if @node['sudo']
|
131
|
+
ret = exec 'mktemp --tmpdir dust.XXXXXXXXXX'
|
132
|
+
if ret[:exit_code] != 0
|
133
|
+
::Dust.print_failed 'could not create temporary file (needed for sudo)'
|
134
|
+
return false
|
135
|
+
end
|
136
|
+
|
137
|
+
tmpfile = ret[:stdout].chomp
|
138
|
+
|
139
|
+
# allow user to write file without sudo (for scp)
|
140
|
+
# then change file back to root, and copy to the destination
|
141
|
+
chown @node['user'], tmpfile, :quiet => true
|
142
|
+
@ssh.scp.upload! source, tmpfile
|
143
|
+
chown 'root', tmpfile, :quiet => true
|
144
|
+
Dust.print_result exec("mv -f #{tmpfile} #{destination}")[:exit_code], options
|
145
|
+
|
146
|
+
else
|
147
|
+
@ssh.scp.upload! source, destination
|
148
|
+
Dust.print_ok '', options
|
149
|
+
end
|
150
|
+
|
106
151
|
restorecon destination, options # restore SELinux labels
|
107
152
|
end
|
108
153
|
|
@@ -272,12 +317,8 @@ module Dust
|
|
272
317
|
return false
|
273
318
|
end
|
274
319
|
|
275
|
-
Dust.print_result ret[:exit_code], options
|
276
|
-
|
277
|
-
# display stderr and stdout
|
278
|
-
puts
|
279
|
-
puts "#{Dust.grey}#{ret[:stdout]}#{Dust.none}"
|
280
|
-
puts "#{Dust.red}#{ret[:stderr]}#{Dust.none}"
|
320
|
+
Dust.print_result ret[:exit_code], options
|
321
|
+
Dust.print_ret ret, options
|
281
322
|
end
|
282
323
|
|
283
324
|
# determining the system packet manager has to be done without facter
|
@@ -383,29 +424,69 @@ module Dust
|
|
383
424
|
options = default_options.merge options
|
384
425
|
|
385
426
|
Dust.print_msg "autostart #{service} on boot", options
|
427
|
+
|
386
428
|
if uses_rpm?
|
387
|
-
|
429
|
+
if file_exists? '/bin/systemctl', :quiet => true
|
430
|
+
Dust.print_result exec("systemctl enable #{service}.service")[:exit_code], options
|
431
|
+
else
|
432
|
+
Dust.print_result exec("chkconfig #{service} on")[:exit_code], options
|
433
|
+
end
|
434
|
+
|
388
435
|
elsif uses_apt?
|
389
436
|
Dust.print_result exec("update-rc.d #{service} defaults")[:exit_code], options
|
437
|
+
|
390
438
|
elsif uses_emerge?
|
391
439
|
Dust.print_result exec("rc-update add #{service} default")[:exit_code], options
|
392
440
|
end
|
393
441
|
end
|
394
|
-
|
442
|
+
|
443
|
+
# invoke 'command' on the service (e.g. @node.service 'postgresql', 'restart')
|
444
|
+
def service service, command, options = {}
|
445
|
+
options = default_options.merge options
|
446
|
+
|
447
|
+
return ::Dust.print_failed "service: '#{service}' unknown", options unless service.is_a? String
|
448
|
+
|
449
|
+
# try systemd, then upstart, then sysvconfig, then initscript
|
450
|
+
if file_exists? '/bin/systemctl', :quiet => true
|
451
|
+
Dust.print_msg "#{command}ing #{service} (via systemd)", options
|
452
|
+
ret = exec("systemctl #{command} #{service}.service")
|
453
|
+
|
454
|
+
elsif file_exists? "/etc/init/#{service}", :quiet => true
|
455
|
+
Dust.print_msg "#{command}ing #{service} (via upstart)", options
|
456
|
+
ret = exec("#{command} #{service}")
|
457
|
+
|
458
|
+
elsif file_exists? '/sbin/service', :quiet => true or file_exists? '/usr/sbin/service', :quiet => true
|
459
|
+
Dust.print_msg "#{command}ing #{service} (via sysvconfig)", options
|
460
|
+
ret = exec("service #{service} #{command}")
|
461
|
+
|
462
|
+
else
|
463
|
+
Dust.print_msg "#{command}ing #{service} (via initscript)", options
|
464
|
+
ret = exec("/etc/init.d/#{service} #{command}")
|
465
|
+
end
|
466
|
+
|
467
|
+
Dust.print_result ret[:exit_code], options
|
468
|
+
ret
|
469
|
+
end
|
470
|
+
|
395
471
|
def restart_service service, options = {}
|
396
472
|
options = default_options.merge options
|
397
473
|
|
398
|
-
|
399
|
-
Dust.print_result exec("/etc/init.d/#{service} restart")[:exit_code], options
|
474
|
+
service service, 'restart', options
|
400
475
|
end
|
401
|
-
|
476
|
+
|
402
477
|
def reload_service service, options = {}
|
403
478
|
options = default_options.merge options
|
404
479
|
|
405
|
-
|
406
|
-
Dust.print_result exec("/etc/init.d/#{service} reload")[:exit_code], options
|
480
|
+
service service, 'reload', options
|
407
481
|
end
|
408
|
-
|
482
|
+
|
483
|
+
def print_service_status service, options = {}
|
484
|
+
options = default_options.merge options
|
485
|
+
ret = service service, 'status', options
|
486
|
+
Dust.print_ret ret, options
|
487
|
+
ret
|
488
|
+
end
|
489
|
+
|
409
490
|
# check whether a user exists on this node
|
410
491
|
def user_exists? user, options = {}
|
411
492
|
options = default_options.merge options
|
@@ -487,7 +568,7 @@ module Dust
|
|
487
568
|
|
488
569
|
|
489
570
|
private
|
490
|
-
|
571
|
+
|
491
572
|
def method_missing method, *args, &block
|
492
573
|
# make server nodeibutes accessible via server.nodeibute
|
493
574
|
if @node[method.to_s]
|
data/lib/dust/version.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 7
|
8
|
+
- 0
|
9
|
+
version: 0.7.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- kris kechagia
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-02-
|
17
|
+
date: 2012-02-08 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|