dev-lxc 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -17
- data/dev-lxc.gemspec +1 -1
- data/files/configs/open-source.yaml +1 -1
- data/files/configs/standalone.yaml +5 -5
- data/files/configs/tier.yaml +5 -5
- data/lib/dev-lxc/chef-cluster.rb +47 -38
- data/lib/dev-lxc/chef-server.rb +73 -64
- data/lib/dev-lxc/cli.rb +29 -23
- data/lib/dev-lxc/container.rb +7 -2
- data/lib/dev-lxc/version.rb +1 -1
- data/lib/dev-lxc.rb +41 -45
- metadata +5 -6
- data/files/configs/ha.yaml +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad3bac1e078481c496d8bba29bf48a5ec94ae4e2
|
4
|
+
data.tar.gz: 08f93c461e0025e70c7e52cddfc021288008169a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe9e4793eaa9b92a18471fd58863153204661ca18f9204042971b1e9aa44222d1ea13abc7d8fbacd8015291735e7aef17d986e7280c30b587c4f5570857f6de7
|
7
|
+
data.tar.gz: d7baa7c93dff7630920778298c4607d0d539f1730e68897b75babb2c71f3e50e406243c9b127d78143717d86a5a844b26b1c0602bfa357b3947da6afb35fcf41
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ cluster builds for demo purposes, as well as general experimentation and explora
|
|
13
13
|
1. LXC 1.0 Containers - Resource efficient servers with fast start/stop times and standard init
|
14
14
|
2. Btrfs - Efficient storage backend provides fast, lightweight container cloning
|
15
15
|
3. Dnsmasq - DHCP networking and DNS resolution
|
16
|
-
4. Base
|
16
|
+
4. Base containers - Containers that are built to resemble a traditional server
|
17
17
|
5. ruby-lxc - Ruby bindings for liblxc
|
18
18
|
6. YAML - Simple, customizable definition of clusters; No more setting ENV variables
|
19
19
|
7. Build process closely models online installation documentation
|
@@ -77,32 +77,34 @@ Run `gem update dev-lxc` inside the Vagrant VM to ensure you have the latest ver
|
|
77
77
|
|
78
78
|
One of the key things this tool uses is the concept of "base" containers.
|
79
79
|
|
80
|
-
`dev-lxc` creates containers with "
|
81
|
-
a base container.
|
80
|
+
`dev-lxc` creates base containers with a "p-", "s-" or "u-" prefix on the name to distinguish it as
|
81
|
+
a "platform", "shared" or "unique" base container.
|
82
82
|
|
83
83
|
Base containers are then snapshot cloned using the btrfs filesystem to very quickly
|
84
|
-
provide lightweight
|
84
|
+
provide a lightweight duplicate of the base container. This clone is either used to build
|
85
85
|
another base container or a container that will actually be run.
|
86
86
|
|
87
87
|
During a cluster build process the base containers that get created fall into three categories.
|
88
88
|
|
89
89
|
1. Platform
|
90
90
|
|
91
|
-
The platform base container is the first to get created
|
91
|
+
The platform base container is the first to get created and is identified by the
|
92
|
+
"p-" prefix on the container name.
|
92
93
|
|
93
94
|
`DevLXC#create_base_platform` controls the creation of a platform base container.
|
94
95
|
|
95
|
-
This container provides the chosen OS platform and version (e.g.
|
96
|
+
This container provides the chosen OS platform and version (e.g. p-ubuntu-1404).
|
96
97
|
A typical LXC container has minimal packages installed so `dev-lxc` makes sure that the
|
97
98
|
same packages used in Chef's [bento boxes](https://github.com/opscode/bento) are
|
98
99
|
installed to provide a more typical server environment.
|
99
100
|
A few additional packages are also installed.
|
100
101
|
|
101
|
-
Once this platform base container is created there is rarely a need to delete it
|
102
|
+
*Once this platform base container is created there is rarely a need to delete it.*
|
102
103
|
|
103
104
|
2. Shared
|
104
105
|
|
105
|
-
The shared base container is the second to get created
|
106
|
+
The shared base container is the second to get created and is identified by the
|
107
|
+
"s-" prefix on the container name.
|
106
108
|
|
107
109
|
`DevLXC::ChefServer#create_base_server` controls the creation of a shared base container.
|
108
110
|
|
@@ -113,14 +115,15 @@ During a cluster build process the base containers that get created fall into th
|
|
113
115
|
servers (i.e. it does not get installed on backend servers).
|
114
116
|
|
115
117
|
The name of this base container is built from the names and versions of the Chef packages that
|
116
|
-
get installed which makes this base container easy to be reused by
|
118
|
+
get installed which makes this base container easy to be reused by another cluster that is
|
117
119
|
configured to use the same Chef packages.
|
118
120
|
|
119
|
-
Since no configuration actually happens yet there is rarely a need to delete this container
|
121
|
+
*Since no configuration actually happens yet there is rarely a need to delete this container.*
|
120
122
|
|
121
123
|
3. Unique
|
122
124
|
|
123
|
-
The unique base container is the last to get created
|
125
|
+
The unique base container is the last to get created and is identified by the
|
126
|
+
"u-" prefix on the container name.
|
124
127
|
|
125
128
|
`DevLXC::ChefServer#create` controls the creation of a unique base container.
|
126
129
|
|
@@ -165,7 +168,7 @@ You can see a menu of platform base containers this tool can create by using the
|
|
165
168
|
The initial creation of platform base containers can take awhile so let's go ahead and start creating
|
166
169
|
an Ubuntu 12.04 base container now.
|
167
170
|
|
168
|
-
dev-lxc create
|
171
|
+
dev-lxc create p-ubuntu-1404
|
169
172
|
|
170
173
|
### Cluster Config Files
|
171
174
|
|
@@ -177,16 +180,16 @@ The following command generates sample config files for various cluster topologi
|
|
177
180
|
|
178
181
|
`dev-lxc cluster init tier` generates the following file:
|
179
182
|
|
180
|
-
|
183
|
+
platform_container: p-ubuntu-1404
|
181
184
|
topology: tier
|
182
185
|
api_fqdn: chef-tier.lxc
|
183
186
|
mounts:
|
184
187
|
- /dev-shared dev-shared
|
185
188
|
packages:
|
186
|
-
server: /dev-shared/chef-packages/cs/chef-server-core_12.0.
|
187
|
-
#
|
188
|
-
#
|
189
|
-
#
|
189
|
+
server: /dev-shared/chef-packages/cs/chef-server-core_12.0.3-1_amd64.deb
|
190
|
+
# reporting: /dev-shared/chef-packages/reporting/opscode-reporting_1.2.3-1_amd64.deb
|
191
|
+
# push-jobs-server: /dev-shared/chef-packages/push-jobs-server/opscode-push-jobs-server_1.1.6-1_amd64.deb
|
192
|
+
# manage: /dev-shared/chef-packages/manage/opscode-manage_1.9.0-1_amd64.deb
|
190
193
|
servers:
|
191
194
|
be-tier.lxc:
|
192
195
|
role: backend
|
@@ -307,6 +310,14 @@ Show the status of the cluster.
|
|
307
310
|
|
308
311
|
dev-cluster status
|
309
312
|
|
313
|
+
Create a local chef-repo with appropriate knife.rb and pem files.
|
314
|
+
This makes it easy to use knife.
|
315
|
+
|
316
|
+
dev-lxc cluster chef-repo
|
317
|
+
cd chef-repo
|
318
|
+
knife ssl fetch
|
319
|
+
knife client list
|
320
|
+
|
310
321
|
Stop the cluster's servers.
|
311
322
|
|
312
323
|
dev-lxc cluster stop
|
data/dev-lxc.gemspec
CHANGED
@@ -21,5 +21,5 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake", "~> 0"
|
23
23
|
spec.add_runtime_dependency "thor", "~> 0"
|
24
|
-
spec.add_runtime_dependency "ruby-lxc", "~> 1.0.
|
24
|
+
spec.add_runtime_dependency "ruby-lxc", "~> 1.0.2"
|
25
25
|
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
|
1
|
+
platform_container: p-ubuntu-1404
|
2
2
|
topology: standalone
|
3
3
|
api_fqdn: chef-standalone.lxc
|
4
4
|
mounts:
|
5
5
|
- /dev-shared dev-shared
|
6
6
|
packages:
|
7
|
-
server: /dev-shared/chef-packages/cs/chef-server-core_12.0.
|
8
|
-
# reporting: /dev-shared/chef-packages/
|
9
|
-
# push-jobs-server: /dev-shared/chef-packages/
|
10
|
-
# manage: /dev-shared/chef-packages/
|
7
|
+
server: /dev-shared/chef-packages/cs/chef-server-core_12.0.3-1_amd64.deb
|
8
|
+
# reporting: /dev-shared/chef-packages/reporting/opscode-reporting_1.2.3-1_amd64.deb
|
9
|
+
# push-jobs-server: /dev-shared/chef-packages/push-jobs-server/opscode-push-jobs-server_1.1.6-1_amd64.deb
|
10
|
+
# manage: /dev-shared/chef-packages/manage/opscode-manage_1.9.0-1_amd64.deb
|
11
11
|
servers:
|
12
12
|
chef-standalone.lxc:
|
13
13
|
ipaddress: 10.0.3.201
|
data/files/configs/tier.yaml
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
|
1
|
+
platform_container: p-ubuntu-1404
|
2
2
|
topology: tier
|
3
3
|
api_fqdn: chef-tier.lxc
|
4
4
|
mounts:
|
5
5
|
- /dev-shared dev-shared
|
6
6
|
packages:
|
7
|
-
server: /dev-shared/chef-packages/cs/chef-server-core_12.0.
|
8
|
-
# reporting: /dev-shared/chef-packages/
|
9
|
-
# push-jobs-server: /dev-shared/chef-packages/
|
10
|
-
# manage: /dev-shared/chef-packages/
|
7
|
+
server: /dev-shared/chef-packages/cs/chef-server-core_12.0.3-1_amd64.deb
|
8
|
+
# reporting: /dev-shared/chef-packages/reporting/opscode-reporting_1.2.3-1_amd64.deb
|
9
|
+
# push-jobs-server: /dev-shared/chef-packages/push-jobs-server/opscode-push-jobs-server_1.1.6-1_amd64.deb
|
10
|
+
# manage: /dev-shared/chef-packages/manage/opscode-manage_1.9.0-1_amd64.deb
|
11
11
|
servers:
|
12
12
|
be-tier.lxc:
|
13
13
|
role: backend
|
data/lib/dev-lxc/chef-cluster.rb
CHANGED
@@ -2,20 +2,17 @@ require "dev-lxc/chef-server"
|
|
2
2
|
|
3
3
|
module DevLXC
|
4
4
|
class ChefCluster
|
5
|
-
attr_reader :api_fqdn, :topology, :bootstrap_backend, :
|
5
|
+
attr_reader :api_fqdn, :topology, :bootstrap_backend, :frontends
|
6
6
|
|
7
7
|
def initialize(cluster_config)
|
8
8
|
@cluster_config = cluster_config
|
9
9
|
@api_fqdn = @cluster_config["api_fqdn"]
|
10
10
|
@topology = @cluster_config["topology"]
|
11
11
|
@servers = @cluster_config["servers"]
|
12
|
-
if
|
12
|
+
if @topology == 'tier'
|
13
13
|
@bootstrap_backend = @servers.select {|k,v| v["role"] == "backend" && v["bootstrap"] == true}.first.first
|
14
14
|
@frontends = @servers.select {|k,v| v["role"] == "frontend"}.keys
|
15
15
|
end
|
16
|
-
if @topology == "ha"
|
17
|
-
@secondary_backend = @servers.select {|k,v| v["role"] == "backend" && v["bootstrap"] == nil}.first.first
|
18
|
-
end
|
19
16
|
end
|
20
17
|
|
21
18
|
def chef_servers
|
@@ -28,12 +25,6 @@ module DevLXC
|
|
28
25
|
@frontends.each do |frontend_name|
|
29
26
|
chef_servers << ChefServer.new(frontend_name, @cluster_config)
|
30
27
|
end
|
31
|
-
when "ha"
|
32
|
-
chef_servers << ChefServer.new(@bootstrap_backend, @cluster_config)
|
33
|
-
chef_servers << ChefServer.new(@secondary_backend, @cluster_config)
|
34
|
-
@frontends.each do |frontend_name|
|
35
|
-
chef_servers << ChefServer.new(frontend_name, @cluster_config)
|
36
|
-
end
|
37
28
|
end
|
38
29
|
chef_servers
|
39
30
|
end
|
@@ -49,6 +40,44 @@ module DevLXC
|
|
49
40
|
abspath.compact
|
50
41
|
end
|
51
42
|
|
43
|
+
def chef_repo
|
44
|
+
case @topology
|
45
|
+
when "open-source"
|
46
|
+
puts "Unable to create a chef-repo for an Open Source Chef Server"
|
47
|
+
exit 1
|
48
|
+
when "standalone"
|
49
|
+
chef_server = ChefServer.new(@servers.keys.first, @cluster_config)
|
50
|
+
when "tier"
|
51
|
+
chef_server = ChefServer.new(@bootstrap_backend, @cluster_config)
|
52
|
+
end
|
53
|
+
if ! chef_server.server.defined?
|
54
|
+
puts "The '#{chef_server.server.name}' Chef Server does not exist. Please create it first."
|
55
|
+
exit 1
|
56
|
+
end
|
57
|
+
puts "Creating chef-repo with pem files and knife.rb in the current directory"
|
58
|
+
FileUtils.mkdir_p("./chef-repo/.chef")
|
59
|
+
knife_rb = %Q(
|
60
|
+
current_dir = File.dirname(__FILE__)
|
61
|
+
|
62
|
+
chef_server_url "https://#{api_fqdn}/organizations/ponyville"
|
63
|
+
|
64
|
+
node_name "rainbowdash"
|
65
|
+
client_key "\#{current_dir}/rainbowdash.pem"
|
66
|
+
|
67
|
+
validation_client_name "ponyville-validator"
|
68
|
+
validation_key "\#{current_dir}/ponyville-validator.pem"
|
69
|
+
|
70
|
+
cookbook_path Dir.pwd + "/cookbooks"
|
71
|
+
knife[:chef_repo_path] = Dir.pwd
|
72
|
+
)
|
73
|
+
IO.write("./chef-repo/.chef/knife.rb", knife_rb)
|
74
|
+
if Dir.glob("#{chef_server.abspath('/root/chef-repo/.chef')}/*.pem").empty?
|
75
|
+
puts "The pem files can not be copied because they do not exist in '#{chef_server.server.name}' Chef Server's `/root/chef-repo/.chef` directory"
|
76
|
+
else
|
77
|
+
FileUtils.cp( Dir.glob("#{chef_server.abspath('/root/chef-repo/.chef')}/*.pem"), "./chef-repo/.chef" )
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
52
81
|
def run_command(command)
|
53
82
|
chef_servers.each { |cs| cs.run_command(command) }
|
54
83
|
end
|
@@ -67,54 +96,34 @@ module DevLXC
|
|
67
96
|
puts "Destroying cluster"
|
68
97
|
chef_servers.reverse_each { |cs| cs.destroy }
|
69
98
|
end
|
70
|
-
|
71
|
-
def
|
99
|
+
|
100
|
+
def destroy_container(type)
|
72
101
|
case type
|
73
102
|
when :unique
|
74
103
|
@servers.keys.each do |server_name|
|
75
|
-
DevLXC::ChefServer.new(server_name, @cluster_config).
|
104
|
+
DevLXC::ChefServer.new(server_name, @cluster_config).destroy_container(:unique)
|
76
105
|
end
|
77
106
|
when :shared
|
78
|
-
DevLXC::ChefServer.new(@servers.keys.first, @cluster_config).
|
107
|
+
DevLXC::ChefServer.new(@servers.keys.first, @cluster_config).destroy_container(:shared)
|
79
108
|
when :platform
|
80
|
-
DevLXC::ChefServer.new(@servers.keys.first, @cluster_config).
|
109
|
+
DevLXC::ChefServer.new(@servers.keys.first, @cluster_config).destroy_container(:platform)
|
81
110
|
end
|
82
111
|
end
|
83
112
|
|
84
113
|
def chef_server_config
|
85
114
|
chef_server_config = %Q(api_fqdn "#{@api_fqdn}"\n)
|
86
|
-
if
|
115
|
+
if @topology == 'tier'
|
87
116
|
chef_server_config += %Q(
|
88
117
|
topology "#{@topology}"
|
89
118
|
|
90
119
|
server "#{@bootstrap_backend}",
|
91
120
|
:ipaddress => "#{@servers[@bootstrap_backend]["ipaddress"]}",
|
92
121
|
:role => "backend",
|
93
|
-
:bootstrap => true
|
94
|
-
|
95
|
-
case @topology
|
96
|
-
when "tier"
|
97
|
-
chef_server_config += %Q(
|
122
|
+
:bootstrap => true
|
98
123
|
|
99
124
|
backend_vip "#{@bootstrap_backend}",
|
100
125
|
:ipaddress => "#{@servers[@bootstrap_backend]["ipaddress"]}"
|
101
126
|
)
|
102
|
-
when "ha"
|
103
|
-
backend_vip_name = config["backend_vip"].keys.first
|
104
|
-
chef_server_config += %Q(,
|
105
|
-
:cluster_ipaddress => "#{@servers[@bootstrap_backend]["cluster_ipaddress"]}"
|
106
|
-
|
107
|
-
server "#{@secondary_backend}",
|
108
|
-
:ipaddress => "#{@servers[@secondary_backend]["ipaddress"]}",
|
109
|
-
:role => "backend",
|
110
|
-
:cluster_ipaddress => "#{@servers[@secondary_backend]["cluster_ipaddress"]}
|
111
|
-
|
112
|
-
backend_vip "#{backend_vip_name}",
|
113
|
-
:ipaddress => "#{config["backend_vip"][backend_vip_name]["ipaddress"]}",
|
114
|
-
:device => "#{config["backend_vip"][backend_vip_name]["device"]}",
|
115
|
-
:heartbeat_device => "#{config["backend_vip"][backend_vip_name]["heartbeat_device"]}"
|
116
|
-
)
|
117
|
-
end
|
118
127
|
@frontends.each do |frontend_name|
|
119
128
|
chef_server_config += %Q(
|
120
129
|
server "#{frontend_name}",
|
data/lib/dev-lxc/chef-server.rb
CHANGED
@@ -3,7 +3,7 @@ require "dev-lxc/chef-cluster"
|
|
3
3
|
|
4
4
|
module DevLXC
|
5
5
|
class ChefServer
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :platform_container_name, :server, :shared_container_name
|
7
7
|
|
8
8
|
def initialize(name, cluster_config)
|
9
9
|
unless cluster_config["servers"].keys.include?(name)
|
@@ -16,16 +16,15 @@ module DevLXC
|
|
16
16
|
case cluster.topology
|
17
17
|
when "open-source", "standalone"
|
18
18
|
@role = cluster.topology
|
19
|
-
when "tier"
|
19
|
+
when "tier"
|
20
20
|
@role = "bootstrap_backend" if @server.name == cluster.bootstrap_backend
|
21
|
-
@role = "secondary_backend" if @server.name == cluster.secondary_backend
|
22
21
|
@role = "frontend" if cluster.frontends.include?(@server.name)
|
23
22
|
end
|
24
23
|
@mounts = cluster_config["mounts"]
|
25
24
|
@bootstrap_backend = cluster.bootstrap_backend
|
26
25
|
@chef_server_config = cluster.chef_server_config
|
27
26
|
@api_fqdn = cluster.api_fqdn
|
28
|
-
@
|
27
|
+
@platform_container_name = cluster_config["platform_container"]
|
29
28
|
@packages = cluster_config["packages"]
|
30
29
|
|
31
30
|
if File.basename(@packages["server"]).match(/^(\w+-\w+.*)[_-]((?:\d+\.?){3,})-/)
|
@@ -33,21 +32,21 @@ module DevLXC
|
|
33
32
|
@chef_server_version = Regexp.last_match[2].gsub(".", "-")
|
34
33
|
end
|
35
34
|
|
36
|
-
@
|
35
|
+
@shared_container_name = "s#{@platform_container_name[1..-1]}"
|
37
36
|
case @chef_server_type
|
38
37
|
when 'chef-server-core'
|
39
|
-
@
|
38
|
+
@shared_container_name += '-cs'
|
40
39
|
@server_ctl = 'chef-server'
|
41
40
|
when 'private-chef'
|
42
|
-
@
|
41
|
+
@shared_container_name += '-ec'
|
43
42
|
@server_ctl = 'private-chef'
|
44
43
|
when 'chef-server'
|
45
|
-
@
|
44
|
+
@shared_container_name += '-osc'
|
46
45
|
@server_ctl = 'chef-server'
|
47
46
|
end
|
48
|
-
@
|
49
|
-
@
|
50
|
-
@
|
47
|
+
@shared_container_name += "-#{@chef_server_version}"
|
48
|
+
@shared_container_name += "-reporting-#{Regexp.last_match[1].gsub(".", "-")}" if @packages["reporting"].to_s.match(/[_-]((\d+\.?){3,})-/)
|
49
|
+
@shared_container_name += "-pushy-#{Regexp.last_match[1].gsub(".", "-")}" if @packages["push-jobs-server"].to_s.match(/[_-]((\d+\.?){3,})-/)
|
51
50
|
end
|
52
51
|
|
53
52
|
def status
|
@@ -103,14 +102,14 @@ module DevLXC
|
|
103
102
|
DevLXC.reload_dnsmasq
|
104
103
|
end
|
105
104
|
|
106
|
-
def
|
105
|
+
def destroy_container(type)
|
107
106
|
case type
|
108
107
|
when :unique
|
109
|
-
DevLXC::Container.new("
|
108
|
+
DevLXC::Container.new("u-#{@server.name}").destroy
|
110
109
|
when :shared
|
111
|
-
DevLXC::Container.new(@
|
110
|
+
DevLXC::Container.new(@shared_container_name).destroy
|
112
111
|
when :platform
|
113
|
-
DevLXC::Container.new(@
|
112
|
+
DevLXC::Container.new(@platform_container_name).destroy
|
114
113
|
end
|
115
114
|
end
|
116
115
|
|
@@ -119,10 +118,10 @@ module DevLXC
|
|
119
118
|
puts "Using existing container #{@server.name}"
|
120
119
|
return
|
121
120
|
end
|
122
|
-
|
123
|
-
if
|
124
|
-
puts "Cloning container #{
|
125
|
-
|
121
|
+
unique_container = DevLXC::Container.new("u-#{@server.name}")
|
122
|
+
if unique_container.defined?
|
123
|
+
puts "Cloning shared container #{unique_container.name} into container #{@server.name}"
|
124
|
+
unique_container.clone(@server.name, {:flags => LXC::LXC_CLONE_SNAPSHOT|LXC::LXC_CLONE_KEEPMACADDR})
|
126
125
|
@server = DevLXC::Container.new(@server.name)
|
127
126
|
return
|
128
127
|
else
|
@@ -130,9 +129,9 @@ module DevLXC
|
|
130
129
|
unless %w(open-source standalone).include?(@role) || @server.name == @bootstrap_backend || DevLXC::Container.new(@bootstrap_backend).defined?
|
131
130
|
raise "The bootstrap backend server must be created first."
|
132
131
|
end
|
133
|
-
|
134
|
-
puts "Cloning container #{
|
135
|
-
|
132
|
+
shared_container = create_shared_container
|
133
|
+
puts "Cloning shared container #{shared_container.name} into container #{@server.name}"
|
134
|
+
shared_container.clone(@server.name, {:flags => LXC::LXC_CLONE_SNAPSHOT})
|
136
135
|
@server = DevLXC::Container.new(@server.name)
|
137
136
|
puts "Adding lxc.hook.post-stop hook"
|
138
137
|
@server.set_config_item("lxc.hook.post-stop", "/usr/local/share/lxc/hooks/post-stop-dhcp-release")
|
@@ -145,7 +144,7 @@ module DevLXC
|
|
145
144
|
@server.start
|
146
145
|
configure_server unless @packages["server"].nil?
|
147
146
|
create_users if %w(standalone bootstrap_backend).include?(@role)
|
148
|
-
if %w(standalone bootstrap_backend
|
147
|
+
if %w(standalone bootstrap_backend frontend).include?(@role)
|
149
148
|
configure_reporting unless @packages["reporting"].nil?
|
150
149
|
configure_push_jobs_server unless @packages["push-jobs-server"].nil?
|
151
150
|
end
|
@@ -154,42 +153,41 @@ module DevLXC
|
|
154
153
|
configure_manage
|
155
154
|
end
|
156
155
|
@server.stop
|
157
|
-
puts "Cloning container #{@server.name} into
|
158
|
-
@server.clone("
|
156
|
+
puts "Cloning container #{@server.name} into unique container #{unique_container.name}"
|
157
|
+
@server.clone("#{unique_container.name}", {:flags => LXC::LXC_CLONE_SNAPSHOT|LXC::LXC_CLONE_KEEPMACADDR})
|
159
158
|
end
|
160
159
|
end
|
161
160
|
|
162
|
-
def
|
163
|
-
|
164
|
-
if
|
165
|
-
puts "Using existing container #{
|
166
|
-
return
|
161
|
+
def create_shared_container
|
162
|
+
shared_container = DevLXC::Container.new(@shared_container_name)
|
163
|
+
if shared_container.defined?
|
164
|
+
puts "Using existing shared container #{shared_container.name}"
|
165
|
+
return shared_container
|
167
166
|
end
|
168
|
-
|
169
|
-
puts "Cloning container #{
|
170
|
-
|
171
|
-
|
167
|
+
platform_container = DevLXC.create_platform_container(@platform_container_name)
|
168
|
+
puts "Cloning platform container #{platform_container.name} into shared container #{shared_container.name}"
|
169
|
+
platform_container.clone(shared_container.name, {:flags => LXC::LXC_CLONE_SNAPSHOT})
|
170
|
+
shared_container = DevLXC::Container.new(shared_container.name)
|
172
171
|
|
173
172
|
# Disable certain sysctl.d files in Ubuntu 10.04, they cause `start procps` to fail
|
174
173
|
# Enterprise Chef server's postgresql recipe expects to be able to `start procps`
|
175
|
-
if
|
176
|
-
if File.exist?("#{
|
177
|
-
FileUtils.mv("#{
|
178
|
-
"#{
|
174
|
+
if platform_container.name == "p-ubuntu-1004"
|
175
|
+
if File.exist?("#{shared_container.config_item('lxc.rootfs')}/etc/sysctl.d/10-console-messages.conf")
|
176
|
+
FileUtils.mv("#{shared_container.config_item('lxc.rootfs')}/etc/sysctl.d/10-console-messages.conf",
|
177
|
+
"#{shared_container.config_item('lxc.rootfs')}/etc/sysctl.d/10-console-messages.conf.orig")
|
179
178
|
end
|
180
179
|
end
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
base_server.save_config
|
180
|
+
unless shared_container.config_item("lxc.mount.auto").empty?
|
181
|
+
shared_container.set_config_item("lxc.mount.auto", "proc:rw sys:rw")
|
182
|
+
shared_container.save_config
|
185
183
|
end
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
return
|
184
|
+
shared_container.sync_mounts(@mounts)
|
185
|
+
shared_container.start
|
186
|
+
shared_container.install_package(@packages["server"]) unless @packages["server"].nil?
|
187
|
+
shared_container.install_package(@packages["reporting"]) unless @packages["reporting"].nil?
|
188
|
+
shared_container.install_package(@packages["push-jobs-server"]) unless @packages["push-jobs-server"].nil?
|
189
|
+
shared_container.stop
|
190
|
+
return shared_container
|
193
191
|
end
|
194
192
|
|
195
193
|
def configure_server
|
@@ -211,7 +209,7 @@ module DevLXC
|
|
211
209
|
IO.write("#{@server.config_item('lxc.rootfs')}/etc/opscode/chef-server.rb", @chef_server_config)
|
212
210
|
end
|
213
211
|
run_ctl(@server_ctl, "reconfigure")
|
214
|
-
when "
|
212
|
+
when "frontend"
|
215
213
|
puts "Copying /etc/opscode from bootstrap backend"
|
216
214
|
FileUtils.cp_r("#{LXC::Container.new(@bootstrap_backend).config_item('lxc.rootfs')}/etc/opscode",
|
217
215
|
"#{@server.config_item('lxc.rootfs')}/etc")
|
@@ -220,7 +218,7 @@ module DevLXC
|
|
220
218
|
end
|
221
219
|
|
222
220
|
def configure_reporting
|
223
|
-
if
|
221
|
+
if @role == 'frontend'
|
224
222
|
puts "Copying /etc/opscode-reporting from bootstrap backend"
|
225
223
|
FileUtils.cp_r("#{LXC::Container.new(@bootstrap_backend).config_item('lxc.rootfs')}/etc/opscode-reporting",
|
226
224
|
"#{@server.config_item('lxc.rootfs')}/etc")
|
@@ -231,10 +229,7 @@ module DevLXC
|
|
231
229
|
|
232
230
|
def configure_push_jobs_server
|
233
231
|
run_ctl("opscode-push-jobs-server", "reconfigure")
|
234
|
-
|
235
|
-
run_ctl(@server_ctl, "reconfigure")
|
236
|
-
end
|
237
|
-
run_ctl(@server_ctl, "restart opscode-pushy-server")
|
232
|
+
run_ctl(@server_ctl, "reconfigure")
|
238
233
|
end
|
239
234
|
|
240
235
|
def configure_manage
|
@@ -255,20 +250,34 @@ module DevLXC
|
|
255
250
|
def create_users
|
256
251
|
puts "Creating org, user, keys and knife.rb in /root/chef-repo/.chef"
|
257
252
|
FileUtils.mkdir_p("#{@server.config_item('lxc.rootfs')}/root/chef-repo/.chef")
|
258
|
-
knife_rb =
|
259
|
-
|
260
|
-
|
261
|
-
|
253
|
+
knife_rb = %Q(
|
254
|
+
current_dir = File.dirname(__FILE__)
|
255
|
+
|
256
|
+
chef_server_url "https://127.0.0.1/organizations/ponyville"
|
257
|
+
|
258
|
+
node_name "rainbowdash"
|
259
|
+
client_key "\#{current_dir}/rainbowdash.pem"
|
260
|
+
|
261
|
+
validation_client_name "ponyville-validator"
|
262
|
+
validation_key "\#{current_dir}/ponyville-validator.pem"
|
263
|
+
|
264
|
+
cookbook_path Dir.pwd + "/cookbooks"
|
265
|
+
knife[:chef_repo_path] = Dir.pwd
|
266
|
+
)
|
262
267
|
IO.write("#{@server.config_item('lxc.rootfs')}/root/chef-repo/.chef/knife.rb", knife_rb)
|
263
268
|
case @chef_server_type
|
264
269
|
when 'private-chef'
|
265
270
|
# give time for all services to come up completely
|
266
271
|
sleep 60
|
267
|
-
pivotal_rb =
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
+
pivotal_rb = %Q(
|
273
|
+
chef_server_root "https://127.0.0.1/"
|
274
|
+
chef_server_url "https://127.0.0.1/"
|
275
|
+
|
276
|
+
node_name "pivotal"
|
277
|
+
client_key "/etc/opscode/pivotal.pem"
|
278
|
+
|
279
|
+
knife[:chef_repo_path] = Dir.pwd
|
280
|
+
)
|
272
281
|
IO.write("#{@server.config_item('lxc.rootfs')}/root/chef-repo/.chef/pivotal.rb", pivotal_rb)
|
273
282
|
@server.run_command("/opt/opscode/embedded/bin/gem install knife-opc --no-ri --no-rdoc")
|
274
283
|
@server.run_command("/opt/opscode/embedded/bin/knife opc org create ponyville ponyville --filename /root/chef-repo/.chef/ponyville-validator.pem -c /root/chef-repo/.chef/pivotal.rb")
|
data/lib/dev-lxc/cli.rb
CHANGED
@@ -37,6 +37,12 @@ module DevLXC::CLI
|
|
37
37
|
puts get_cluster(options[:config]).abspath(rootfs_path).join(" ")
|
38
38
|
end
|
39
39
|
|
40
|
+
desc "chef-repo", "Creates a chef-repo in the current directory using files from the cluster's backend /root/chef-repo"
|
41
|
+
option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yaml will be used by default"
|
42
|
+
def chef_repo
|
43
|
+
get_cluster(options[:config]).chef_repo
|
44
|
+
end
|
45
|
+
|
40
46
|
desc "run_command [COMMAND]", "Runs a command in each Chef server in a cluster"
|
41
47
|
option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yaml will be used by default"
|
42
48
|
def run_command(command)
|
@@ -57,15 +63,15 @@ module DevLXC::CLI
|
|
57
63
|
|
58
64
|
desc "destroy", "Destroy a cluster's Chef servers"
|
59
65
|
option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yaml will be used by default"
|
60
|
-
option :unique, :aliases => "-u", :type => :boolean, :desc => "Also destroy the cluster's unique
|
61
|
-
option :shared, :aliases => "-s", :type => :boolean, :desc => "Also destroy the cluster's shared
|
62
|
-
option :platform, :aliases => "-p", :type => :boolean, :desc => "Also destroy the cluster's platform
|
66
|
+
option :unique, :aliases => "-u", :type => :boolean, :desc => "Also destroy the cluster's unique containers"
|
67
|
+
option :shared, :aliases => "-s", :type => :boolean, :desc => "Also destroy the cluster's shared container"
|
68
|
+
option :platform, :aliases => "-p", :type => :boolean, :desc => "Also destroy the cluster's platform container"
|
63
69
|
def destroy
|
64
70
|
cluster = get_cluster(options[:config])
|
65
71
|
cluster.destroy
|
66
|
-
cluster.
|
67
|
-
cluster.
|
68
|
-
cluster.
|
72
|
+
cluster.destroy_container(:unique) if options[:unique]
|
73
|
+
cluster.destroy_container(:shared) if options[:shared]
|
74
|
+
cluster.destroy_container(:platform) if options[:platform]
|
69
75
|
end
|
70
76
|
end
|
71
77
|
|
@@ -111,35 +117,35 @@ module DevLXC::CLI
|
|
111
117
|
|
112
118
|
desc "destroy [NAME]", "Destroy a cluster's Chef server"
|
113
119
|
option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yaml will be used by default"
|
114
|
-
option :unique, :aliases => "-u", :type => :boolean, :desc => "Also destroy the server's unique
|
115
|
-
option :shared, :aliases => "-s", :type => :boolean, :desc => "Also destroy the server's shared
|
116
|
-
option :platform, :aliases => "-p", :type => :boolean, :desc => "Also destroy the server's platform
|
120
|
+
option :unique, :aliases => "-u", :type => :boolean, :desc => "Also destroy the server's unique container"
|
121
|
+
option :shared, :aliases => "-s", :type => :boolean, :desc => "Also destroy the server's shared container"
|
122
|
+
option :platform, :aliases => "-p", :type => :boolean, :desc => "Also destroy the server's platform container"
|
117
123
|
def destroy(name)
|
118
124
|
server = get_server(name, options[:config])
|
119
125
|
server.destroy
|
120
|
-
server.
|
121
|
-
server.
|
122
|
-
server.
|
126
|
+
server.destroy_container(:unique) if options[:unique]
|
127
|
+
server.destroy_container(:shared) if options[:shared]
|
128
|
+
server.destroy_container(:platform) if options[:platform]
|
123
129
|
end
|
124
130
|
end
|
125
131
|
|
126
132
|
class DevLXC < Thor
|
127
|
-
desc "create [
|
128
|
-
def create(
|
129
|
-
|
130
|
-
if
|
131
|
-
|
132
|
-
print_table
|
133
|
-
selection = ask("Which
|
134
|
-
|
133
|
+
desc "create [PLATFORM_CONTAINER_NAME]", "Create a platform container"
|
134
|
+
def create(platform_container_name=nil)
|
135
|
+
platform_container_names = %w(p-ubuntu-1204 p-ubuntu-1404 p-centos-5 p-centos-6)
|
136
|
+
if platform_container_name.nil? || ! platform_container_names.include?(platform_container_name)
|
137
|
+
platform_container_names_with_index = platform_container_names.map.with_index{ |a, i| [i+1, *a]}
|
138
|
+
print_table platform_container_names_with_index
|
139
|
+
selection = ask("Which platform container do you want to create?", :limited_to => platform_container_names_with_index.map{|c| c[0].to_s})
|
140
|
+
platform_container_name = platform_container_names[selection.to_i - 1]
|
135
141
|
end
|
136
|
-
::DevLXC.
|
142
|
+
::DevLXC.create_platform_container(platform_container_name)
|
137
143
|
end
|
138
144
|
|
139
|
-
desc "cluster SUBCOMMAND ...ARGS", "
|
145
|
+
desc "cluster SUBCOMMAND ...ARGS", "Manage Chef cluster"
|
140
146
|
subcommand "cluster", Cluster
|
141
147
|
|
142
|
-
desc "server SUBCOMMAND ...ARGS", "
|
148
|
+
desc "server SUBCOMMAND ...ARGS", "Manage Chef server"
|
143
149
|
subcommand "server", Server
|
144
150
|
end
|
145
151
|
end
|
data/lib/dev-lxc/container.rb
CHANGED
@@ -37,8 +37,13 @@ module DevLXC
|
|
37
37
|
end
|
38
38
|
mounts.each do |mount|
|
39
39
|
raise "Mount source #{mount.split.first} does not exist." unless File.exists?(mount.split.first)
|
40
|
-
|
41
|
-
|
40
|
+
if preserved_mounts.any? { |m| m.start_with?("#{mount} ") }
|
41
|
+
puts "Skipping mount entry #{mount}, it already exists"
|
42
|
+
next
|
43
|
+
else
|
44
|
+
puts "Adding mount entry #{mount}"
|
45
|
+
self.set_config_item("lxc.mount.entry", "#{mount} none bind,optional,create=dir 0 0 ## dev-lxc ##")
|
46
|
+
end
|
42
47
|
end
|
43
48
|
self.save_config
|
44
49
|
end
|
data/lib/dev-lxc/version.rb
CHANGED
data/lib/dev-lxc.rb
CHANGED
@@ -6,60 +6,56 @@ require "dev-lxc/chef-server"
|
|
6
6
|
require "dev-lxc/chef-cluster"
|
7
7
|
|
8
8
|
module DevLXC
|
9
|
-
def self.
|
10
|
-
|
11
|
-
if
|
12
|
-
puts "Using existing container #{
|
13
|
-
return
|
9
|
+
def self.create_platform_container(platform_container_name)
|
10
|
+
platform_container = DevLXC::Container.new(platform_container_name)
|
11
|
+
if platform_container.defined?
|
12
|
+
puts "Using existing platform container #{platform_container.name}"
|
13
|
+
return platform_container
|
14
14
|
end
|
15
|
-
puts "Creating container #{
|
16
|
-
case
|
17
|
-
when "
|
18
|
-
|
19
|
-
when "
|
20
|
-
|
21
|
-
when "
|
22
|
-
|
23
|
-
when "
|
24
|
-
|
25
|
-
when "
|
26
|
-
|
15
|
+
puts "Creating platform container #{platform_container.name}"
|
16
|
+
case platform_container.name
|
17
|
+
when "p-ubuntu-1004"
|
18
|
+
platform_container.create("download", "btrfs", 0, ["-d", "ubuntu", "-r", "lucid", "-a", "amd64"])
|
19
|
+
when "p-ubuntu-1204"
|
20
|
+
platform_container.create("download", "btrfs", 0, ["-d", "ubuntu", "-r", "precise", "-a", "amd64"])
|
21
|
+
when "p-ubuntu-1404"
|
22
|
+
platform_container.create("download", "btrfs", 0, ["-d", "ubuntu", "-r", "trusty", "-a", "amd64"])
|
23
|
+
when "p-centos-5"
|
24
|
+
platform_container.create("centos", "btrfs", 0, ["-R", "5"])
|
25
|
+
when "p-centos-6"
|
26
|
+
platform_container.create("download", "btrfs", 0, ["-d", "centos", "-r", "6", "-a", "amd64"])
|
27
27
|
end
|
28
|
-
|
29
|
-
|
30
|
-
base_platform.save_config
|
31
|
-
# TODO when LXC 1.0.2 is released the following test can be done using #config_item("lxc.mount.auto")
|
32
|
-
unless IO.readlines(base_platform.config_file_name).select { |line| line.start_with?("lxc.mount.auto") }.empty?
|
33
|
-
base_platform.set_config_item("lxc.mount.auto", "proc:rw sys:rw")
|
28
|
+
unless platform_container.config_item("lxc.mount.auto").empty?
|
29
|
+
platform_container.set_config_item("lxc.mount.auto", "proc:rw sys:rw")
|
34
30
|
end
|
35
31
|
hwaddr = '00:16:3e:' + Digest::SHA1.hexdigest(Time.now.to_s).slice(0..5).unpack('a2a2a2').join(':')
|
36
|
-
puts "Setting #{
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
puts "Installing packages in container #{
|
41
|
-
case
|
42
|
-
when "
|
32
|
+
puts "Setting #{platform_container.name} platform container's lxc.network.0.hwaddr to #{hwaddr}"
|
33
|
+
platform_container.set_config_item("lxc.network.0.hwaddr", hwaddr)
|
34
|
+
platform_container.save_config
|
35
|
+
platform_container.start
|
36
|
+
puts "Installing packages in platform container #{platform_container.name}"
|
37
|
+
case platform_container.name
|
38
|
+
when "p-ubuntu-1004"
|
43
39
|
# Disable certain sysctl.d files in Ubuntu 10.04, they cause `start procps` to fail
|
44
|
-
if File.exist?("#{
|
45
|
-
FileUtils.mv("#{
|
46
|
-
"#{
|
40
|
+
if File.exist?("#{platform_container.config_item('lxc.rootfs')}/etc/sysctl.d/10-console-messages.conf")
|
41
|
+
FileUtils.mv("#{platform_container.config_item('lxc.rootfs')}/etc/sysctl.d/10-console-messages.conf",
|
42
|
+
"#{platform_container.config_item('lxc.rootfs')}/etc/sysctl.d/10-console-messages.conf.orig")
|
47
43
|
end
|
48
|
-
|
49
|
-
|
50
|
-
when "
|
51
|
-
|
52
|
-
|
53
|
-
when "
|
44
|
+
platform_container.run_command("apt-get update")
|
45
|
+
platform_container.run_command("apt-get install -y standard^ server^ vim-nox emacs23-nox curl tree")
|
46
|
+
when "p-ubuntu-1204", "p-ubuntu-1404"
|
47
|
+
platform_container.run_command("apt-get update")
|
48
|
+
platform_container.run_command("apt-get install -y standard^ server^ vim-nox emacs23-nox tree")
|
49
|
+
when "p-centos-5"
|
54
50
|
# downgrade openssl temporarily to overcome an install bug
|
55
51
|
# reference: http://www.hack.net.br/blog/2014/02/12/openssl-conflicts-with-file-from-package-openssl/
|
56
|
-
|
57
|
-
|
58
|
-
when "
|
59
|
-
|
52
|
+
platform_container.run_command("yum downgrade -y openssl")
|
53
|
+
platform_container.run_command("yum install -y @base @core vim-enhanced emacs-nox tree")
|
54
|
+
when "p-centos-6"
|
55
|
+
platform_container.run_command("yum install -y @base @core vim-enhanced emacs-nox tree")
|
60
56
|
end
|
61
|
-
|
62
|
-
return
|
57
|
+
platform_container.stop
|
58
|
+
return platform_container
|
63
59
|
end
|
64
60
|
|
65
61
|
def self.assign_ip_address(ipaddress, container_name, hwaddr)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dev-lxc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremiah Snapp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0.
|
61
|
+
version: 1.0.2
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0.
|
68
|
+
version: 1.0.2
|
69
69
|
description: A tool for creating Chef server clusters using LXC containers
|
70
70
|
email:
|
71
71
|
- jeremiah@getchef.com
|
@@ -81,7 +81,6 @@ files:
|
|
81
81
|
- Rakefile
|
82
82
|
- bin/dev-lxc
|
83
83
|
- dev-lxc.gemspec
|
84
|
-
- files/configs/ha.yaml
|
85
84
|
- files/configs/open-source.yaml
|
86
85
|
- files/configs/standalone.yaml
|
87
86
|
- files/configs/tier.yaml
|
@@ -111,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
110
|
version: '0'
|
112
111
|
requirements: []
|
113
112
|
rubyforge_project:
|
114
|
-
rubygems_version: 2.4.
|
113
|
+
rubygems_version: 2.4.4
|
115
114
|
signing_key:
|
116
115
|
specification_version: 4
|
117
116
|
summary: A tool for creating Chef server clusters using LXC containers
|
data/files/configs/ha.yaml
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
base_platform: b-ubuntu-1404
|
2
|
-
topology: ha
|
3
|
-
api_fqdn: chef-ha.lxc
|
4
|
-
mounts:
|
5
|
-
- /dev-shared dev-shared
|
6
|
-
packages:
|
7
|
-
server: /dev-shared/chef-packages/cs/chef-server-core_12.0.1-1_amd64.deb
|
8
|
-
# reporting: /dev-shared/chef-packages/cs/reporting/opscode-reporting_1.2.3-1_amd64.deb
|
9
|
-
# push-jobs-server: /dev-shared/chef-packages/cs/push-jobs-server/opscode-push-jobs-server_1.1.6-1_amd64.deb
|
10
|
-
# manage: /dev-shared/chef-packages/cs/manage/opscode-manage_1.6.2-1_amd64.deb
|
11
|
-
servers:
|
12
|
-
be1-ha.lxc:
|
13
|
-
role: backend
|
14
|
-
ipaddress: 10.0.3.206
|
15
|
-
bootstrap: true
|
16
|
-
cluster_ipaddress: 192.168.0.5
|
17
|
-
be2-ha.lxc:
|
18
|
-
role: backend
|
19
|
-
ipaddress: 10.0.3.207
|
20
|
-
cluster_ipaddress: 192.168.0.6
|
21
|
-
fe1-ha.lxc:
|
22
|
-
role: frontend
|
23
|
-
ipaddress: 10.0.3.208
|
24
|
-
# fe2-ha.lxc:
|
25
|
-
# role: frontend
|
26
|
-
# ipaddress: 10.0.3.209
|
27
|
-
backend_vip:
|
28
|
-
be-ha.lxc:
|
29
|
-
ipaddress: 10.0.3.210
|
30
|
-
device: eth0
|
31
|
-
heartbeat_device: eth1
|