gluez 0.2.1 → 0.3

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/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