toft-puppet 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +62 -0
  3. data/Rakefile +121 -0
  4. data/features/checker.feature +14 -0
  5. data/features/chef.feature +70 -0
  6. data/features/command.feature +20 -0
  7. data/features/node.feature +41 -0
  8. data/features/puppet.feature +40 -0
  9. data/features/step_definitions/centos/checks.rb +9 -0
  10. data/features/step_definitions/checker.rb +15 -0
  11. data/features/step_definitions/chef.rb +43 -0
  12. data/features/step_definitions/command.rb +28 -0
  13. data/features/step_definitions/node.rb +65 -0
  14. data/features/step_definitions/puppet.rb +7 -0
  15. data/features/support/env.rb +25 -0
  16. data/fixtures/chef/attributes.json +9 -0
  17. data/fixtures/chef/cookbooks/test/attributes/default.rb +4 -0
  18. data/fixtures/chef/cookbooks/test/recipes/attribute.rb +19 -0
  19. data/fixtures/chef/cookbooks/test/recipes/default.rb +4 -0
  20. data/fixtures/chef/cookbooks/test/recipes/role.rb +4 -0
  21. data/fixtures/chef/roles/test.rb +3 -0
  22. data/fixtures/puppet/conf/fileserver.conf +3 -0
  23. data/fixtures/puppet/conf/puppet.conf +15 -0
  24. data/fixtures/puppet/conf/puppet_exec.conf +9 -0
  25. data/fixtures/puppet/conf/puppet_fileserver.conf +8 -0
  26. data/fixtures/puppet/conf/puppet_modules.conf +7 -0
  27. data/fixtures/puppet/conf/puppet_template.conf +8 -0
  28. data/fixtures/puppet/manifests/fileserver/conf/test_fileserver +1 -0
  29. data/fixtures/puppet/manifests/nodes/test_node.pp +26 -0
  30. data/fixtures/puppet/manifests/site.pp +1 -0
  31. data/fixtures/puppet/manifests/templates/template_test +2 -0
  32. data/fixtures/puppet/manifests/test.pp +8 -0
  33. data/fixtures/puppet/manifests/test_fileserver.pp +14 -0
  34. data/fixtures/puppet/manifests/test_install.pp +5 -0
  35. data/fixtures/puppet/manifests/test_module.pp +5 -0
  36. data/fixtures/puppet/manifests/test_service.pp +11 -0
  37. data/fixtures/puppet/manifests/test_template.pp +12 -0
  38. data/fixtures/puppet/modules/test_module/manifests/init.pp +8 -0
  39. data/lib/toft.rb +39 -0
  40. data/lib/toft/chef/chef_attributes.rb +29 -0
  41. data/lib/toft/chef/chef_runner.rb +77 -0
  42. data/lib/toft/command_executor.rb +16 -0
  43. data/lib/toft/file_checker.rb +47 -0
  44. data/lib/toft/node.rb +243 -0
  45. data/lib/toft/node_controller.rb +32 -0
  46. data/lib/toft/puppet/puppet_runner.rb +38 -0
  47. data/lib/toft/version.rb +3 -0
  48. data/scripts/bin/centos/lxc-prepare-host +172 -0
  49. data/scripts/bin/centos/provision_vagrant +11 -0
  50. data/scripts/bin/share/install-chef-ubuntu.sh +19 -0
  51. data/scripts/bin/share/lxc-create-centos-image +60 -0
  52. data/scripts/bin/ubuntu/lxc-create-ubuntu-image +77 -0
  53. data/scripts/bin/ubuntu/lxc-prepare-host +199 -0
  54. data/scripts/bin/ubuntu/provision_vagrant +9 -0
  55. data/scripts/lxc-templates/files/rc.local +38 -0
  56. data/scripts/lxc-templates/lxc-centos-6 +279 -0
  57. data/scripts/lxc-templates/lxc-lenny +255 -0
  58. data/scripts/lxc-templates/lxc-lucid +313 -0
  59. data/scripts/lxc-templates/lxc-natty +237 -0
  60. data/spec/fixtures/illegal_syntax.json +1 -0
  61. data/spec/spec_helper.rb +6 -0
  62. data/spec/toft/chef/chef_attributes_spec.rb +39 -0
  63. data/spec/toft/chef/chef_runner_spec.rb +34 -0
  64. data/spec/toft/node_spec.rb +18 -0
  65. data/spec/toft/puppet/puppet_runner_spec.rb +26 -0
  66. metadata +234 -0
@@ -0,0 +1,16 @@
1
+ module Toft
2
+ module CommandExecutor
3
+ def cmd!(cmd)
4
+ system "#{sudo}#{cmd}"
5
+ end
6
+
7
+ def cmd(cmd)
8
+ `#{sudo}#{cmd}`
9
+ end
10
+
11
+ private
12
+ def sudo
13
+ ENV["USER"] == "root" ? "" : "sudo "
14
+ end
15
+ end
16
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Toft
2
+ VERSION = "0.0.9"
3
+ end
@@ -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