toft-puppet 0.0.9
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/Gemfile +3 -0
- data/Gemfile.lock +62 -0
- data/Rakefile +121 -0
- data/features/checker.feature +14 -0
- data/features/chef.feature +70 -0
- data/features/command.feature +20 -0
- data/features/node.feature +41 -0
- data/features/puppet.feature +40 -0
- data/features/step_definitions/centos/checks.rb +9 -0
- data/features/step_definitions/checker.rb +15 -0
- data/features/step_definitions/chef.rb +43 -0
- data/features/step_definitions/command.rb +28 -0
- data/features/step_definitions/node.rb +65 -0
- data/features/step_definitions/puppet.rb +7 -0
- data/features/support/env.rb +25 -0
- data/fixtures/chef/attributes.json +9 -0
- data/fixtures/chef/cookbooks/test/attributes/default.rb +4 -0
- data/fixtures/chef/cookbooks/test/recipes/attribute.rb +19 -0
- data/fixtures/chef/cookbooks/test/recipes/default.rb +4 -0
- data/fixtures/chef/cookbooks/test/recipes/role.rb +4 -0
- data/fixtures/chef/roles/test.rb +3 -0
- data/fixtures/puppet/conf/fileserver.conf +3 -0
- data/fixtures/puppet/conf/puppet.conf +15 -0
- data/fixtures/puppet/conf/puppet_exec.conf +9 -0
- data/fixtures/puppet/conf/puppet_fileserver.conf +8 -0
- data/fixtures/puppet/conf/puppet_modules.conf +7 -0
- data/fixtures/puppet/conf/puppet_template.conf +8 -0
- data/fixtures/puppet/manifests/fileserver/conf/test_fileserver +1 -0
- data/fixtures/puppet/manifests/nodes/test_node.pp +26 -0
- data/fixtures/puppet/manifests/site.pp +1 -0
- data/fixtures/puppet/manifests/templates/template_test +2 -0
- data/fixtures/puppet/manifests/test.pp +8 -0
- data/fixtures/puppet/manifests/test_fileserver.pp +14 -0
- data/fixtures/puppet/manifests/test_install.pp +5 -0
- data/fixtures/puppet/manifests/test_module.pp +5 -0
- data/fixtures/puppet/manifests/test_service.pp +11 -0
- data/fixtures/puppet/manifests/test_template.pp +12 -0
- data/fixtures/puppet/modules/test_module/manifests/init.pp +8 -0
- data/lib/toft.rb +39 -0
- data/lib/toft/chef/chef_attributes.rb +29 -0
- data/lib/toft/chef/chef_runner.rb +77 -0
- data/lib/toft/command_executor.rb +16 -0
- data/lib/toft/file_checker.rb +47 -0
- data/lib/toft/node.rb +243 -0
- data/lib/toft/node_controller.rb +32 -0
- data/lib/toft/puppet/puppet_runner.rb +38 -0
- data/lib/toft/version.rb +3 -0
- data/scripts/bin/centos/lxc-prepare-host +172 -0
- data/scripts/bin/centos/provision_vagrant +11 -0
- data/scripts/bin/share/install-chef-ubuntu.sh +19 -0
- data/scripts/bin/share/lxc-create-centos-image +60 -0
- data/scripts/bin/ubuntu/lxc-create-ubuntu-image +77 -0
- data/scripts/bin/ubuntu/lxc-prepare-host +199 -0
- data/scripts/bin/ubuntu/provision_vagrant +9 -0
- data/scripts/lxc-templates/files/rc.local +38 -0
- data/scripts/lxc-templates/lxc-centos-6 +279 -0
- data/scripts/lxc-templates/lxc-lenny +255 -0
- data/scripts/lxc-templates/lxc-lucid +313 -0
- data/scripts/lxc-templates/lxc-natty +237 -0
- data/spec/fixtures/illegal_syntax.json +1 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/toft/chef/chef_attributes_spec.rb +39 -0
- data/spec/toft/chef/chef_runner_spec.rb +34 -0
- data/spec/toft/node_spec.rb +18 -0
- data/spec/toft/puppet/puppet_runner_spec.rb +26 -0
- metadata +234 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'toft/command_executor'
|
2
|
+
|
3
|
+
module Toft
|
4
|
+
class FileChecker
|
5
|
+
|
6
|
+
include Toft::CommandExecutor
|
7
|
+
|
8
|
+
def initialize(rootfs, path)
|
9
|
+
@rootfs = rootfs
|
10
|
+
@path = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def exist?
|
14
|
+
test("-e")
|
15
|
+
end
|
16
|
+
|
17
|
+
def directory?
|
18
|
+
filetype == "directory"
|
19
|
+
end
|
20
|
+
|
21
|
+
def filetype
|
22
|
+
stat("%F")
|
23
|
+
end
|
24
|
+
|
25
|
+
def owner
|
26
|
+
stat("%U")
|
27
|
+
end
|
28
|
+
|
29
|
+
def group
|
30
|
+
stat("%G")
|
31
|
+
end
|
32
|
+
|
33
|
+
def mode
|
34
|
+
stat("%a")
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def stat(format)
|
39
|
+
cmd("chroot #{@rootfs} stat -c #{format} #{@path}").rstrip
|
40
|
+
end
|
41
|
+
|
42
|
+
def test(op)
|
43
|
+
cmd!("chroot #{@rootfs} test #{op} #{@path}")
|
44
|
+
$? == 0 ? true : false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/toft/node.rb
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
require 'observer'
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'ping'
|
4
|
+
require 'toft/file_checker'
|
5
|
+
require 'toft/command_executor'
|
6
|
+
|
7
|
+
module Toft
|
8
|
+
class Node
|
9
|
+
PRIVATE_KEY = <<-EOF
|
10
|
+
-----BEGIN RSA PRIVATE KEY-----
|
11
|
+
MIIEpAIBAAKCAQEAwoLge1y9wEcy2WC7CDGXuFFDt+9Zvh+QulfDIbZkpYF7YBw6
|
12
|
+
O3mYTUpucwnqMhnd9jini8bsQghJF3wwxdWmtmurcHAEhN6ZljXZwUu2rojh+D+4
|
13
|
+
PnkOAMPb+w3REmyFYBxfzQ4gBBRXZgKWDTN6Al9hYRFTVSsZJCKJFK+GsWBSc5ie
|
14
|
+
l6IuUnfCbTwvORWVV6g7nGQ5x0JTnApG0qNFDprFkBsLbvHlB6A3lBtHQfJ7W/cZ
|
15
|
+
QXi3LXawD4bhWAl/CHxZHXGpJM7+tREz2yhOoPcHUwwv0xHqe/wBxmJmq84kZ8Co
|
16
|
+
lTi9Y5xNXKDiS6svMDgt3ShpkWcvQ+LE3PhUVQIDAQABAoIBAQCEvfZemeLw9mXw
|
17
|
+
TYA2TknhQqw5OYIAKuCFGuGS/ztea6f75iejcQ8MKDCKF4kZGegNYYqN7HpNcgQX
|
18
|
+
n+xVBsJYGdCM0hVza8pa5XMu4/HO2KGF3k5pbAmvYfqdMUeuEBtRhOuoL+yPfCZM
|
19
|
+
+pTWe3vXZKo7KSy6ocftjhgI4uTD5OtUHZe+Q61K8Ng5723kk4KcbZo4LHEvj4C2
|
20
|
+
nnplt9uxiS04qTPuJohxiwE1pbSybaH5Kndfvzmh1A1q/HKCZNhQKK/jhgvDBtBu
|
21
|
+
hiDfPtKdEeSTbFm11ckJBE1HPdAXoppxwDHQzcq82+vNJdB2P2TsMPklPRb6FuDa
|
22
|
+
dCQ0B5IBAoGBAPUlki+Q6yC4snhJ7r0ipIiMimB+Q6UlrE6ayyc3s/akjvTaqs2z
|
23
|
+
tcZTPUVVLjs0WIRIYwOWMcNmMZoi2s8nGsDiljmd1+smWHPK8A9X8pSUH6Z5k7sS
|
24
|
+
fzno3ytRXohyR2UB6iuUoT3F0VEnaaDjLlNk77DYusAmMsrm8W5PkMHVAoGBAMsf
|
25
|
+
aocc8yrwC7Wa0xfeNreK4F3OayqP6xAu0aSXqj1gtJ6HTTgY2g4jqtnV40NVXwHK
|
26
|
+
7zA4ie5IfmQ/672Te+9ifeWYNqv8faHDJwZFbZ2LwPW/lm5i4Ezn9KMmpLTz+6yj
|
27
|
+
f1bS+Y0NYyxfs1nn7Lx/kvuJVdIV+Ktma+ZHGAiBAoGAHo6NV0KAHHcJP/cvPAIa
|
28
|
+
ci7afMagVfCJNs8SrZPC6eZ/L0QmcDeLW+o6Q+8nMRgIRIzlUqghEdMmMalQjuu3
|
29
|
+
6P0Vbp8fL996vQw5uh/jS+Pewhh7cqEOnMBLORIOb4GXJp8DemUvaAzFV5FLGFPZ
|
30
|
+
DWoSen+5X4QjZqk8xNxEFfUCgYB+xR6xMMo69BH6x6QTc2Zm6s/Y++k6aRPlx7Kj
|
31
|
+
rNxc7iwL/Jme9zOwO2Z4CduKvI9NCSB60e6Tvr7TRmmUqaVh4/B7CKKmeDDYcnm6
|
32
|
+
mj4tY3mMZoQ2ZJNkrCesY4PMQ7HBL1FcGNQSylYo7Zl79Rl1E5HiVvYu5fOK1aNl
|
33
|
+
1t0TAQKBgQCaN91JXWJFXc1rJsDy365SKrX00Nt8rZolFQy2UhhERoCxD0uwbOYm
|
34
|
+
sfWYRr79L2BZkyRHmuxCD24SvHibDev+T0Jh6leXjnrwd/dj3P0tH8+ctET5SXsD
|
35
|
+
CQWv13UgQjiHgQILXSb7xdzpWK1wpDoqIEWQugRyPQDeZhPWVbB4Lg==
|
36
|
+
-----END RSA PRIVATE KEY-----
|
37
|
+
EOF
|
38
|
+
|
39
|
+
TIMEOUT_IN_SECONDS = 120
|
40
|
+
TRY_INTERVAL = 0.5
|
41
|
+
|
42
|
+
include Observable
|
43
|
+
include Toft::CommandExecutor
|
44
|
+
|
45
|
+
def initialize(hostname, options = {})
|
46
|
+
options = {:ip => DYNAMIC_IP, :netmask => "24", :type => "natty"}.merge(options)
|
47
|
+
@hostname = hostname
|
48
|
+
@ip = options[:ip]
|
49
|
+
@netmask = options[:netmask]
|
50
|
+
unless exists?
|
51
|
+
conf_file = generate_lxc_config
|
52
|
+
cmd! "lxc-create -n #{hostname} -f #{conf_file} -t #{options[:type].to_s}"
|
53
|
+
end
|
54
|
+
@chef_runner = Toft::Chef::ChefRunner.new("#{rootfs}") do |chef_command|
|
55
|
+
run_ssh chef_command
|
56
|
+
end
|
57
|
+
|
58
|
+
@puppet_runner = options[:runner]
|
59
|
+
@puppet_runner ||= Toft::Puppet::PuppetRunner.new("#{rootfs}") do |puppet_command|
|
60
|
+
run_ssh puppet_command
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def hostname
|
65
|
+
return @hostname
|
66
|
+
end
|
67
|
+
|
68
|
+
def exists?
|
69
|
+
cmd("lxc-ls") =~ /#{@hostname}/
|
70
|
+
end
|
71
|
+
|
72
|
+
def start
|
73
|
+
puts "Starting host node..."
|
74
|
+
cmd "lxc-start -n #{@hostname} -d" # system + sudo lxc-start does not work on centos-6, but back-quote does(no clue on why)
|
75
|
+
cmd! "lxc-wait -n #{@hostname} -s RUNNING"
|
76
|
+
wait_ssh_ready
|
77
|
+
end
|
78
|
+
|
79
|
+
def stop
|
80
|
+
cmd! "lxc-stop -n #{@hostname}"
|
81
|
+
cmd! "lxc-wait -n #{@hostname} -s STOPPED"
|
82
|
+
end
|
83
|
+
|
84
|
+
def destroy
|
85
|
+
stop
|
86
|
+
cmd! "lxc-destroy -n #{@hostname}"
|
87
|
+
changed
|
88
|
+
notify_observers(@hostname)
|
89
|
+
end
|
90
|
+
|
91
|
+
def running?
|
92
|
+
cmd("lxc-info -n #{@hostname}") =~ /RUNNING/
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_cname(cname)
|
96
|
+
run_ssh "echo -e 'update add #{cname}.#{Toft::DOMAIN} 86400 CNAME #{@hostname}.#{Toft::DOMAIN}\\nsend' | nsupdate"
|
97
|
+
end
|
98
|
+
|
99
|
+
def remove_cname(cname)
|
100
|
+
run_ssh "echo -e 'update delete #{cname}.#{Toft::DOMAIN}\\nsend' | nsupdate"
|
101
|
+
end
|
102
|
+
|
103
|
+
def run_ssh(command)
|
104
|
+
raise ArgumentError, "Trying to run empty command on node #{@hostname}", caller if command.blank?
|
105
|
+
stdout = ""
|
106
|
+
stderr = ""
|
107
|
+
Net::SSH.start(fqdn, "root", :key_data => [PRIVATE_KEY], :paranoid => false) do |ssh|
|
108
|
+
ssh.open_channel do |channel|
|
109
|
+
channel.exec(command) do |ch, success|
|
110
|
+
raise RuntimeError, "Could not execute command: [#{command}]", caller unless success
|
111
|
+
|
112
|
+
channel.on_data do |c, data|
|
113
|
+
puts data
|
114
|
+
stdout << data
|
115
|
+
yield data if block_given?
|
116
|
+
end
|
117
|
+
channel.on_extended_data do |c, type, data|
|
118
|
+
puts data
|
119
|
+
stderr << data
|
120
|
+
yield data if block_given?
|
121
|
+
end
|
122
|
+
channel.on_request("exit-status") do |c, data|
|
123
|
+
exit_code = data.read_long
|
124
|
+
raise CommandExecutionError.new "Remote command [#{command}] exited with status #{exit_code}", stdout, stderr unless exit_code.zero?
|
125
|
+
end
|
126
|
+
channel.on_request("exit-signal") do |c, data|
|
127
|
+
raise CommandExecutionError.new "Remote command [#{command}] terminated with signal", stdout, stderr
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end.wait
|
131
|
+
end
|
132
|
+
return CommandResult.new stdout, stderr
|
133
|
+
end
|
134
|
+
|
135
|
+
def rm(dir)
|
136
|
+
raise ArgumentError, "Illegal dir path: [#{dir}]", caller if dir.blank? || dir[0] != ?/
|
137
|
+
cmd! "rm -rf #{rootfs}#{dir}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def run_chef(run_list, params = {})
|
141
|
+
@chef_runner.run run_list, params
|
142
|
+
end
|
143
|
+
|
144
|
+
def run_puppet(run_list, params = {})
|
145
|
+
@puppet_runner.run run_list, params
|
146
|
+
end
|
147
|
+
|
148
|
+
def file(path)
|
149
|
+
FileChecker.new(rootfs, path)
|
150
|
+
end
|
151
|
+
|
152
|
+
def ip
|
153
|
+
@ip == Toft::DYNAMIC_IP ? `dig +short #{fqdn}`.strip : @ip
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
def rootfs
|
158
|
+
"/var/lib/lxc/#{@hostname}/rootfs"
|
159
|
+
end
|
160
|
+
|
161
|
+
def wait_sshd_running
|
162
|
+
wait_for do
|
163
|
+
netstat = cmd("lxc-netstat --name #{@hostname} -ta")
|
164
|
+
return if netstat =~ /ssh/
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def wait_remote_host_reachable
|
169
|
+
wait_for do
|
170
|
+
begin
|
171
|
+
return if Ping.pingecho fqdn, 0.1
|
172
|
+
rescue Exception
|
173
|
+
# fix the strange pingcho exception
|
174
|
+
end
|
175
|
+
end
|
176
|
+
raise RuntimeError, "Remote machine not responding." if try >= max_try
|
177
|
+
end
|
178
|
+
|
179
|
+
def wait_for
|
180
|
+
return if !block_given?
|
181
|
+
max_try = TIMEOUT_IN_SECONDS / TRY_INTERVAL
|
182
|
+
try = 0
|
183
|
+
while try < max_try
|
184
|
+
output_progress
|
185
|
+
yield
|
186
|
+
sleep TRY_INTERVAL
|
187
|
+
try += 1
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def output_progress
|
192
|
+
print "."
|
193
|
+
STDOUT.flush
|
194
|
+
end
|
195
|
+
|
196
|
+
def wait_ssh_ready
|
197
|
+
print "Waiting for host ssdh ready"
|
198
|
+
wait_sshd_running
|
199
|
+
print "\nWaiting for host to be reachable"
|
200
|
+
wait_remote_host_reachable
|
201
|
+
puts "\nSSH connection on '#{@hostname}/#{@ip}' is ready."
|
202
|
+
end
|
203
|
+
|
204
|
+
def generate_lxc_config
|
205
|
+
full_ip = @ip == Toft::DYNAMIC_IP ? "#{@ip}" : "#{@ip}/#{@netmask}"
|
206
|
+
conf = <<-EOF
|
207
|
+
lxc.network.type = veth
|
208
|
+
lxc.network.flags = up
|
209
|
+
lxc.network.link = br0
|
210
|
+
lxc.network.name = eth0
|
211
|
+
lxc.network.ipv4 = #{full_ip}
|
212
|
+
EOF
|
213
|
+
conf_file = "/tmp/#{@hostname}-conf"
|
214
|
+
File.open(conf_file, 'w') do |f|
|
215
|
+
f.write(conf);
|
216
|
+
end
|
217
|
+
return conf_file
|
218
|
+
end
|
219
|
+
|
220
|
+
def fqdn
|
221
|
+
"#{@hostname}.#{Toft::DOMAIN}"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
class CommandResult
|
226
|
+
attr_reader :stdout, :stderr
|
227
|
+
|
228
|
+
def initialize(stdout, stderr)
|
229
|
+
@stdout = stdout
|
230
|
+
@stderr = stderr
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class CommandExecutionError < RuntimeError
|
235
|
+
attr_reader :message, :stdout, :stderr
|
236
|
+
|
237
|
+
def initialize(message, stdout, stderr)
|
238
|
+
@message = message
|
239
|
+
@stdout = stdout
|
240
|
+
@stderr = stderr
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'toft/node'
|
2
|
+
|
3
|
+
module Toft
|
4
|
+
class NodeController
|
5
|
+
attr_reader :nodes
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@nodes = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_node(hostname, options)
|
12
|
+
node = Node.new(hostname, options)
|
13
|
+
node.add_observer self
|
14
|
+
@nodes[hostname] = node
|
15
|
+
end
|
16
|
+
|
17
|
+
def update(hostname)
|
18
|
+
@nodes.delete hostname
|
19
|
+
end
|
20
|
+
|
21
|
+
def destroy_node(hostname)
|
22
|
+
@nodes[hostname].destroy
|
23
|
+
end
|
24
|
+
|
25
|
+
@@instance = NodeController.new
|
26
|
+
class << self
|
27
|
+
def instance
|
28
|
+
@@instance
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Toft
|
4
|
+
module Puppet
|
5
|
+
class PuppetRunner
|
6
|
+
include FileUtils
|
7
|
+
|
8
|
+
DEST_PUPPET_TMP = "/tmp/toft-puppet-tmp"
|
9
|
+
DEST_CONF_PATH = "/etc/puppet/puppet.conf"
|
10
|
+
|
11
|
+
def initialize(root_dir, &command_runner)
|
12
|
+
@root_dir = root_dir
|
13
|
+
@command_runner = command_runner
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(run_list, params = {})
|
17
|
+
copy_puppet_material
|
18
|
+
copy_conf_file(params[:conf_file]) if params[:conf_file]
|
19
|
+
@command_runner.call "puppet apply #{DEST_PUPPET_TMP}/manifests/#{run_list}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def copy_conf_file(conf_file)
|
25
|
+
cp "#{@root_dir}#{DEST_PUPPET_TMP}/conf/#{conf_file}", "#{@root_dir}#{DEST_CONF_PATH}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def copy_puppet_material
|
29
|
+
raise ArgumentError, "Toft.manifest_path can not be empty!" if Toft.manifest_path.blank?
|
30
|
+
rm_rf "#{@root_dir}#{DEST_PUPPET_TMP}"
|
31
|
+
mkdir_p "#{@root_dir}#{DEST_PUPPET_TMP}"
|
32
|
+
|
33
|
+
cp_r "#{Toft.manifest_path}/.", "#{@root_dir}#{DEST_PUPPET_TMP}"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/toft/version.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
username=`id -nu`
|
4
|
+
if [ ! "$username" = "root" ]; then
|
5
|
+
echo "This command has to be run as root!"
|
6
|
+
exit 1
|
7
|
+
fi
|
8
|
+
|
9
|
+
sudo yum -y install wget
|
10
|
+
wget http://dl.dropbox.com/u/43220259/toft-lxc-0.0.6.noarch.rpm
|
11
|
+
sudo yum erase -y dhclient
|
12
|
+
sudo yum install -y --nogpgcheck toft-lxc-0.0.6.noarch.rpm
|
13
|
+
sudo yum install -y bind dhcp dhclient bridge-utils
|
14
|
+
|
15
|
+
gateway_ip="192.168.20.1"
|
16
|
+
subnet="192.168.20.0"
|
17
|
+
netmask="255.255.255.0"
|
18
|
+
range="192.168.20.2 192.168.20.254"
|
19
|
+
domain=foo
|
20
|
+
|
21
|
+
# setup bridge interface
|
22
|
+
if [[ ! `ip link ls dev br0` ]]; then
|
23
|
+
brctl addbr br0
|
24
|
+
ifconfig br0 $gateway_ip netmask $netmask up
|
25
|
+
sysctl -w net.ipv4.ip_forward=1
|
26
|
+
fi
|
27
|
+
|
28
|
+
cat <<EOF > /etc/sysconfig/network-scripts/ifcfg-br0
|
29
|
+
DEVICE=br0
|
30
|
+
ONBOOT=yes
|
31
|
+
BOOTPROTO=static
|
32
|
+
DELAY=0
|
33
|
+
TYPE=Bridge
|
34
|
+
IPADDR=$gateway_ip
|
35
|
+
NETMASK=$netmask
|
36
|
+
MTU=1500
|
37
|
+
IPV6INIT=no
|
38
|
+
USERCTL=no
|
39
|
+
EOF
|
40
|
+
|
41
|
+
sudo sed -i "s/#*[ ^I]*net\.ipv4\.ip_forward[ ^I]*=[ ^I]*[01]/net\.ipv4\.ip_forward = 1/" /etc/sysctl.conf
|
42
|
+
|
43
|
+
# reset iptables
|
44
|
+
cat <<EOF > /etc/sysconfig/iptables
|
45
|
+
*nat
|
46
|
+
:PREROUTING ACCEPT [0:0]
|
47
|
+
:POSTROUTING ACCEPT [28:2070]
|
48
|
+
:OUTPUT ACCEPT [106:10068]
|
49
|
+
-A POSTROUTING -o eth0 -j MASQUERADE
|
50
|
+
COMMIT
|
51
|
+
EOF
|
52
|
+
|
53
|
+
service iptables restart
|
54
|
+
|
55
|
+
# mount cgroup
|
56
|
+
if [[ ! -d /cgroup ]]; then
|
57
|
+
mkdir -p /cgroup
|
58
|
+
fi
|
59
|
+
|
60
|
+
if [[ ! `mount | grep cgroup` ]]; then
|
61
|
+
mount none -t cgroup /cgroup
|
62
|
+
fi
|
63
|
+
|
64
|
+
if [[ ! `grep "/cgroup" /etc/fstab` ]]; then
|
65
|
+
cat <<EOF >> /etc/fstab
|
66
|
+
none /cgroup cgroup defaults 0 0
|
67
|
+
EOF
|
68
|
+
fi
|
69
|
+
|
70
|
+
# setup nameserver
|
71
|
+
cat <<EOF > /var/named/named.foo
|
72
|
+
\$ORIGIN $domain.
|
73
|
+
\$TTL 7200 ; 2 hours
|
74
|
+
@ IN SOA ns1.$domain. hostmaster.$domain. (
|
75
|
+
3641625943 ; serial
|
76
|
+
36000 ; refresh (10 hours)
|
77
|
+
900 ; retry (15 minutes)
|
78
|
+
36000 ; expire (10 hours)
|
79
|
+
7200 ; minimum (2 hours)
|
80
|
+
)
|
81
|
+
NS ns1.$domain.
|
82
|
+
ns1 A $gateway_ip
|
83
|
+
EOF
|
84
|
+
|
85
|
+
## set bind to forward original nameservers
|
86
|
+
original_nameservers=`grep nameserver /etc/resolv.conf | cut -d " " -f2 | sed s/$gateway_ip//`
|
87
|
+
bind_forward_options=''
|
88
|
+
if [[ -n `echo $original_nameservers | tr -d ' \n\t\r'` ]]; then
|
89
|
+
bind_forward_options="forwarders {
|
90
|
+
`echo $original_nameservers | xargs -n 1 | awk '{ print $1";" }'`
|
91
|
+
};
|
92
|
+
forward first;"
|
93
|
+
fi
|
94
|
+
|
95
|
+
mv /etc/named.conf /etc/named.conf.old
|
96
|
+
cat <<EOF > /etc/named.conf
|
97
|
+
options {
|
98
|
+
directory "/var/named";
|
99
|
+
dump-file "/var/named/data/cache_dump.db";
|
100
|
+
statistics-file "/var/named/data/named_stats.txt";
|
101
|
+
memstatistics-file "/var/named/data/named_mem_stats.txt";
|
102
|
+
$bind_forward_options
|
103
|
+
};
|
104
|
+
|
105
|
+
logging {
|
106
|
+
channel default_debug {
|
107
|
+
file "data/named.run";
|
108
|
+
severity dynamic;
|
109
|
+
};
|
110
|
+
};
|
111
|
+
|
112
|
+
zone "." IN {
|
113
|
+
type hint;
|
114
|
+
file "named.ca";
|
115
|
+
};
|
116
|
+
|
117
|
+
include "/etc/named.rfc1912.zones";
|
118
|
+
|
119
|
+
zone "$domain" in {
|
120
|
+
type master;
|
121
|
+
file "named.foo";
|
122
|
+
allow-update {any;};
|
123
|
+
};
|
124
|
+
EOF
|
125
|
+
|
126
|
+
# disable selinux to make it happy for bind to creating jnl file
|
127
|
+
echo 0 >/selinux/enforce
|
128
|
+
|
129
|
+
# fix the dir owner to grant bind to generate jnl
|
130
|
+
chown named:named /var/named
|
131
|
+
|
132
|
+
service named restart
|
133
|
+
|
134
|
+
# add our nameserver into /etc/resolv.conf
|
135
|
+
if [[ ! `grep "nameserver $gateway_ip" /etc/resolv.conf` ]]; then
|
136
|
+
cp /etc/resolv.conf /etc/resolv.conf.old
|
137
|
+
cat <<EOF > /etc/resolv.conf
|
138
|
+
nameserver $gateway_ip
|
139
|
+
`cat /etc/resolv.conf`
|
140
|
+
EOF
|
141
|
+
fi
|
142
|
+
|
143
|
+
# setup dhcp3 server
|
144
|
+
cat <<EOF > /etc/dhcp/dhcpd.conf
|
145
|
+
ddns-updates on;
|
146
|
+
ddns-update-style interim;
|
147
|
+
|
148
|
+
ddns-domainname "$domain.";
|
149
|
+
option domain-name "$domain.";
|
150
|
+
option domain-name-servers $gateway_ip;
|
151
|
+
|
152
|
+
option ntp-servers $gateway_ip;
|
153
|
+
default-lease-time 600;
|
154
|
+
max-lease-time 7200;
|
155
|
+
|
156
|
+
authoritative;
|
157
|
+
log-facility local7;
|
158
|
+
|
159
|
+
zone $domain. {
|
160
|
+
primary localhost;
|
161
|
+
}
|
162
|
+
|
163
|
+
subnet $subnet netmask $netmask {
|
164
|
+
range $range;
|
165
|
+
option routers $gateway_ip;
|
166
|
+
}
|
167
|
+
EOF
|
168
|
+
service dhcpd restart
|
169
|
+
|
170
|
+
sudo yum install -y ruby ruby-devel ruby-docs ruby-ri ruby-irb ruby-rdoc rubygems
|
171
|
+
sudo gem install bundler --no-ri --no-rdoc
|
172
|
+
sudo bundle install
|