gluez 0.2.1 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/gluez.rb CHANGED
@@ -1,168 +1,85 @@
1
- require 'gluez/ext/string'
2
-
3
- require 'gluez/option_wrapper'
4
- require 'gluez/formatter'
5
- require 'gluez/erb/engine'
6
-
7
- require 'gluez/impl/linux'
8
-
9
- module Gluez
10
-
11
- def self.run(entries, cfg={})
12
-
13
- cfg = {
14
- :file_dir => ".",
15
- :simulate => false
16
- }.merge(cfg)
17
-
18
- lines = []
19
- lines << "#!/bin/bash"
20
- # lines << "set -e"
21
-
22
- entries.each do |entry|
23
-
24
- task, name, opts = entry
25
-
26
- opts ||= {}
27
- opts = OptionWrapper.new(opts)
28
-
29
- name, setup, steps = Gluez::Impl::Linux.steps(cfg, task, name, opts)
30
-
31
- steps.each do |step|
32
- if step[:check].is_a?(Array)
33
- step[:check].each_with_index do |check, idx|
34
- step[:check][idx] = step[:check][idx].gsub("\"", "\\\"")
35
- end
36
- else
37
- step[:check] = step[:check].gsub("\"", "\\\"")
38
- end
39
- step[:code] = step[:code].gsub("\"", "\\\"")
40
- end
41
-
42
- entry[1] = name
43
-
44
- fun = function_name(task, name)
45
-
46
- lines << "function #{fun} {"
47
- lines << setup if setup
48
-
49
- notifies = []
50
- opts[:notifies, Array.new].each do |notify|
51
- notify_task, notify_name = notify
52
- notify_fun = function_name(notify_task, notify_name)
53
-
54
- notifies << notify_fun
55
-
56
- unless entries.detect{|entry| entry[0] == notify_task && entry[1] == notify_name}
57
- entries << [notify_task, notify_name, {:embedded => true}]
58
- end
59
- end
60
-
61
- if cfg[:simulate]
62
- generate_simulate(lines, opts[:user, 'root'], fun, steps, notifies)
63
- else
64
- generate_execute(lines, opts[:user, 'root'], fun, steps, notifies)
65
- end
66
-
67
- lines << "}"
68
-
69
- end
70
-
71
- entries.each do |entry|
72
- task, name, opts = entry
73
- opts ||= {}
74
-
75
- lines << function_name(task, name) unless opts[:embedded]
76
- end
77
-
78
- Formatter.format(lines.join("\n"))
1
+ class Object
2
+ def context(&block)
3
+ Gluez::Context.new(&block)
4
+ end
5
+ def recipe(&block)
6
+ $gluez.instance_eval(&block)
7
+ end
8
+ def resource(name, &block)
9
+ Gluez::Context.register(name.to_s.underscore, &block)
79
10
  end
11
+ end
12
+
13
+ # Gluez does a lot of text processing and maniputation. The string class is extended to dry up code.
14
+ class String
80
15
 
81
- private
16
+ # Return the string as underscored version e.g. SomeTextValue becomes some_text_value.
17
+ def underscore
18
+ word = self.dup
19
+ word.gsub!(/::/, '/')
20
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
21
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
22
+ word.tr!("-", "_")
23
+ word.downcase!
24
+ word
25
+ end
82
26
 
83
- def self.function_name(task, name)
84
- "#{task}_#{name}".gsub('/', '_').gsub(':', '_').gsub("@", "_").gsub("~", "_").gsub(".", "_")
27
+ # Return the string as camelcased version e.g. some_text_value becomes SomeTextValue.
28
+ def camelize(first_letter_in_uppercase=true)
29
+ word = self.dup
30
+ if first_letter_in_uppercase
31
+ word.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
32
+ else
33
+ word.to_s[0].chr.downcase + word.camelize[1..-1]
34
+ end
85
35
  end
86
36
 
87
- def self.generate_simulate(lines, user, fun, steps, notifies)
88
-
89
- lines << code_check(steps, user, true)
37
+ end
90
38
 
91
- lines << "if [[ $? -eq 0 ]]; then"
92
- lines << " echo \"[ up2date ] #{fun}\""
93
- lines << "else"
94
- lines << " echo \"[ not up2date ] #{fun}\""
95
-
96
- notifies.each do |notify|
97
- lines << notify
98
- end
99
-
100
- lines << "fi"
39
+ module Gluez
40
+
41
+ def self.args()
42
+ ARGV.select{|a| !(a =~ /^-/)}
101
43
  end
102
44
 
103
- def self.code_check(steps, user, applied)
104
- steps.collect do |step|
45
+ def self.options()
46
+ ARGV.select{|a| a =~ /^-/}
47
+ end
48
+
49
+ # Takes an array of bash code lines and returns it as a nicely formatted string.
50
+ def self.format(lines)
51
+ indent = 0
52
+ num_line = 0
53
+
54
+ prev_line = nil
55
+ lines.split("\n").collect do |line|
56
+ num_line += 1
57
+ begin
58
+ line = line.strip
105
59
 
106
- if step[:check].is_a?(Array)
107
-
108
- step[:check].collect do |check|
109
- "su -l #{user} -c \"test " + check + "\""
110
- end.join(" && ")
111
-
112
- else
113
- "su -l #{user} -c \"test " + step[:check] + "\"" unless (applied && step[:check] == '1 -eq 0')
114
- end
60
+ indent -= 2 if ['}', 'fi', 'else'].include?(line)
115
61
 
116
- end.join(" && ")
117
- end
62
+ l = (' ' * indent) + line
63
+ indent += 2 if [/^function /, /^if /, /^else/].any?{|e| line =~ e}
118
64
 
119
- def self.generate_execute(lines, user, fun, steps, notifies)
120
-
121
- lines << code_check(steps, user, false)
122
-
123
- lines << "if [[ $? -eq 0 ]]; then"
124
- lines << " echo \"[ up2date ] #{fun}\""
125
- lines << "else"
126
-
127
- if steps.length > 1
128
- (0..steps.length-1).to_a.each do |limit|
129
-
130
- lines << code_check(steps[0..limit], user, false)
65
+ indent -= 2 if line.index('cat >~/.gluez_transfer <<\DATA')
66
+ indent += 2 if line == 'DATA"'
67
+
68
+ prev_line = line
69
+
70
+ l
71
+ rescue Exception => e
72
+ puts "error on line: #{num_line}"
73
+ raise e
74
+ end
75
+ end.join("\n")
76
+ end
77
+ end
131
78
 
132
- lines << "if [[ $? -eq 0 ]]; then"
133
- lines << " echo \"[ up2date ] #{fun}\""
134
- lines << "else"
135
-
136
- lines << " su -l #{user} -c \"#{steps[limit][:code]}\""
79
+ $simulate = true if $simulate.nil?
80
+ $env = :development if $env.nil?
137
81
 
138
- lines << code_check(steps[0..limit], user, true)
139
-
140
- lines << " if [[ $? -eq 0 ]]; then"
141
- lines << " echo \"[ applied ] #{fun}\""
142
- lines << " else"
143
- lines << " echo \"[ not applied ] #{fun}\""
144
- lines << " exit 1"
145
- lines << " fi"
146
- lines << "fi"
147
- end
148
- else
149
- lines << " su -l #{user} -c \"#{steps[0][:code]}\""
82
+ require 'gluez/resource'
83
+ require 'gluez/context'
150
84
 
151
- lines << code_check([steps[0]], user, true)
152
-
153
- lines << " if [[ $? -eq 0 ]]; then"
154
- lines << " echo \"[ applied ] #{fun}\""
155
- lines << " else"
156
- lines << " echo \"[ not applied ] #{fun}\""
157
- lines << " exit 1"
158
- lines << " fi"
159
- end
160
-
161
- notifies.each do |notify|
162
- lines << notify
163
- end
164
-
165
- lines << "fi"
166
- end
167
-
168
- end
85
+ Gluez::Context.load_resources
metadata CHANGED
@@ -1,63 +1,66 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: gluez
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.3'
4
5
  prerelease:
5
- version: 0.2.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Jan Zimmek
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-06-06 00:00:00 +02:00
14
- default_executable:
12
+ date: 2011-10-27 00:00:00.000000000Z
15
13
  dependencies: []
16
-
17
14
  description: a server configuration toolkit
18
15
  email: jan.zimmek@web.de
19
16
  executables: []
20
-
21
17
  extensions: []
22
-
23
18
  extra_rdoc_files: []
24
-
25
- files:
26
- - lib/gluez/erb/engine.rb
27
- - lib/gluez/erb/vars.rb
28
- - lib/gluez/ext/string.rb
29
- - lib/gluez/formatter.rb
30
- - lib/gluez/impl/linux.rb
31
- - lib/gluez/impl/mac.rb
32
- - lib/gluez/option_wrapper.rb
19
+ files:
20
+ - lib/gluez/context.rb
21
+ - lib/gluez/resource.rb
22
+ - lib/gluez/resources/bash.rb
23
+ - lib/gluez/resources/bash_once.rb
24
+ - lib/gluez/resources/dir.rb
25
+ - lib/gluez/resources/disable.rb
26
+ - lib/gluez/resources/enable.rb
27
+ - lib/gluez/resources/file.rb
28
+ - lib/gluez/resources/gem.rb
29
+ - lib/gluez/resources/group.rb
30
+ - lib/gluez/resources/link.rb
31
+ - lib/gluez/resources/mount.rb
32
+ - lib/gluez/resources/package.rb
33
+ - lib/gluez/resources/path.rb
34
+ - lib/gluez/resources/restart.rb
35
+ - lib/gluez/resources/source.rb
36
+ - lib/gluez/resources/start.rb
37
+ - lib/gluez/resources/stop.rb
38
+ - lib/gluez/resources/transfer.rb
39
+ - lib/gluez/resources/umount.rb
40
+ - lib/gluez/resources/user.rb
33
41
  - lib/gluez.rb
34
- has_rdoc: true
35
42
  homepage:
36
43
  licenses: []
37
-
38
44
  post_install_message:
39
45
  rdoc_options: []
40
-
41
- require_paths:
46
+ require_paths:
42
47
  - lib
43
- required_ruby_version: !ruby/object:Gem::Requirement
48
+ required_ruby_version: !ruby/object:Gem::Requirement
44
49
  none: false
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: "0"
49
- required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
55
  none: false
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: "0"
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
55
60
  requirements: []
56
-
57
61
  rubyforge_project:
58
- rubygems_version: 1.6.2
62
+ rubygems_version: 1.8.6
59
63
  signing_key:
60
64
  specification_version: 3
61
65
  summary: a system configuration toolkit
62
66
  test_files: []
63
-
@@ -1,19 +0,0 @@
1
- require 'erb'
2
- require 'base64'
3
-
4
- require 'gluez/erb/vars'
5
-
6
- module Gluez
7
- module Erb
8
- class Engine
9
- def self.parse(content, vars={})
10
- v = Gluez::Vars.new(vars)
11
-
12
- erb = ERB.new(content)
13
- content2 = erb.result(v.get_binding)
14
-
15
- Base64.encode64(content2)
16
- end
17
- end
18
- end
19
- end
@@ -1,19 +0,0 @@
1
- module Gluez
2
- class Vars
3
- def initialize(hash={})
4
- hash.each_pair do |key, val|
5
- self.metaclass.send(:define_method, key) do
6
- val
7
- end
8
- end
9
- end
10
-
11
- def metaclass
12
- class << self; self; end
13
- end
14
-
15
- def get_binding
16
- binding
17
- end
18
- end
19
- end
@@ -1,18 +0,0 @@
1
- class String
2
- def strip2
3
- unless self.empty?
4
- lines = self.split("\n")
5
- indent = 0
6
- lines[0].each_char do |char|
7
- if char == " "
8
- indent += 1
9
- else
10
- break
11
- end
12
- end
13
- lines.collect{|line| line.gsub(/^([ ]{0,#{indent}})/, "")}.join("\n")
14
- else
15
- self
16
- end
17
- end
18
- end
@@ -1,32 +0,0 @@
1
- module Gluez
2
- class Formatter
3
- def self.format(lines)
4
- indent = 0
5
- num_line = 0
6
-
7
- prev_line = nil
8
- lines.split("\n").collect do |line|
9
- num_line += 1
10
- begin
11
- line = line.strip
12
-
13
- indent -= 2 if ['}', 'fi', 'else'].include?(line)
14
-
15
- l = (' ' * indent) + line
16
- indent += 2 if [/^function /, /^if /, /^else/].any?{|e| line =~ e}
17
-
18
- # indent -= 2 if line =~ /^data=/
19
- indent -= 2 if line.index('cat >~/.gluez_transfer <<\DATA')
20
- indent += 2 if line == '"' && prev_line == 'DATA'
21
-
22
- prev_line = line
23
-
24
- l
25
- rescue Exception => e
26
- puts "error on line: #{num_line}"
27
- raise e
28
- end
29
- end.join("\n")
30
- end
31
- end
32
- end
@@ -1,233 +0,0 @@
1
- module Gluez
2
- module Impl
3
- class Linux
4
- def self.steps(cfg, task, name, opts)
5
-
6
- setup = nil
7
- steps = []
8
-
9
- case task
10
- when :gem
11
- steps << {
12
- :check => "\\$(gem list | awk '{print \\$1}' | grep ^#{name}$ | wc -l) -eq 1",
13
- :code => "gem install #{name} --version #{opts[:version]} --user-install --no-rdoc --no-ri"
14
- }
15
-
16
- when :file
17
- steps << {
18
- :check => "-f #{name}",
19
- :code => "touch #{name}"
20
- }
21
-
22
- steps << {
23
- :check => %Q("\\$(stat -L --format=%a #{name})" = "#{opts[:chmod, "644"]}"),
24
- :code => "chmod #{opts[:chmod, "644"]} #{name}"
25
- }
26
-
27
- when :dir
28
- steps << {
29
- :check => "-d #{name}",
30
- :code => "mkdir #{name}"
31
- }
32
-
33
- steps << {
34
- :check => %Q("\\$(stat -L --format=%a #{name})" = "#{opts[:chmod, "755"]}"),
35
- :code => "chmod #{opts[:chmod, "755"]} #{name}"
36
- }
37
-
38
- when :package
39
- steps << {
40
- :check => [
41
- "\\$(apt-cache policy #{name} | grep Installed | wc -l) -eq 1",
42
- "\\$(apt-cache policy #{name} | grep Installed | grep '(none)' | wc -l) -eq 0"
43
- ],
44
- :code => "apt-get install #{name} --yes"
45
- }
46
-
47
- when :crontab
48
- default_file = "crontab.#{name}.erb"
49
-
50
- raw = File.read(cfg[:file_dir] + "/files/" + opts[:source, default_file])
51
-
52
- content = Gluez::Erb::Engine.parse(raw, opts[:vars, {}])
53
-
54
- # setup = <<-CMD
55
- # data=$(cat <<\\DATA
56
- # #{content.strip}
57
- # DATA
58
- # )
59
- # CMD
60
-
61
- setup = <<-CMD
62
- su -l #{opts[:user, 'root']} -c "cat >~/.gluez_transfer <<\\DATA
63
- #{content.strip}
64
- DATA
65
- "
66
- CMD
67
-
68
-
69
- steps << {
70
- :check => %Q("\\$(cat ~/.gluez_transfer | base64 -i -d - | md5sum - | awk '{print \\$1}')" = "\\$(crontab -u #{name} -l | md5sum - | awk '{print \\$1}')"),
71
- :code => "cat ~/.gluez_transfer | base64 -i -d - | crontab -u #{name} -"
72
- }
73
-
74
- when :transfer
75
- default_file = name.split("/").last.gsub(/^\./, "") + ".erb"
76
-
77
- raw = File.read(cfg[:file_dir] + "/files/" + opts[:source, default_file])
78
-
79
- content = Gluez::Erb::Engine.parse(raw, opts[:vars, {}])
80
-
81
- setup = <<-CMD
82
- su -l #{opts[:user, 'root']} -c "cat >~/.gluez_transfer <<\\DATA
83
- #{content.strip}
84
- DATA
85
- "
86
- CMD
87
-
88
- steps << {
89
- :check => "-f #{name}",
90
- :code => "touch #{name}"
91
- }
92
-
93
- steps << {
94
- :check => %Q("\\$(stat -L --format=%a #{name})" = "#{opts[:chmod, "644"]}"),
95
- :code => "chmod #{opts[:chmod, "644"]} #{name}"
96
- }
97
-
98
- steps << {
99
- :check => %Q("\\$(cat ~/.gluez_transfer | base64 -i -d - | md5sum - | awk '{print \\$1}')" = "\\$(md5sum #{name} | awk '{print \\$1}')"),
100
- :code => "chmod +w #{name} && cat ~/.gluez_transfer | base64 -i -d - > #{name} && chmod #{opts[:chmod, "644"]} #{name}"
101
- }
102
-
103
- when :group
104
- steps << {
105
- :check => "$(cat /etc/group | grep ^#{name}: | wc -l) -eq 1",
106
- :code => "groupadd --gid #{opts[:gid]} #{name}"
107
- }
108
-
109
- when :user
110
- steps << {
111
- :check => "$(cat /etc/passwd | grep ^#{name}: | wc -l) -eq 1",
112
- :code => "useradd --create-home --uid #{opts[:uid]} --gid #{opts[:gid]} --shell #{opts[:shell, "/bin/bash"]} #{name}"
113
- }
114
-
115
- when :start
116
- setup = "service --status-all 1>/tmp/gluez.tmp 2>&1"
117
-
118
- steps << {
119
- :check => [
120
- %Q("\\$(grep #{name} /tmp/gluez.tmp | wc -l)" = "1"),
121
- %Q("\\$(service #{name} status | grep -E 'is running|start/running' | wc -l)" = "1")
122
- ],
123
-
124
- :code => "service #{name} start"
125
- }
126
-
127
- when :stop
128
- setup = "service --status-all 1>/tmp/gluez.tmp 2>&1"
129
- steps << {
130
- :check => [
131
- %Q("\\$(grep #{name} /tmp/gluez.tmp | wc -l)" = "1"),
132
- %Q("\\$(service #{name} status | grep -E 'is running|start/running' | wc -l)" = "0"),
133
- ],
134
- :code => "service #{name} stop"
135
- }
136
-
137
- when :restart
138
- setup = "service --status-all 1>/tmp/gluez.tmp 2>&1"
139
-
140
- steps << {
141
- :check => '1 -eq 0',
142
- :code => "service #{name} restart"
143
- }
144
-
145
- when :bash
146
- steps << {
147
- :check => opts[:not_if],
148
- :code => opts[:code]
149
- }
150
-
151
- when :bash_once
152
- home_dir = (opts[:user, 'root'] == 'root') ? "/root" : "/home/#{opts[:user, 'root']}"
153
- steps << {
154
- :check => "-f #{home_dir}/.gluez/#{name}",
155
- :code => opts[:code] + "\n" + "touch #{home_dir}/.gluez/#{name}"
156
- }
157
-
158
- when :bundler
159
- steps << {
160
- :check => "\"\\$(cd #{name} && bundle check > /dev/null && echo 'up2date')\" = \"up2date\"",
161
- :code => "cd #{name} && bundle install"
162
- }
163
-
164
- when :umount
165
- steps << {
166
- :check => "\\$(mount | grep \"on #{name} type\" | wc -l) -eq 0",
167
- :code => "umount #{name}"
168
- }
169
-
170
- when :mount
171
-
172
- cmd = "mount -t #{opts[:type]}"
173
- cmd = "#{cmd} -o #{opts[:options]}" if opts.key?(:options)
174
- cmd = "#{cmd} #{opts[:device]} #{name}"
175
-
176
- steps << {
177
- :check => "\\$(mount | grep \"on #{name} type\" | wc -l) -eq 1",
178
- :code => cmd
179
- }
180
-
181
- when :link
182
- steps << {
183
- :check => [
184
- "-L #{name}",
185
- "\\$(file #{name} | grep \"#{name.gsub('~', '\$HOME')}: symbolic link to \\\\\\`#{opts[:target].gsub('~', '\$HOME')}'\" | wc -l) -eq 1"
186
- ],
187
- :code => "ln -f -s #{opts[:target]} #{name}"
188
- }
189
-
190
- when :enable
191
- steps << {
192
- :check => "\\$(update-rc.d -n -f #{name} remove | grep '/etc/rc' | wc -l) -gt 0",
193
- :code => "/usr/sbin/update-rc.d #{name} defaults"
194
- }
195
-
196
- when :disable
197
- steps << {
198
- :check => "\\$(update-rc.d -n -f #{name} remove | grep '/etc/rc' | wc -l) -eq 0",
199
- :code => "/usr/sbin/update-rc.d -f #{name} remove"
200
- }
201
-
202
- when :source
203
- user = opts[:user, "root"]
204
- home_dir = (user != "root") ? "/home/#{opts[:user]}" : "/root"
205
-
206
- steps << {
207
- :check => "-d ~/tmp",
208
- :code => "mkdir ~/tmp"
209
- }
210
-
211
- steps << {
212
- :check => opts[:test],
213
- :code => <<-CODE
214
- [ -f ~/tmp/#{opts[:filename]} ] && rm ~/tmp/#{opts[:filename]}
215
- [ -d ~/tmp/#{opts[:folder]} ] && rm -rf ~/tmp/#{opts[:folder]}
216
-
217
- wget --no-check-certificate -O ~/tmp/#{opts[:filename]} #{name}
218
- tar -C ~/tmp/ -x#{opts[:filename] =~ /\.tar\.bz2/ ? "j" : "z"}f ~/tmp/#{opts[:filename]}
219
- cd ~/tmp/#{opts[:folder]} && #{opts[:steps].join(' && ')}
220
- CODE
221
- }
222
-
223
- else
224
- raise "unsupported task: #{task}, name: #{name}, opts: #{opts.inspect}"
225
- end
226
-
227
- name = "#{name}@#{opts[:user]}" if opts.key?(:user)
228
-
229
- [name, setup, steps]
230
- end
231
- end
232
- end
233
- end