angry_mob_common_targets 0.1.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/LICENSE +21 -0
- data/README.md +38 -0
- data/lib/common_mob.rb +9 -0
- data/lib/common_mob/digest.rb +43 -0
- data/lib/common_mob/erb.rb +72 -0
- data/lib/common_mob/file.rb +55 -0
- data/lib/common_mob/patch.rb +51 -0
- data/lib/common_mob/resource_locator.rb +9 -0
- data/lib/common_mob/shell.rb +323 -0
- data/lib/common_mob/template.rb +23 -0
- data/lib/common_mob/version.rb +3 -0
- data/targets/crontab_patch.rb +37 -0
- data/targets/extract.rb +40 -0
- data/targets/fetch.rb +40 -0
- data/targets/files.rb +244 -0
- data/targets/git.rb +84 -0
- data/targets/group.rb +33 -0
- data/targets/packages.rb +94 -0
- data/targets/ruby.rb +13 -0
- data/targets/services.rb +184 -0
- data/targets/shell.rb +43 -0
- data/targets/user.rb +108 -0
- data/vendor/mustache/CONTRIBUTORS +9 -0
- data/vendor/mustache/HISTORY.md +135 -0
- data/vendor/mustache/LICENSE +20 -0
- data/vendor/mustache/README.md +405 -0
- data/vendor/mustache/Rakefile +103 -0
- data/vendor/mustache/benchmarks/complex.erb +15 -0
- data/vendor/mustache/benchmarks/complex.haml +12 -0
- data/vendor/mustache/benchmarks/helper.rb +20 -0
- data/vendor/mustache/benchmarks/simple.erb +5 -0
- data/vendor/mustache/benchmarks/speed.rb +78 -0
- data/vendor/mustache/bin/mustache +90 -0
- data/vendor/mustache/contrib/mustache-mode.el +278 -0
- data/vendor/mustache/contrib/mustache.vim +69 -0
- data/vendor/mustache/examples/hash.rb +16 -0
- data/vendor/mustache/examples/hash.yml +5 -0
- data/vendor/mustache/examples/projects.mustache +26 -0
- data/vendor/mustache/examples/projects.yml +28 -0
- data/vendor/mustache/examples/self.mustache +4 -0
- data/vendor/mustache/examples/self.yml +3 -0
- data/vendor/mustache/examples/simple.mustache +10 -0
- data/vendor/mustache/examples/simple.rb +24 -0
- data/vendor/mustache/lib/mustache.rb +358 -0
- data/vendor/mustache/lib/mustache/context.rb +108 -0
- data/vendor/mustache/lib/mustache/generator.rb +160 -0
- data/vendor/mustache/lib/mustache/parser.rb +230 -0
- data/vendor/mustache/lib/mustache/sinatra.rb +180 -0
- data/vendor/mustache/lib/mustache/template.rb +59 -0
- data/vendor/mustache/lib/mustache/version.rb +3 -0
- data/vendor/mustache/lib/rack/bug/panels/mustache_panel.rb +81 -0
- data/vendor/mustache/lib/rack/bug/panels/mustache_panel/mustache_extension.rb +27 -0
- data/vendor/mustache/lib/rack/bug/panels/mustache_panel/view.mustache +46 -0
- data/vendor/mustache/man/mustache.1 +180 -0
- data/vendor/mustache/man/mustache.1.html +204 -0
- data/vendor/mustache/man/mustache.1.ron +127 -0
- data/vendor/mustache/man/mustache.5 +576 -0
- data/vendor/mustache/man/mustache.5.html +415 -0
- data/vendor/mustache/man/mustache.5.ron +324 -0
- data/vendor/mustache/mustache.gemspec +32 -0
- data/vendor/mustache/test/autoloading_test.rb +52 -0
- data/vendor/mustache/test/fixtures/comments.mustache +1 -0
- data/vendor/mustache/test/fixtures/comments.rb +14 -0
- data/vendor/mustache/test/fixtures/complex_view.mustache +17 -0
- data/vendor/mustache/test/fixtures/complex_view.rb +34 -0
- data/vendor/mustache/test/fixtures/crazy_recursive.mustache +9 -0
- data/vendor/mustache/test/fixtures/crazy_recursive.rb +31 -0
- data/vendor/mustache/test/fixtures/delimiters.mustache +8 -0
- data/vendor/mustache/test/fixtures/delimiters.rb +23 -0
- data/vendor/mustache/test/fixtures/double_section.mustache +7 -0
- data/vendor/mustache/test/fixtures/double_section.rb +14 -0
- data/vendor/mustache/test/fixtures/escaped.mustache +1 -0
- data/vendor/mustache/test/fixtures/escaped.rb +14 -0
- data/vendor/mustache/test/fixtures/inner_partial.mustache +1 -0
- data/vendor/mustache/test/fixtures/inner_partial.txt +1 -0
- data/vendor/mustache/test/fixtures/inverted_section.mustache +7 -0
- data/vendor/mustache/test/fixtures/inverted_section.rb +14 -0
- data/vendor/mustache/test/fixtures/lambda.mustache +7 -0
- data/vendor/mustache/test/fixtures/lambda.rb +31 -0
- data/vendor/mustache/test/fixtures/namespaced.mustache +1 -0
- data/vendor/mustache/test/fixtures/namespaced.rb +25 -0
- data/vendor/mustache/test/fixtures/nested_objects.mustache +17 -0
- data/vendor/mustache/test/fixtures/nested_objects.rb +35 -0
- data/vendor/mustache/test/fixtures/node.mustache +8 -0
- data/vendor/mustache/test/fixtures/partial_with_module.mustache +3 -0
- data/vendor/mustache/test/fixtures/partial_with_module.rb +37 -0
- data/vendor/mustache/test/fixtures/passenger.conf +5 -0
- data/vendor/mustache/test/fixtures/passenger.rb +27 -0
- data/vendor/mustache/test/fixtures/recursive.mustache +4 -0
- data/vendor/mustache/test/fixtures/recursive.rb +14 -0
- data/vendor/mustache/test/fixtures/simple.mustache +5 -0
- data/vendor/mustache/test/fixtures/simple.rb +26 -0
- data/vendor/mustache/test/fixtures/template_partial.mustache +2 -0
- data/vendor/mustache/test/fixtures/template_partial.rb +18 -0
- data/vendor/mustache/test/fixtures/template_partial.txt +4 -0
- data/vendor/mustache/test/fixtures/unescaped.mustache +1 -0
- data/vendor/mustache/test/fixtures/unescaped.rb +14 -0
- data/vendor/mustache/test/fixtures/utf8.mustache +3 -0
- data/vendor/mustache/test/fixtures/utf8_partial.mustache +1 -0
- data/vendor/mustache/test/helper.rb +7 -0
- data/vendor/mustache/test/mustache_test.rb +536 -0
- data/vendor/mustache/test/parser_test.rb +54 -0
- data/vendor/mustache/test/partial_test.rb +168 -0
- metadata +167 -0
data/targets/group.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'common_mob'
|
|
2
|
+
require 'etc'
|
|
3
|
+
|
|
4
|
+
class Group < AngryMob::Target
|
|
5
|
+
include CommonMob::ShellHelper
|
|
6
|
+
|
|
7
|
+
default_action
|
|
8
|
+
def ensure
|
|
9
|
+
unless before_state[:exists]
|
|
10
|
+
create
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create
|
|
15
|
+
log "creating #{default_object}"
|
|
16
|
+
sh("groupadd #{default_object}").run
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
protected
|
|
20
|
+
def state
|
|
21
|
+
begin
|
|
22
|
+
group = Etc.getgrnam(default_object)
|
|
23
|
+
{
|
|
24
|
+
:exists => true
|
|
25
|
+
}
|
|
26
|
+
rescue ArgumentError
|
|
27
|
+
{
|
|
28
|
+
:exists => false
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
data/targets/packages.rb
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'common_mob'
|
|
2
|
+
|
|
3
|
+
class Apt < AngryMob::Target
|
|
4
|
+
include CommonMob::ShellHelper
|
|
5
|
+
|
|
6
|
+
default_action
|
|
7
|
+
def install
|
|
8
|
+
if args.version && !before_state[:version_matches]
|
|
9
|
+
# TODO - install with version
|
|
10
|
+
sh("apt-get install -y #{default_object}").run
|
|
11
|
+
elsif !before_state[:installed]
|
|
12
|
+
sh("apt-get install -y #{default_object}").run
|
|
13
|
+
else
|
|
14
|
+
log "no need to install #{default_object}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def upgrade
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def uninstall
|
|
22
|
+
if before_state[:installed]
|
|
23
|
+
sh("apt-get remove -y #{default_object}").run
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
protected
|
|
28
|
+
|
|
29
|
+
def state
|
|
30
|
+
version = sh("apt-cache policy #{default_object}").to_s[/^\s+Installed: (.*)$/, 1]
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
:installed => (version != '(none)'),
|
|
34
|
+
:version_matches => (version == args.version),
|
|
35
|
+
:installable => !version.nil?
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
protected
|
|
40
|
+
def before_call
|
|
41
|
+
skip! unless before_state[:installable]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class AptSource < AngryMob::Target
|
|
47
|
+
include CommonMob::ShellHelper
|
|
48
|
+
default_action
|
|
49
|
+
def install
|
|
50
|
+
act.in_sub_act { apt 'python-software-properties' }
|
|
51
|
+
# TODO make null op less expensive
|
|
52
|
+
sh("add-apt-repository #{default_object} && apt-get update").run
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class GemPackage < AngryMob::Target
|
|
57
|
+
nickname 'gem'
|
|
58
|
+
|
|
59
|
+
include CommonMob::ShellHelper
|
|
60
|
+
|
|
61
|
+
default_action
|
|
62
|
+
def install
|
|
63
|
+
gemsh("install #{default_object} #{gem_version}").run unless before_state[:installed]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def upgrade
|
|
67
|
+
gemsh("update #{default_object}").run
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def uninstall
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
protected
|
|
74
|
+
|
|
75
|
+
def state
|
|
76
|
+
{
|
|
77
|
+
:installed => installed?
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def gem_version
|
|
82
|
+
args.version.blank? ? '' : " -v '#{args.version}'"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# works around bundler being a bit pushy
|
|
86
|
+
def gemsh(*args)
|
|
87
|
+
args[0] = "gem #{args[0]}"
|
|
88
|
+
sh(*args)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def installed?
|
|
92
|
+
gemsh("list -i #{gem_version} #{default_object}").to_s.strip == 'true'
|
|
93
|
+
end
|
|
94
|
+
end
|
data/targets/ruby.rb
ADDED
data/targets/services.rb
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
require 'common_mob'
|
|
2
|
+
|
|
3
|
+
class Service < AngryMob::Target
|
|
4
|
+
include CommonMob::ShellHelper
|
|
5
|
+
|
|
6
|
+
def self.instance_key(args)
|
|
7
|
+
"service:#{nickname}"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
default_action
|
|
11
|
+
def enable
|
|
12
|
+
unless before_state[:enabled]
|
|
13
|
+
begin
|
|
14
|
+
sh("/usr/sbin/update-rc.d #{name} defaults").run
|
|
15
|
+
rescue CommonMob::ShellError
|
|
16
|
+
# can't really be expected to enable before init.d exists
|
|
17
|
+
if ! $!.result.stderr[/file does not exist$/]
|
|
18
|
+
raise $!
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
log "enabled service #{nickname}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def disable
|
|
26
|
+
if before_state[:enabled]
|
|
27
|
+
sh("/usr/sbin/update-rc.d -f #{name} remove").run
|
|
28
|
+
log "disabled service #{nickname}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def start
|
|
33
|
+
initd('start')
|
|
34
|
+
ensure_running!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def stop
|
|
38
|
+
initd('stop')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def restart
|
|
42
|
+
if is_running?
|
|
43
|
+
ui.log "restarting."
|
|
44
|
+
initd('restart', true)
|
|
45
|
+
else
|
|
46
|
+
ui.log "restart requested, but not running: starting."
|
|
47
|
+
initd('start')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
ensure_running!
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def reload
|
|
54
|
+
if is_running?
|
|
55
|
+
ui.log "reloading."
|
|
56
|
+
initd('reload', true)
|
|
57
|
+
else
|
|
58
|
+
ui.log "reload requested, but not running: starting."
|
|
59
|
+
initd('start')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
ensure_running!
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def be_running
|
|
66
|
+
start
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def to_s
|
|
71
|
+
"#{nickname}()"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
protected
|
|
75
|
+
def validate!
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def state
|
|
79
|
+
enabled = sh("/usr/sbin/update-rc.d -n -f #{name} remove").to_s[%r[/etc/rc\d+.d/]]
|
|
80
|
+
|
|
81
|
+
{
|
|
82
|
+
:enabled => enabled
|
|
83
|
+
}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def name
|
|
87
|
+
nickname
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def self.service_name(name)
|
|
91
|
+
self.class_eval "def name; '#{name}' end"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def initd(command,should_raise=false)
|
|
95
|
+
should_raise = raise_on_failed_initd?
|
|
96
|
+
begin
|
|
97
|
+
sh("/etc/init.d/#{name} #{command}").run
|
|
98
|
+
rescue CommonMob::ShellError
|
|
99
|
+
if should_raise
|
|
100
|
+
raise $!
|
|
101
|
+
else
|
|
102
|
+
log "/etc/init.d/#{name} #{command} failed (but swallowing exception)"
|
|
103
|
+
log "(out=#{$!.result.stdout})"
|
|
104
|
+
log "(err=#{$!.result.stderr})"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def raise_on_failed_initd?
|
|
111
|
+
false
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def self.pidfile(pidfile)
|
|
115
|
+
self.class_eval %{
|
|
116
|
+
def pidfile; "#{pidfile}" end
|
|
117
|
+
def process_approach; :pid end
|
|
118
|
+
}
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def process_approach
|
|
122
|
+
:initd
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def pidfile
|
|
126
|
+
raise "Not implemented. To use the pid based process approach, please override pidfile in #{self.class}."
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def ensure_running!
|
|
130
|
+
case process_approach
|
|
131
|
+
when :initd
|
|
132
|
+
ensure_running_with_initd!
|
|
133
|
+
when :pid
|
|
134
|
+
ensure_running_with_pid!
|
|
135
|
+
else
|
|
136
|
+
raise ArgumentError, "Unknown process_approach '#{process_approach}'\nSet the process approach to :initd or :pid\ndef process_approach\n\t:initd\nend"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def is_running?
|
|
141
|
+
case process_approach
|
|
142
|
+
when :initd
|
|
143
|
+
is_running_initd?
|
|
144
|
+
when :pid
|
|
145
|
+
is_running_pid?
|
|
146
|
+
else
|
|
147
|
+
raise ArgumentError, "Unknown process_approach '#{process_approach}'\nSet the process approach to :initd or :pid\ndef process_approach\n\t:initd\nend"
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def is_running_initd?
|
|
152
|
+
sh("/etc/init.d/#{name} status").ok?
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def is_running_pid?
|
|
156
|
+
pid = pidfile.pathname.read.chomp.to_i
|
|
157
|
+
Process.kill(0,pid)
|
|
158
|
+
true
|
|
159
|
+
rescue Errno::ENOENT,Errno::ESRCH
|
|
160
|
+
false
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def ensure_running_with_initd!
|
|
164
|
+
unless sh("/etc/init.d/#{name} status").ok?
|
|
165
|
+
raise "#{name} should be running but isn't"
|
|
166
|
+
end
|
|
167
|
+
log "#{name} is running"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def ensure_running_with_pid!
|
|
171
|
+
pid = pidfile.pathname.read.chomp.to_i
|
|
172
|
+
Process.kill(0,pid)
|
|
173
|
+
true
|
|
174
|
+
rescue Errno::ENOENT
|
|
175
|
+
raise "#{name} not running: no pidfile found at #{pidfile}"
|
|
176
|
+
rescue Errno::ESRCH
|
|
177
|
+
raise "#{name} not running: no process with pid #{pid} found (pidfile at #{pidfile})"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def at_least_lucid?
|
|
181
|
+
issue = "/etc/issue".pathname
|
|
182
|
+
issue.exist? && issue.read[/ubuntu.+10\.04/i]
|
|
183
|
+
end
|
|
184
|
+
end
|
data/targets/shell.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'common_mob'
|
|
2
|
+
|
|
3
|
+
class Sh < AngryMob::Target
|
|
4
|
+
include CommonMob::ShellHelper
|
|
5
|
+
|
|
6
|
+
default_action
|
|
7
|
+
def execute
|
|
8
|
+
if ! before_state[:created]
|
|
9
|
+
begin
|
|
10
|
+
sh(default_object, opts).run
|
|
11
|
+
rescue CommonMob::ShellError
|
|
12
|
+
if args.swallow_error?
|
|
13
|
+
log "command failed, but ignoring"
|
|
14
|
+
else
|
|
15
|
+
raise $!
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
protected
|
|
22
|
+
|
|
23
|
+
def opts
|
|
24
|
+
opts = AngryHash[ args ]
|
|
25
|
+
|
|
26
|
+
opts.delete_all_of(%w{notify action default_object creates})
|
|
27
|
+
|
|
28
|
+
opts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def state
|
|
32
|
+
if args.creates
|
|
33
|
+
{
|
|
34
|
+
:created => args.creates.pathname.exist?
|
|
35
|
+
}
|
|
36
|
+
else # force state changed if we don't have any state comparison to go on
|
|
37
|
+
{
|
|
38
|
+
:rand => rand
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
data/targets/user.rb
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
require 'common_mob'
|
|
2
|
+
require 'etc'
|
|
3
|
+
|
|
4
|
+
class User < AngryMob::Target
|
|
5
|
+
include CommonMob::ShellHelper
|
|
6
|
+
|
|
7
|
+
default_action
|
|
8
|
+
def ensure
|
|
9
|
+
if before_state[:exists] then update else create end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create
|
|
13
|
+
opt_string = opts
|
|
14
|
+
|
|
15
|
+
unless opt_string.blank?
|
|
16
|
+
log "creating #{default_object}"
|
|
17
|
+
sh("useradd #{opts} #{default_object}").run
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def update
|
|
22
|
+
opt_string = opts
|
|
23
|
+
|
|
24
|
+
unless opt_string.blank?
|
|
25
|
+
log "updating #{default_object}"
|
|
26
|
+
sh("usermod #{opts} #{default_object}").run
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def delete
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def lock
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def unlock
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
protected
|
|
40
|
+
|
|
41
|
+
def state
|
|
42
|
+
begin
|
|
43
|
+
user = Etc.getpwnam(default_object)
|
|
44
|
+
|
|
45
|
+
groups = []
|
|
46
|
+
|
|
47
|
+
username = default_object
|
|
48
|
+
Etc.group do |g|
|
|
49
|
+
groups << g.name if g.mem.include?(username)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
extra_groups = groups.uniq - [ Etc.getgrgid(user.gid).name ]
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
:exists => true,
|
|
56
|
+
:uid => user.uid,
|
|
57
|
+
:gid => user.gid,
|
|
58
|
+
:comment => user.gecos,
|
|
59
|
+
:home => user.dir,
|
|
60
|
+
:shell => user.shell,
|
|
61
|
+
:extra_groups => extra_groups
|
|
62
|
+
}
|
|
63
|
+
rescue ArgumentError => e
|
|
64
|
+
{
|
|
65
|
+
:exists => false
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def default_object
|
|
72
|
+
super.to_s
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def validate!
|
|
76
|
+
super
|
|
77
|
+
problem!("username is blank") if default_object.blank?
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
protected
|
|
81
|
+
def opts
|
|
82
|
+
opts = ''
|
|
83
|
+
switches = {
|
|
84
|
+
:comment => '-c',
|
|
85
|
+
:gid => '-g',
|
|
86
|
+
:uid => '-u',
|
|
87
|
+
:shell => '-s',
|
|
88
|
+
:set_home => lambda {|value| "-d '#{value}'" },
|
|
89
|
+
:home => lambda {|value| "-d '#{value}' -m"},
|
|
90
|
+
:extra_groups => lambda {|value| "-G #{value * ','}"}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
switches.each do |(key,switch)|
|
|
94
|
+
to_value = args.__send__(key)
|
|
95
|
+
|
|
96
|
+
if !to_value.nil? && to_value != before_state[key]
|
|
97
|
+
if switch.respond_to?(:call)
|
|
98
|
+
opts << switch.call(to_value)
|
|
99
|
+
else
|
|
100
|
+
opts << " #{switch} '#{to_value}'"
|
|
101
|
+
end
|
|
102
|
+
opts << ' '
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
opts
|
|
107
|
+
end
|
|
108
|
+
end
|