gluez 0.1

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/bin/gluez ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ # /usr/bin/env ruby "require gluez; Gluez::run"
data/lib/gluez.rb ADDED
@@ -0,0 +1,129 @@
1
+ require 'json'
2
+
3
+ require 'gluez/ext/string'
4
+
5
+ require 'gluez/option_wrapper'
6
+ require 'gluez/formatter'
7
+ require 'gluez/erb/engine'
8
+
9
+ require 'gluez/impl/linux'
10
+ # require 'gluez/impl/mac'
11
+
12
+ module Gluez
13
+
14
+ def self.run(entries, cfg={})
15
+
16
+ cfg = {
17
+ :file_dir => "."
18
+ }.merge(cfg)
19
+
20
+ lines = []
21
+ lines << "#!/bin/bash"
22
+ # lines << "set -x"
23
+ lines << "set -e"
24
+
25
+ entries.each do |entry|
26
+
27
+ task, name, opts = entry
28
+
29
+ opts ||= {}
30
+ opts = OptionWrapper.new(opts)
31
+
32
+ name, setup, steps = Gluez::Impl::Linux.steps(cfg, task, name, opts)
33
+ entry[1] = name
34
+
35
+ fun = function_name(task, name)
36
+
37
+ lines << "function #{fun} {"
38
+ lines << setup if setup
39
+
40
+ notifies = []
41
+ opts[:notifies, Array.new].each do |notify|
42
+ notify_task, notify_name = notify
43
+ notify_fun = function_name(notify_task, notify_name)
44
+
45
+ notifies << notify_fun
46
+
47
+ unless entries.detect{|entry| entry[0] == notify_task && entry[1] == notify_name}
48
+ entries << [notify_task, notify_name, {:embedded => true}]
49
+ end
50
+ end
51
+
52
+ add_steps(true, lines, [], [fun, steps], notifies)
53
+
54
+ lines << "}"
55
+
56
+ end
57
+
58
+ entries.each do |entry|
59
+ task, name, opts = entry
60
+ opts ||= {}
61
+
62
+ lines << function_name(task, name) unless opts[:embedded]
63
+ end
64
+
65
+
66
+ Formatter.format(lines.join("\n"))
67
+ end
68
+
69
+ private
70
+
71
+ def self.function_name(task, name)
72
+ "#{task}_#{name}".gsub('/', '_').gsub(':', '_').gsub("@", "_").gsub("~", "_").gsub(".", "_")
73
+ end
74
+
75
+ def self.add_steps(first, lines, completed, steps_wrapper, notifies)
76
+
77
+ fun, steps = steps_wrapper
78
+
79
+ if first
80
+ if steps.length == 2
81
+ add_steps(false, lines, [], [fun, steps], notifies)
82
+ else
83
+ checks = []
84
+ steps.each_with_index do |step, idx|
85
+ checks << step if idx % 2 == 0
86
+ end
87
+
88
+ lines << "if [[ #{checks.join(' && ')} ]]; then"
89
+ lines << " echo \"[ #{fun} ] up2date\""
90
+ lines << "else"
91
+ lines << " echo \"[ #{fun} ] NOT up2date\""
92
+ add_steps(false, lines, [], [fun, steps], notifies)
93
+ lines << "fi"
94
+ end
95
+
96
+ else
97
+ check, code = steps.slice!(0,2)
98
+
99
+ if check == "1 -eq 0"
100
+ completed << "1 -eq 1"
101
+ else
102
+ completed << check
103
+ end
104
+
105
+ lines << "if [[ #{check} ]]; then"
106
+ lines << " echo \"[ #{fun} ] up2date\""
107
+ lines << "else"
108
+ lines << " #{code}"
109
+ lines << " if [[ #{completed.join(' && ')} ]]; then"
110
+ lines << " echo \"[ #{fun} ] applied\""
111
+ lines << " else"
112
+ lines << " exit 1"
113
+ lines << " fi"
114
+
115
+ lines << "fi"
116
+
117
+ if steps.empty?
118
+ notifies.each do |notify|
119
+ lines << notify
120
+ end
121
+ else
122
+ add_steps(false, lines, completed, [fun, steps], notifies)
123
+ end
124
+ end
125
+
126
+
127
+ end
128
+
129
+ end
@@ -0,0 +1,19 @@
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
@@ -0,0 +1,19 @@
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
@@ -0,0 +1,18 @@
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
@@ -0,0 +1,24 @@
1
+ module Gluez
2
+ class Formatter
3
+ def self.format(lines)
4
+ indent = 0
5
+
6
+ prev_line = nil
7
+ lines.split("\n").collect do |line|
8
+ line = line.strip
9
+
10
+ indent -= 2 if ['}', 'fi', 'else'].include?(line)
11
+
12
+ l = (' ' * indent) + line
13
+ indent += 2 if [/^function /, /^if /, /^else/].any?{|e| line =~ e}
14
+
15
+ indent -= 2 if line =~ /^data=/
16
+ indent += 2 if line == ')' && prev_line == 'DATA'
17
+
18
+ prev_line = line
19
+
20
+ l
21
+ end.join("\n")
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,146 @@
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 << "$(su -l #{opts[:user]} -c \"gem list | awk '{print \\$1}' | grep ^#{name}$ | wc -l\") -eq 1"
12
+ steps << "su -l #{opts[:user]} -c \"gem install #{name} --version #{opts[:version]} --user-install --no-rdoc --no-ri\""
13
+
14
+ name = "#{name}@#{opts[:user]}"
15
+
16
+ when :file
17
+ steps << "-f #{name}"
18
+ steps << "touch #{name}"
19
+
20
+ steps << "\"$(stat -L --format=%a #{name})\" = \"#{opts[:chmod, "644"]}\""
21
+ steps << "chmod #{opts[:chmod, "644"]} #{name}"
22
+
23
+ steps << "\"$(stat -L --format=%G:%U #{name})\" = \"#{opts[:chown, "root:root"]}\""
24
+ steps << "chown --no-dereference #{opts[:chown, "root:root"]} #{name}"
25
+
26
+ when :dir
27
+ steps << "-d #{name}"
28
+ steps << "mkdir #{name}"
29
+
30
+ steps << "\"$(stat -L --format=%a #{name})\" = \"#{opts[:chmod, "755"]}\""
31
+ steps << "chmod #{opts[:chmod, "755"]} #{name}"
32
+
33
+ steps << "\"$(stat -L --format=%G:%U #{name})\" = \"#{opts[:chown, "root:root"]}\""
34
+ steps << "chown --no-dereference #{opts[:chown, "root:root"]} #{name}"
35
+
36
+ when :package
37
+ steps << "$(apt-cache policy #{name} | grep Installed | wc -l) -eq 1 && $(apt-cache policy #{name} | grep Installed | grep '(none)' | wc -l) -eq 0"
38
+ steps << "apt-get install #{name} --yes"
39
+
40
+ when :transfer
41
+ raw = File.read(cfg[:file_dir] + "/files/" + opts[:source])
42
+
43
+ content = Gluez::Erb::Engine.parse(raw, opts[:vars, {}])
44
+
45
+ setup = <<-CMD
46
+ data=$(cat <<\\DATA
47
+ #{content.strip}
48
+ DATA
49
+ )
50
+ CMD
51
+
52
+ steps << "-f #{name}"
53
+ steps << "touch #{name}"
54
+
55
+ steps << "\"$(stat -L --format=%a #{name})\" = \"#{opts[:chmod, "644"]}\""
56
+ steps << "chmod #{opts[:chmod, "644"]} #{name}"
57
+
58
+ steps << "\"$(stat -L --format=%G:%U #{name})\" = \"#{opts[:chown, "root:root"]}\""
59
+ steps << "chown --no-dereference #{opts[:chown, "root:root"]} #{name}"
60
+
61
+ steps << "\"$(echo -n $data | base64 -i -d | md5sum - | awk '{print $1}')\" = \"$(md5sum #{name} | awk '{print $1}')\""
62
+ steps << "echo -n ${data} | base64 -i -d > #{name}"
63
+
64
+ when :group
65
+ steps << "$(cat /etc/group | grep ^#{name}: | wc -l) -eq 1"
66
+ steps << "groupadd --gid #{opts[:gid]} #{name}"
67
+
68
+ when :user
69
+ steps << "$(cat /etc/passwd | grep ^#{name}: | wc -l) -eq 1"
70
+ steps << "useradd --create-home --uid #{opts[:uid]} --gid #{opts[:gid]} --shell #{opts[:shell, "/bin/bash"]} #{name}"
71
+
72
+ when :start
73
+ setup = "service --status-all 1>/tmp/gluez.tmp 2>&1"
74
+ steps << "\"$(grep #{name} /tmp/gluez.tmp | wc -l)\" = \"1\" && \"$(service #{name} status | grep -E 'is running|start/running' | wc -l)\" = \"1\""
75
+ steps << "service #{name} start"
76
+
77
+ when :stop
78
+ setup = "service --status-all 1>/tmp/gluez.tmp 2>&1"
79
+ steps << "\"$(grep #{name} /tmp/gluez.tmp | wc -l)\" = \"1\" && \"$(service #{name} status | grep -E 'is running|start/running' | wc -l)\" = \"0\""
80
+ steps << "service #{name} stop"
81
+
82
+ when :restart
83
+ setup = "service --status-all 1>/tmp/gluez.tmp 2>&1"
84
+ steps << "1 -eq 0"
85
+ steps << <<-CODE
86
+ if [[ "$(grep #{name} /tmp/gluez.tmp | wc -l)" = "1" && "$(service #{name} status | grep -E 'is running|start/running' | wc -l)" = "1" ]]; then
87
+ service #{name} restart
88
+ else
89
+ service #{name} start
90
+ fi
91
+ CODE
92
+
93
+ when :bash
94
+ steps << opts[:not_if]
95
+ steps << "su -l #{opts[:user, 'root']} -c '#{opts[:code]}'"
96
+
97
+ when :link
98
+ steps << "-L #{name} && $(file #{name} | grep \"#{name}: symbolic link to \\`#{opts[:target]}'\" | wc -l) -eq 1"
99
+ steps << "ln -f -s #{opts[:target]} #{name}"
100
+
101
+ steps << "\"$(stat --format=%G:%U #{name})\" = \"#{opts[:chown]}\""
102
+ steps << "chown --no-dereference #{opts[:chown]} #{name}"
103
+
104
+ when :enable
105
+ steps << "$(update-rc.d -n -f #{name} remove | grep '/etc/rc' | wc -l) -gt 0"
106
+ steps << "/usr/sbin/update-rc.d #{name} defaults"
107
+
108
+ when :disable
109
+ steps << "$(update-rc.d -n -f #{name} remove | grep '/etc/rc' | wc -l) -eq 0"
110
+ steps << "/usr/sbin/update-rc.d -f #{name} remove"
111
+
112
+ when :source
113
+ user = opts[:user, "root"]
114
+ home_dir = (user != "root") ? "/home/#{opts[:user]}" : "/root"
115
+
116
+ steps << "-d #{home_dir}/tmp"
117
+ steps << "mkdir #{home_dir}/tmp && chown #{user}:#{user} #{home_dir}/tmp"
118
+
119
+ steps << "-f #{opts[:binary]}"
120
+ steps << <<-CODE
121
+ [ -f #{home_dir}/tmp/#{opts[:filename]} ] && rm #{home_dir}/tmp/#{opts[:filename]}
122
+ [ -d #{home_dir}/tmp/#{opts[:folder]} ] && rm -rf #{home_dir}/tmp/#{opts[:folder]}
123
+
124
+ wget --no-check-certificate -O #{home_dir}/tmp/#{opts[:filename]} #{name}
125
+
126
+ chown #{user}:#{user} #{home_dir}/tmp/#{opts[:filename]}
127
+
128
+ tar -C #{home_dir}/tmp/ -x#{opts[:filename] =~ /\.tar\.bz2/ ? "j" : "z"}f #{home_dir}/tmp/#{opts[:filename]}
129
+
130
+ chown -R #{user}:#{user} #{home_dir}/tmp/#{opts[:folder]}
131
+
132
+ su -l #{user} -c 'cd #{home_dir}/tmp/#{opts[:folder]} && #{opts[:steps].join(' && ')}'
133
+
134
+ chown -R #{user}:#{user} #{home_dir}/tmp/#{opts[:folder].split('/').first}
135
+ CODE
136
+
137
+ else
138
+ raise "unsupported task: #{task}, name: #{name}, opts: #{opts.inspect}"
139
+ end
140
+
141
+
142
+ [name, setup, steps]
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,34 @@
1
+ module Gluez
2
+ module Impl
3
+ class Mac
4
+ def self.steps(cfg, task, name, opts)
5
+
6
+ setup = nil
7
+ steps = []
8
+
9
+ case task
10
+
11
+ when :group
12
+ steps << "$(/usr/bin/dscl . -list Groups | grep ^#{name}$ | wc -l) -eq 1"
13
+ steps << "$(/usr/bin/dscl . -create /Groups/#{name} PrimaryGroupID #{opts[:gid]})"
14
+
15
+ when :user
16
+ steps << "$(/usr/bin/dscl . -list Users | grep ^#{name}$ | wc -l) -eq 1"
17
+ steps << "$(/usr/bin/dscl . -create /Users/#{name} UniqueID #{opts[:uid]} PrimaryGroupID #{opts[:gid]} UserShell #{opts[:shell, "/bin/bash"]} NFSHomeDir /Users/#{name})"
18
+
19
+ steps << "-d /Users/#{name}"
20
+ steps << "mkdir /Users/#{name}"
21
+
22
+ steps << "\"$(stat -L -f %Sg:%Su /Users/#{name})\" = \"#{name}:#{name}\""
23
+ steps << "chown #{name}:#{name} /Users/#{name}"
24
+
25
+ else
26
+ raise "unsupported task: #{task}, name: #{name}, opts: #{opts.inspect}"
27
+ end
28
+
29
+
30
+ [name, setup, steps]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,20 @@
1
+ module Gluez
2
+ class OptionWrapper
3
+ def initialize(options)
4
+ @options = options
5
+ end
6
+
7
+ def [](name, default=nil)
8
+ value = @options[name]
9
+ if value
10
+ value
11
+ else
12
+ if default
13
+ default
14
+ else
15
+ raise "missing option: #{name}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gluez
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: "0.1"
6
+ platform: ruby
7
+ authors:
8
+ - Jan Zimmek
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-01 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: a server configuration toolkit
18
+ email: jan.zimmek@web.de
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ 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
33
+ - lib/gluez.rb
34
+ - bin/gluez
35
+ has_rdoc: true
36
+ homepage:
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.6.2
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: a server configuration toolkit
63
+ test_files: []
64
+