dev-lxc 0.5.0 → 0.6.0

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.
@@ -1,18 +1,40 @@
1
- platform_container: p-ubuntu-1404
2
- topology: standalone
3
- api_fqdn: chef.lxc
4
- #analytics_fqdn: analytics.lxc
5
- mounts:
6
- - /dev-shared dev-shared
7
- packages:
8
- server: /dev-shared/chef-packages/cs/chef-server-core_12.0.5-1_amd64.deb
9
- # manage: /dev-shared/chef-packages/manage/opscode-manage_1.11.2-1_amd64.deb
10
- # reporting: /dev-shared/chef-packages/reporting/opscode-reporting_1.2.3-1_amd64.deb
11
- # push-jobs-server: /dev-shared/chef-packages/push-jobs-server/opscode-push-jobs-server_1.1.6-1_amd64.deb
12
- # analytics: /dev-shared/chef-packages/analytics/opscode-analytics_1.1.1-1_amd64.deb
13
- servers:
14
- standalone-chef.lxc:
15
- ipaddress: 10.0.3.201
16
- # standalone-analytics.lxc:
17
- # role: analytics
18
- # ipaddress: 10.0.3.202
1
+ ## Mount source directories must exist in the LXC host
2
+
3
+ ## Make sure package paths are correct
4
+
5
+ ## All FQDNs and server names must end with the `.lxc` domain
6
+
7
+ ## DHCP reserved (static) IPs must be selected from the IP range 10.0.3.150 - 254
8
+
9
+ chef-server:
10
+ platform_image: p-ubuntu-1404
11
+ mounts:
12
+ - /dev-shared dev-shared
13
+ packages:
14
+ server: /dev-shared/chef-packages/cs/chef-server-core_12.0.7-1_amd64.deb
15
+ manage: /dev-shared/chef-packages/manage/opscode-manage_1.11.2-1_amd64.deb
16
+ # reporting: /dev-shared/chef-packages/reporting/opscode-reporting_1.2.3-1_amd64.deb
17
+ # push-jobs-server: /dev-shared/chef-packages/push-jobs-server/opscode-push-jobs-server_1.1.6-1_amd64.deb
18
+
19
+ ## The chef-sync package would only be installed.
20
+ ## It would NOT be configured since we don't know whether it should be a master or replica.
21
+ # sync: /dev-shared/chef-packages/sync/chef-sync_1.0.0~rc.6-1_amd64.deb
22
+
23
+ api_fqdn: chef.lxc
24
+ topology: standalone
25
+ servers:
26
+ chef.lxc:
27
+ ipaddress: 10.0.3.201
28
+
29
+ analytics:
30
+ platform_image: p-ubuntu-1404
31
+ mounts:
32
+ - /dev-shared dev-shared
33
+ packages:
34
+ analytics: /dev-shared/chef-packages/analytics/opscode-analytics_1.1.2-1_amd64.deb
35
+
36
+ analytics_fqdn: analytics.lxc
37
+ topology: standalone
38
+ servers:
39
+ analytics.lxc:
40
+ ipaddress: 10.0.3.202
@@ -1,26 +1,56 @@
1
- platform_container: p-ubuntu-1404
2
- topology: tier
3
- api_fqdn: chef.lxc
4
- #analytics_fqdn: analytics.lxc
5
- mounts:
6
- - /dev-shared dev-shared
7
- packages:
8
- server: /dev-shared/chef-packages/cs/chef-server-core_12.0.5-1_amd64.deb
9
- # manage: /dev-shared/chef-packages/manage/opscode-manage_1.11.2-1_amd64.deb
10
- # reporting: /dev-shared/chef-packages/reporting/opscode-reporting_1.2.3-1_amd64.deb
11
- # push-jobs-server: /dev-shared/chef-packages/push-jobs-server/opscode-push-jobs-server_1.1.6-1_amd64.deb
12
- # analytics: /dev-shared/chef-packages/analytics/opscode-analytics_1.1.1-1_amd64.deb
13
- servers:
14
- tier-be.lxc:
15
- role: backend
16
- ipaddress: 10.0.3.203
17
- bootstrap: true
18
- tier-fe1.lxc:
19
- role: frontend
20
- ipaddress: 10.0.3.204
21
- # tier-fe2.lxc:
22
- # role: frontend
23
- # ipaddress: 10.0.3.205
24
- # tier-analytics.lxc:
25
- # role: analytics
26
- # ipaddress: 10.0.3.206
1
+ ## Mount source directories must exist in the LXC host
2
+
3
+ ## Make sure package paths are correct
4
+
5
+ ## All FQDNs and server names must end with the `.lxc` domain
6
+
7
+ ## DHCP reserved (static) IPs must be selected from the IP range 10.0.3.150 - 254
8
+
9
+ chef-server:
10
+ platform_image: p-ubuntu-1404
11
+ mounts:
12
+ - /dev-shared dev-shared
13
+ packages:
14
+ server: /dev-shared/chef-packages/cs/chef-server-core_12.0.7-1_amd64.deb
15
+ manage: /dev-shared/chef-packages/manage/opscode-manage_1.11.2-1_amd64.deb
16
+ # reporting: /dev-shared/chef-packages/reporting/opscode-reporting_1.2.3-1_amd64.deb
17
+ # push-jobs-server: /dev-shared/chef-packages/push-jobs-server/opscode-push-jobs-server_1.1.6-1_amd64.deb
18
+
19
+ ## The chef-sync package would only be installed.
20
+ ## It would NOT be configured since we don't know whether it should be a master or replica.
21
+ # sync: /dev-shared/chef-packages/sync/chef-sync_1.0.0~rc.6-1_amd64.deb
22
+
23
+ api_fqdn: chef.lxc
24
+ topology: tier
25
+ servers:
26
+ chef-be.lxc:
27
+ role: backend
28
+ ipaddress: 10.0.3.203
29
+ bootstrap: true
30
+ chef-fe1.lxc:
31
+ role: frontend
32
+ ipaddress: 10.0.3.204
33
+ # chef-fe2.lxc:
34
+ # role: frontend
35
+ # ipaddress: 10.0.3.205
36
+
37
+ analytics:
38
+ platform_image: p-ubuntu-1404
39
+ mounts:
40
+ - /dev-shared dev-shared
41
+ packages:
42
+ analytics: /dev-shared/chef-packages/analytics/opscode-analytics_1.1.2-1_amd64.deb
43
+
44
+ analytics_fqdn: analytics.lxc
45
+ topology: tier
46
+ servers:
47
+ analytics-be.lxc:
48
+ role: backend
49
+ ipaddress: 10.0.3.206
50
+ bootstrap: true
51
+ analytics-fe1.lxc:
52
+ role: frontend
53
+ ipaddress: 10.0.3.207
54
+ # analytics-fe2.lxc:
55
+ # role: frontend
56
+ # ipaddress: 10.0.3.208
data/lib/dev-lxc/cli.rb CHANGED
@@ -7,32 +7,35 @@ module DevLXC::CLI
7
7
 
8
8
  no_commands{
9
9
  def get_cluster(config_option)
10
- config = "dev-lxc.yaml" if File.exists?("dev-lxc.yaml")
11
- config = "dev-lxc.yml" if File.exists?("dev-lxc.yml")
12
- config = config_option unless config_option.nil?
13
- raise "A cluster config file must be provided" if config.nil?
14
- ::DevLXC::ChefCluster.new(YAML.load(IO.read(config)))
10
+ config = options[:config]
11
+ config ||= "dev-lxc.yml"
12
+ if ! File.exists?(config)
13
+ puts "ERROR: Cluster config file `config` does not exist."
14
+ puts " Create a `./dev-lxc.yml` file or specify the path using `-c`."
15
+ exit 1
16
+ end
17
+ ::DevLXC::Cluster.new(YAML.load(IO.read(config)))
15
18
  end
16
19
 
17
- def match_pattern(pattern)
18
- get_cluster(options[:config]).chef_servers.select { |cs| cs.server.name =~ /#{pattern}/ }
20
+ def match_server_name_regex(server_name_regex)
21
+ get_cluster(options[:config]).servers.select { |s| s.server.name =~ /#{server_name_regex}/ }
19
22
  end
20
23
  }
21
24
 
22
- desc "create [PLATFORM_CONTAINER_NAME]", "Create a platform container"
23
- def create(platform_container_name=nil)
24
- platform_container_names = %w(p-ubuntu-1204 p-ubuntu-1404 p-centos-5 p-centos-6)
25
- if platform_container_name.nil? || ! platform_container_names.include?(platform_container_name)
26
- platform_container_names_with_index = platform_container_names.map.with_index{ |a, i| [i+1, *a]}
27
- print_table platform_container_names_with_index
28
- selection = ask("Which platform container do you want to create?", :limited_to => platform_container_names_with_index.map{|c| c[0].to_s})
29
- platform_container_name = platform_container_names[selection.to_i - 1]
25
+ desc "create [PLATFORM_IMAGE_NAME]", "Create a platform image"
26
+ def create(platform_image_name=nil)
27
+ platform_image_names = %w(p-ubuntu-1204 p-ubuntu-1404 p-centos-5 p-centos-6)
28
+ if platform_image_name.nil? || ! platform_image_names.include?(platform_image_name)
29
+ platform_image_names_with_index = platform_image_names.map.with_index{ |a, i| [i+1, *a]}
30
+ print_table platform_image_names_with_index
31
+ selection = ask("Which platform image do you want to create?", :limited_to => platform_image_names_with_index.map{|c| c[0].to_s})
32
+ platform_image_name = platform_image_names[selection.to_i - 1]
30
33
  end
31
- ::DevLXC.create_platform_container(platform_container_name)
34
+ ::DevLXC.create_platform_image(platform_image_name)
32
35
  end
33
36
 
34
- desc "init [TOPOLOGY]", "Provide a cluster config file"
35
- def init(topology=nil)
37
+ desc "init [TOPOLOGY] [UNIQUE_STRING]", "Provide a cluster config file with optional uniqueness in server names and FQDNs"
38
+ def init(topology=nil, unique_string=nil)
36
39
  topologies = %w(open-source standalone tier)
37
40
  if topology.nil? || ! topologies.include?(topology)
38
41
  topologies_with_index = topologies.map.with_index{ |a, i| [i+1, *a]}
@@ -40,73 +43,133 @@ module DevLXC::CLI
40
43
  selection = ask("Which cluster topology do you want to use?", :limited_to => topologies_with_index.map{|c| c[0].to_s})
41
44
  topology = topologies[selection.to_i - 1]
42
45
  end
43
- puts IO.read("#{File.dirname(__FILE__)}/../../files/configs/#{topology}.yml")
46
+ config = IO.read("#{File.dirname(__FILE__)}/../../files/configs/#{topology}.yml")
47
+ unless unique_string.nil?
48
+ config_hash = YAML.load(config.gsub(/^#/, ''))
49
+ config.gsub!(/api_fqdn:\s+#{config_hash['api_fqdn']}/, "api_fqdn: #{unique_string}#{config_hash['api_fqdn']}")
50
+ config.gsub!(/analytics_fqdn:\s+#{config_hash['analytics_fqdn']}/, "analytics_fqdn: #{unique_string}#{config_hash['analytics_fqdn']}")
51
+ config_hash['chef-server']['servers'].keys.each do |server_name|
52
+ config.gsub!(/ #{server_name}:/, " #{unique_string}#{server_name}:")
53
+ end
54
+ config_hash['analytics']['servers'].keys.each do |server_name|
55
+ config.gsub!(/ #{server_name}:/, " #{unique_string}#{server_name}:")
56
+ end
57
+ end
58
+ puts config
44
59
  end
45
60
 
46
- desc "status", "Show status of servers"
47
- option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yml will be used by default"
48
- def status(pattern=nil)
49
- config = "dev-lxc.yaml" if File.exists?("dev-lxc.yaml")
50
- config = "dev-lxc.yml" if File.exists?("dev-lxc.yml")
51
- config = options[:config] unless options[:config].nil?
52
- raise "A cluster config file must be provided" if config.nil?
53
- cluster_config = YAML.load(IO.read(config))
54
-
55
- puts "Cluster is available at https://#{cluster_config['api_fqdn']}"
56
- puts "Analytics is available at https://#{cluster_config['analytics_fqdn']}" if cluster_config['analytics_fqdn']
57
- match_pattern(pattern).each { |cs| cs.status }
61
+ desc "status [SERVER_NAME_REGEX]", "Show status of servers"
62
+ option :config, :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
63
+ def status(server_name_regex=nil)
64
+ cluster = get_cluster(options[:config])
65
+ puts "Chef Server: https://#{cluster.api_fqdn}\n\n"
66
+ puts "Analytics: https://#{cluster.analytics_fqdn}\n\n" if cluster.analytics_fqdn
67
+ match_server_name_regex(server_name_regex).each { |s| s.status }
58
68
  end
59
69
 
60
- desc "abspath [ROOTFS_PATH]", "Returns the absolute path to a file in each server"
61
- option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yml will be used by default"
62
- def abspath(pattern=nil, rootfs_path)
70
+ desc "abspath [SERVER_NAME_REGEX] [ROOTFS_PATH]", "Returns the absolute path to a file in each server"
71
+ option :config, :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
72
+ def abspath(server_name_regex=nil, rootfs_path)
63
73
  abspath = Array.new
64
- match_pattern(pattern).map { |cs| abspath << cs.abspath(rootfs_path) }
74
+ match_server_name_regex(server_name_regex).map { |s| abspath << s.abspath(rootfs_path) }
65
75
  puts abspath.compact.join(" ")
66
76
  end
67
77
 
68
- desc "chef-repo", "Creates a chef-repo in the current directory using files from the cluster's backend /root/chef-repo"
69
- option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yml will be used by default"
78
+ desc "chef-repo", "Creates a `bootstrap-node` script and chef-repo in the current directory using files from the cluster's backend /root/chef-repo"
79
+ option :config, :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
70
80
  def chef_repo
71
81
  get_cluster(options[:config]).chef_repo
72
82
  end
73
83
 
74
- desc "run_command [COMMAND]", "Runs a command in each server"
75
- option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yml will be used by default"
76
- def run_command(pattern=nil, command)
77
- match_pattern(pattern).each { |cs| cs.run_command(command) }
84
+ desc "list_images [SERVER_NAME_REGEX]", "List of each servers' images created during the build process"
85
+ option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
86
+ def list_images(server_name_regex=nil)
87
+ images = Hash.new { |h,k| h[k] = Hash.new { |h,k| h[k] = Array.new } }
88
+ match_server_name_regex(server_name_regex).each do |s|
89
+ images[s.platform_image_name][s.shared_image_name] << s.server.name
90
+ end
91
+ images.each_with_index do |(platform_name, shared), images_index|
92
+ shared.each_with_index do |(shared_name, final), shared_index|
93
+ printf "Platform: %21s %s\n", (LXC::Container.new(platform_name).defined? ? "Created" : "Not Created"), platform_name
94
+ puts "|"
95
+ printf "\\_ Shared: %20s %s\n", (LXC::Container.new(shared_name).defined? ? "Created" : "Not Created"), shared_name
96
+ final.each_with_index do |final_name, final_index|
97
+ puts " |"
98
+ unique_name = "u-#{final_name}"
99
+ printf " \\_ Unique: %17s %s\n", (LXC::Container.new(unique_name).defined? ? "Created" : "Not Created"), unique_name
100
+
101
+ shared_connector = (final_index + 1 < final.length ? "|" : " ")
102
+
103
+ custom_name = "c-#{final_name}"
104
+ if LXC::Container.new(custom_name).defined?
105
+ printf " #{shared_connector} \\_ Custom: %14s %s\n", "Created", custom_name
106
+ custom_spacing = " "
107
+ final_width = 12
108
+ else
109
+ final_width = 15
110
+ end
111
+ printf " #{shared_connector} #{custom_spacing}\\_ Final: %#{final_width}s %s\n", (LXC::Container.new(final_name).defined? ? "Created" : "Not Created"), final_name
112
+ end
113
+ puts if (shared_index + 1 < shared.length) || (images_index + 1 < images.length)
114
+ end
115
+ end
116
+ end
117
+
118
+ desc "run_command [SERVER_NAME_REGEX] [COMMAND]", "Runs a command in each server"
119
+ option :config, :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
120
+ def run_command(server_name_regex=nil, command)
121
+ match_server_name_regex(server_name_regex).each { |s| s.run_command(command) }
78
122
  end
79
123
 
80
- desc "start", "Start servers"
81
- option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yml will be used by default"
82
- def start(pattern=nil)
83
- match_pattern(pattern).each { |cs| cs.start }
124
+ desc "up [SERVER_NAME_REGEX]", "Start servers - This is the default if no subcommand is given"
125
+ option :config, :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
126
+ def up(server_name_regex=nil)
127
+ match_server_name_regex(server_name_regex).each { |s| s.start }
84
128
  end
85
129
 
86
- # make `start` the default subcommand and pass any arguments to it
87
- default_task :start
88
- def method_missing(method, *args)
89
- args = ["start", method.to_s] + args
90
- DevLXC.start(args)
130
+ desc "halt [SERVER_NAME_REGEX]", "Stop servers"
131
+ option :config, :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
132
+ def halt(server_name_regex=nil)
133
+ match_server_name_regex(server_name_regex).reverse_each { |s| s.stop }
91
134
  end
92
135
 
93
- desc "stop", "Stop servers"
94
- option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yml will be used by default"
95
- def stop(pattern=nil)
96
- match_pattern(pattern).reverse_each { |cs| cs.stop }
136
+ desc "snapshot [SERVER_NAME_REGEX]", "Create a snapshot of servers"
137
+ option :config, :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
138
+ option :force, :aliases => "-f", :type => :boolean, :desc => "Overwrite existing custom images"
139
+ def snapshot(server_name_regex=nil)
140
+ non_stopped_servers = Array.new
141
+ existing_custom_images = Array.new
142
+ match_server_name_regex(server_name_regex).each do |s|
143
+ non_stopped_servers << s.server.name if s.server.state != :stopped
144
+ existing_custom_images << s.server.name if LXC::Container.new("c-#{s.server.name}").defined?
145
+ end
146
+ unless non_stopped_servers.empty?
147
+ puts "WARNING: Aborting snapshot because the following servers are not stopped"
148
+ puts non_stopped_servers
149
+ exit 1
150
+ end
151
+ unless existing_custom_images.empty? || options[:force]
152
+ puts "WARNING: The following servers already have a custom image"
153
+ puts " Use the `--force` or `-f` option to overwrite existing custom images"
154
+ puts existing_custom_images
155
+ exit 1
156
+ end
157
+ match_server_name_regex(server_name_regex).each { |s| s.snapshot(options[:force]) }
97
158
  end
98
159
 
99
- desc "destroy", "Destroy servers"
100
- option :config, :aliases => "-c", :desc => "Specify a cluster's YAML config file. ./dev-lxc.yml will be used by default"
101
- option :unique, :aliases => "-u", :type => :boolean, :desc => "Also destroy the unique containers"
102
- option :shared, :aliases => "-s", :type => :boolean, :desc => "Also destroy the shared container"
103
- option :platform, :aliases => "-p", :type => :boolean, :desc => "Also destroy the platform container"
104
- def destroy(pattern=nil)
105
- match_pattern(pattern).reverse_each do |cs|
106
- cs.destroy
107
- cs.destroy_container(:unique) if options[:unique]
108
- cs.destroy_container(:shared) if options[:shared]
109
- cs.destroy_container(:platform) if options[:platform]
160
+ desc "destroy [SERVER_NAME_REGEX]", "Destroy servers"
161
+ option :config, :desc => "Specify a cluster's YAML config file. `./dev-lxc.yml` will be used by default"
162
+ option :custom, :aliases => "-c", :type => :boolean, :desc => "Also destroy the custom images"
163
+ option :unique, :aliases => "-u", :type => :boolean, :desc => "Also destroy the unique images"
164
+ option :shared, :aliases => "-s", :type => :boolean, :desc => "Also destroy the shared images"
165
+ option :platform, :aliases => "-p", :type => :boolean, :desc => "Also destroy the platform images"
166
+ def destroy(server_name_regex=nil)
167
+ match_server_name_regex(server_name_regex).reverse_each do |s|
168
+ s.destroy
169
+ s.destroy_image(:custom) if options[:custom]
170
+ s.destroy_image(:unique) if options[:unique]
171
+ s.destroy_image(:shared) if options[:shared]
172
+ s.destroy_image(:platform) if options[:platform]
110
173
  end
111
174
  end
112
175
 
@@ -0,0 +1,174 @@
1
+ require "dev-lxc/server"
2
+
3
+ module DevLXC
4
+ class Cluster
5
+ attr_reader :api_fqdn, :analytics_fqdn, :chef_server_bootstrap_backend, :analytics_bootstrap_backend
6
+
7
+ def initialize(cluster_config)
8
+ @cluster_config = cluster_config
9
+
10
+ @chef_server_topology = @cluster_config["chef-server"]["topology"]
11
+ @api_fqdn = @cluster_config["chef-server"]["api_fqdn"]
12
+ @chef_server_servers = @cluster_config["chef-server"]["servers"]
13
+ @chef_server_frontends = Array.new
14
+ @chef_server_servers.each do |name, config|
15
+ case @chef_server_topology
16
+ when 'open-source', 'standalone'
17
+ @chef_server_bootstrap_backend = name if config["role"].nil?
18
+ when 'tier'
19
+ @chef_server_bootstrap_backend = name if config["role"] == "backend" && config["bootstrap"] == true
20
+ @chef_server_frontends << name if config["role"] == "frontend"
21
+ end
22
+ end
23
+
24
+ @analytics_topology = @cluster_config["analytics"]["topology"]
25
+ @analytics_fqdn = @cluster_config["analytics"]["analytics_fqdn"]
26
+ @analytics_servers = @cluster_config["analytics"]["servers"]
27
+ @analytics_frontends = Array.new
28
+ @analytics_servers.each do |name, config|
29
+ case @analytics_topology
30
+ when 'standalone'
31
+ @analytics_bootstrap_backend = name if config["role"].nil?
32
+ when 'tier'
33
+ @analytics_bootstrap_backend = name if config["role"] == "backend" && config["bootstrap"] == true
34
+ @analytics_frontends << name if config["role"] == "frontend"
35
+ end
36
+ end
37
+ end
38
+
39
+ def servers
40
+ chef_servers = Array.new
41
+ chef_servers << Server.new(@chef_server_bootstrap_backend, 'chef-server', @cluster_config)
42
+ if @chef_server_topology == "tier"
43
+ @chef_server_frontends.each do |frontend_name|
44
+ chef_servers << Server.new(frontend_name, 'chef-server', @cluster_config)
45
+ end
46
+ end
47
+ analytics_servers = Array.new
48
+ analytics_servers << Server.new(@analytics_bootstrap_backend, 'analytics', @cluster_config)
49
+ if @analytics_topology == "tier"
50
+ @analytics_frontends.each do |frontend_name|
51
+ analytics_servers << Server.new(frontend_name, 'analytics', @cluster_config)
52
+ end
53
+ end
54
+ servers = chef_servers + analytics_servers
55
+ end
56
+
57
+ def chef_repo
58
+ chef_server = Server.new(@chef_server_bootstrap_backend, 'chef-server', @cluster_config)
59
+ if ! chef_server.server.defined?
60
+ puts "The '#{chef_server.server.name}' Chef Server does not exist. Please create it first."
61
+ exit 1
62
+ end
63
+
64
+ puts "Creating chef-repo with pem files and knife.rb in the current directory"
65
+ FileUtils.mkdir_p("./chef-repo/.chef")
66
+
67
+ pem_files = Dir.glob("#{chef_server.abspath('/root/chef-repo/.chef')}/*.pem")
68
+ if pem_files.empty?
69
+ 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"
70
+ else
71
+ FileUtils.cp( pem_files, "./chef-repo/.chef" )
72
+ end
73
+
74
+ if @chef_server_topology == "open-source"
75
+ chef_server_url = "https://#{@api_fqdn}"
76
+ username = "admin"
77
+ validator_name = "chef-validator"
78
+ else
79
+ chef_server_url = "https://#{@api_fqdn}/organizations/ponyville"
80
+ username = "rainbowdash"
81
+ validator_name = "ponyville-validator"
82
+ end
83
+
84
+ knife_rb = %Q(
85
+ current_dir = File.dirname(__FILE__)
86
+
87
+ chef_server_url "#{chef_server_url}"
88
+
89
+ node_name "#{username}"
90
+ client_key "\#{current_dir}/#{username}.pem"
91
+
92
+ validation_client_name "#{validator_name}"
93
+ validation_key "\#{current_dir}/#{validator_name}.pem"
94
+
95
+ cookbook_path Dir.pwd + "/cookbooks"
96
+ knife[:chef_repo_path] = Dir.pwd
97
+ )
98
+ IO.write("./chef-repo/.chef/knife.rb", knife_rb)
99
+
100
+ bootstrap_node = %Q(#!/bin/bash
101
+
102
+ if [[ -z $1 ]]; then
103
+ echo "Please provide the name of the node to be bootstrapped"
104
+ return 1
105
+ fi
106
+
107
+ xc-start $1
108
+
109
+ xc-chef-config -s #{chef_server_url} \\
110
+ -u #{validator_name} \\
111
+ -k ./chef-repo/.chef/#{validator_name}.pem
112
+
113
+ if [[ -n $2 ]]; then
114
+ xc-attach chef-client -r $2
115
+ else
116
+ xc-attach chef-client
117
+ fi
118
+ )
119
+ IO.write("./bootstrap-node", bootstrap_node)
120
+ FileUtils.chmod("u+x", "./bootstrap-node")
121
+ end
122
+
123
+ def chef_server_config
124
+ chef_server_config = %Q(api_fqdn "#{@api_fqdn}"\n)
125
+ if @chef_server_topology == 'tier'
126
+ chef_server_config += %Q(
127
+ topology "#{@chef_server_topology}"
128
+
129
+ server "#{@chef_server_bootstrap_backend}",
130
+ :ipaddress => "#{@chef_server_servers[@chef_server_bootstrap_backend]["ipaddress"]}",
131
+ :role => "backend",
132
+ :bootstrap => true
133
+
134
+ backend_vip "#{@chef_server_bootstrap_backend}",
135
+ :ipaddress => "#{@chef_server_servers[@chef_server_bootstrap_backend]["ipaddress"]}"
136
+ )
137
+ @chef_server_frontends.each do |frontend_name|
138
+ chef_server_config += %Q(
139
+ server "#{frontend_name}",
140
+ :ipaddress => "#{@chef_server_servers[frontend_name]["ipaddress"]}",
141
+ :role => "frontend"
142
+ )
143
+ end
144
+ end
145
+ return chef_server_config
146
+ end
147
+
148
+ def analytics_config
149
+ analytics_config = %Q(analytics_fqdn "#{@analytics_fqdn}"
150
+ topology "#{@analytics_topology}"
151
+ )
152
+ if @analytics_topology == 'tier'
153
+ analytics_config += %Q(
154
+ server "#{@analytics_bootstrap_backend}",
155
+ :ipaddress => "#{@analytics_servers[@analytics_bootstrap_backend]["ipaddress"]}",
156
+ :role => "backend",
157
+ :bootstrap => true
158
+
159
+ backend_vip "#{@analytics_bootstrap_backend}",
160
+ :ipaddress => "#{@analytics_servers[@analytics_bootstrap_backend]["ipaddress"]}"
161
+ )
162
+ @analytics_frontends.each do |frontend_name|
163
+ analytics_config += %Q(
164
+ server "#{frontend_name}",
165
+ :ipaddress => "#{@analytics_servers[frontend_name]["ipaddress"]}",
166
+ :role => "frontend"
167
+ )
168
+ end
169
+ end
170
+ return analytics_config
171
+ end
172
+
173
+ end
174
+ end
@@ -30,14 +30,14 @@ module DevLXC
30
30
 
31
31
  def sync_mounts(mounts)
32
32
  existing_mounts = self.config_item("lxc.mount.entry")
33
- if existing_mounts.is_a?(Array)
33
+ unless existing_mounts.nil?
34
34
  preserved_mounts = existing_mounts.delete_if { |m| m.end_with?("## dev-lxc ##") }
35
35
  self.clear_config_item('lxc.mount.entries')
36
36
  self.set_config_item("lxc.mount.entry", preserved_mounts)
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
- if preserved_mounts.any? { |m| m.start_with?("#{mount} ") }
40
+ if ! preserved_mounts.nil? && preserved_mounts.any? { |m| m.start_with?("#{mount} ") }
41
41
  puts "Skipping mount entry #{mount}, it already exists"
42
42
  next
43
43
  else