caterer 0.0.1 → 0.1.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.
- data/.gitignore +1 -0
- data/Berksfile +3 -0
- data/Berksfile.lock +0 -0
- data/README.md +138 -2
- data/Vagrantfile +22 -0
- data/bin/cater +9 -0
- data/caterer.gemspec +5 -0
- data/cookbooks/users/recipes/default.rb +18 -0
- data/example/Caterfile +28 -10
- data/example/bootstrap.sh +3 -0
- data/knife.rb +1 -0
- data/lib/caterer/action/base.rb +10 -0
- data/lib/caterer/action/config/validate/image.rb +23 -0
- data/lib/caterer/action/config/validate/provisioner.rb +29 -0
- data/lib/caterer/action/config/validate.rb +10 -0
- data/lib/caterer/action/config.rb +7 -0
- data/lib/caterer/action/provisioner/base.rb +16 -0
- data/lib/caterer/action/provisioner/bootstrap.rb +14 -0
- data/lib/caterer/action/provisioner/cleanup.rb +14 -0
- data/lib/caterer/action/provisioner/prepare.rb +14 -0
- data/lib/caterer/action/provisioner/provision.rb +14 -0
- data/lib/caterer/action/provisioner.rb +11 -0
- data/lib/caterer/action/server/validate/ssh.rb +22 -0
- data/lib/caterer/action/server/validate.rb +9 -0
- data/lib/caterer/action/server.rb +7 -0
- data/lib/caterer/action.rb +9 -0
- data/lib/caterer/actions.rb +48 -0
- data/lib/caterer/command/base.rb +100 -0
- data/lib/caterer/command/bootstrap.rb +28 -0
- data/lib/caterer/command/provision.rb +24 -0
- data/lib/caterer/command/reboot.rb +22 -0
- data/lib/caterer/command/test.rb +9 -2
- data/lib/caterer/command/up.rb +28 -0
- data/lib/caterer/command.rb +6 -1
- data/lib/caterer/commands.rb +6 -1
- data/lib/caterer/communication/rsync.rb +14 -0
- data/lib/caterer/communication/ssh.rb +185 -0
- data/lib/caterer/communication.rb +6 -0
- data/lib/caterer/config/base.rb +24 -11
- data/lib/caterer/config/group.rb +24 -0
- data/lib/caterer/config/image.rb +20 -0
- data/lib/caterer/config/member.rb +14 -0
- data/lib/caterer/config/provision/chef_solo.rb +36 -12
- data/lib/caterer/config/provision.rb +5 -3
- data/lib/caterer/config.rb +5 -1
- data/lib/caterer/environment.rb +38 -12
- data/lib/caterer/provisioner/base.rb +19 -0
- data/lib/caterer/provisioner/chef_solo.rb +150 -0
- data/lib/caterer/provisioner.rb +6 -0
- data/lib/caterer/server.rb +102 -0
- data/lib/caterer/util/ansi_escape_code_remover.rb +34 -0
- data/lib/caterer/util/retryable.rb +25 -0
- data/lib/caterer/util.rb +6 -0
- data/lib/caterer/version.rb +1 -1
- data/lib/caterer.rb +15 -5
- data/lib/templates/provisioner/chef_solo/bootstrap.sh +87 -0
- data/lib/templates/provisioner/chef_solo/solo.erb +3 -0
- metadata +124 -3
- data/lib/caterer/config/role.rb +0 -21
data/.gitignore
CHANGED
data/Berksfile
ADDED
data/Berksfile.lock
ADDED
File without changes
|
data/README.md
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
# Caterer
|
2
2
|
|
3
|
-
|
3
|
+
Heavily inspired by vagrant, caterer is a remote server configuration tool that caters to your servers using a collaborative, fast, and iterative push model. Caterer supports chef-solo by default.
|
4
|
+
|
5
|
+
## Why?
|
6
|
+
|
7
|
+
Caterer is designed as a workflow-first utility around 3 guiding principles:
|
8
|
+
|
9
|
+
1. Configuration as code.
|
10
|
+
2. Push provisioning.
|
11
|
+
3. Modular provisioner.
|
12
|
+
|
13
|
+
Caterer does not replace chef or puppet, but leverages them to provide a faster iterative approach to live infrastructures. If you're familiar with the vagrant workflow, imagine that your 'boxes' are remote servers and you'll feel right at home.
|
14
|
+
|
15
|
+
The goal of caterer is that an entire infrastructure definition lives within a git repo. An infrastructure developer can open the Caterfile and read the infrastructure like a map. All provisioning recipes or definitions will live within this repo, and infrastructure developers can interate repidly to provide a hot infrastructure.
|
4
16
|
|
5
17
|
## Installation
|
6
18
|
|
@@ -18,7 +30,131 @@ Or install it yourself as:
|
|
18
30
|
|
19
31
|
## Usage
|
20
32
|
|
21
|
-
|
33
|
+
### Caterfile
|
34
|
+
|
35
|
+
Caterer loads a Caterfile from the current directory. A Caterfile defines your infrastructure in a centralized, familiar ruby dsl. A Caterfile essentially creates a library of images that can be aggregated and applied to live servers.
|
36
|
+
|
37
|
+
### Images
|
38
|
+
|
39
|
+
An image is a configuration construct that defines the end state of the machine after that image has been applied. An image requires a provisioner.
|
40
|
+
|
41
|
+
### Provisioner
|
42
|
+
|
43
|
+
A provisioner is the tool that will provision a server to meet the end requirements of an image. Currently only chef-solo is supported.
|
44
|
+
|
45
|
+
### Member
|
46
|
+
|
47
|
+
A member is an optional configuration for servers. Storing live server credentials in a version controlled repo is not suitable for many infrastructures, but is there for your convenience if you want it.
|
48
|
+
|
49
|
+
### Group
|
50
|
+
|
51
|
+
A group is a simply way of grouping images or members to provide agrregate funcionality in a simple, concise way.
|
52
|
+
|
53
|
+
## Example
|
54
|
+
|
55
|
+
### Caterfile
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
Caterer.configure do |config|
|
59
|
+
|
60
|
+
config.image :basic do |image|
|
61
|
+
image.provision :chef_solo do |chef|
|
62
|
+
chef.cookbooks_path = ['cookbooks'] # default
|
63
|
+
chef.add_recipe 'ruby'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
config.image :rails do |image|
|
68
|
+
image.provision :chef_solo do |chef|
|
69
|
+
chef.bootstrap_script = 'script/bootstrap'
|
70
|
+
chef.cookbooks_path = ['cookbooks'] # default
|
71
|
+
chef.add_recipe 'ruby'
|
72
|
+
chef.add_recipe 'mysql::server'
|
73
|
+
chef.add_recipe 'mysql::client'
|
74
|
+
chef.json = {
|
75
|
+
"ruby" => {
|
76
|
+
"gems" => ['mysql2']
|
77
|
+
}
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
config.member :m1 do |member|
|
83
|
+
member.images = [:basic]
|
84
|
+
member.host = "192.168.1.101"
|
85
|
+
member.password = 'samIam'
|
86
|
+
end
|
87
|
+
|
88
|
+
config.group :oven do |group|
|
89
|
+
|
90
|
+
group.images = [:basic, :rails]
|
91
|
+
group.user = 'root' # optional
|
92
|
+
group.password = 'password' # optional
|
93
|
+
|
94
|
+
# optional member configuration
|
95
|
+
group.member :oven1 do |m|
|
96
|
+
m.host = "192.168.1.100"
|
97
|
+
end
|
98
|
+
|
99
|
+
group.member :oven2 do |m|
|
100
|
+
m.host = "192.168.1.101"
|
101
|
+
m.password = 'samIam'
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
### Command Line
|
110
|
+
|
111
|
+
Provision a server with a basic image (image defined in Caterfile)
|
112
|
+
|
113
|
+
```bash
|
114
|
+
cater provision -i basic HOST
|
115
|
+
```
|
116
|
+
|
117
|
+
Provision a server with multiple images (images defined in Caterfile)
|
118
|
+
|
119
|
+
```bash
|
120
|
+
cater provision -i basic,rails HOST
|
121
|
+
```
|
122
|
+
|
123
|
+
Provision a server with a group (group defined in Caterfile)
|
124
|
+
|
125
|
+
```bash
|
126
|
+
cater provision -g oven HOST
|
127
|
+
```
|
128
|
+
|
129
|
+
Provision a server from a member defined in Caterfile
|
130
|
+
|
131
|
+
```bash
|
132
|
+
cater provision m1
|
133
|
+
```
|
134
|
+
|
135
|
+
Provision a server from a group member
|
136
|
+
|
137
|
+
```bash
|
138
|
+
cater provision oven::oven1
|
139
|
+
```
|
140
|
+
|
141
|
+
Provision multiple servers from members defined in Caterfile
|
142
|
+
|
143
|
+
```bash
|
144
|
+
cater provision m1,oven::oven1,oven::oven2
|
145
|
+
```
|
146
|
+
|
147
|
+
Bootstrap a server
|
148
|
+
|
149
|
+
```bash
|
150
|
+
cater bootstrap -i basic HOST
|
151
|
+
```
|
152
|
+
|
153
|
+
Boostrap and provision a server
|
154
|
+
|
155
|
+
```bash
|
156
|
+
cater up -i basic HOST
|
157
|
+
```
|
22
158
|
|
23
159
|
## Contributing
|
24
160
|
|
data/Vagrantfile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# require 'berkshelf/vagrant'
|
4
|
+
require 'vagrant-vbguest' unless defined? VagrantVbguest::Config
|
5
|
+
|
6
|
+
Vagrant::Config.run do |config|
|
7
|
+
|
8
|
+
config.berkshelf.config_path = './knife.rb'
|
9
|
+
|
10
|
+
config.vm.box = "precise64"
|
11
|
+
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
|
12
|
+
config.vm.customize ["modifyvm", :id, "--cpus", 1, "--memory", 512]
|
13
|
+
config.vm.network :hostonly, "33.33.33.10"
|
14
|
+
config.vm.share_folder("v-root", "/vagrant", ".")
|
15
|
+
config.vbguest.auto_update = true
|
16
|
+
|
17
|
+
config.vm.provision :chef_solo do |chef|
|
18
|
+
chef.cookbooks_path = ['cookbooks']
|
19
|
+
chef.add_recipe 'users'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/bin/cater
CHANGED
@@ -28,6 +28,15 @@ else
|
|
28
28
|
opts[:ui_class] = Vli::UI::Colored
|
29
29
|
end
|
30
30
|
|
31
|
+
# strip out a custom config file and set it into the env opts
|
32
|
+
if ARGV.include? "-c"
|
33
|
+
index = ARGV.index '-c'
|
34
|
+
value = ARGV[index + 1]
|
35
|
+
opts[:custom_config] = value
|
36
|
+
ARGV.delete('-c')
|
37
|
+
ARGV.delete(value)
|
38
|
+
end
|
39
|
+
|
31
40
|
env = Caterer::Environment.new(opts)
|
32
41
|
|
33
42
|
env.load!
|
data/caterer.gemspec
CHANGED
@@ -15,6 +15,11 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.add_dependency 'log4r'
|
16
16
|
gem.add_dependency 'activesupport'
|
17
17
|
gem.add_dependency 'vli'
|
18
|
+
gem.add_dependency 'net-ssh'
|
19
|
+
gem.add_dependency 'net-scp'
|
20
|
+
gem.add_dependency 'tilt'
|
21
|
+
gem.add_dependency 'oj'
|
22
|
+
gem.add_dependency 'multi_json', '>= 1.3'
|
18
23
|
|
19
24
|
gem.files = `git ls-files`.split($/)
|
20
25
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
package "build-essential" do
|
3
|
+
action :nothing
|
4
|
+
end.run_action(:install)
|
5
|
+
|
6
|
+
package 'whois'
|
7
|
+
chef_gem 'ruby-shadow'
|
8
|
+
|
9
|
+
[['bert', 'password'], ['ernie', 'password'], ['tylerflint', 'password']].each do |u, pass|
|
10
|
+
user u do
|
11
|
+
supports :manage_home => true
|
12
|
+
home "/home/#{u}"
|
13
|
+
gid "admin"
|
14
|
+
shell "/bin/bash"
|
15
|
+
password `echo #{pass} | mkpasswd -s -m sha-512`.chomp
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
data/example/Caterfile
CHANGED
@@ -1,25 +1,43 @@
|
|
1
1
|
Caterer.configure do |config|
|
2
2
|
|
3
|
-
config.
|
3
|
+
config.image :basic do |image|
|
4
|
+
image.provision :chef_solo do |chef|
|
5
|
+
chef.cookbooks_path = ['cookbooks'] # default
|
6
|
+
chef.add_recipe 'ruby'
|
7
|
+
end
|
8
|
+
end
|
4
9
|
|
5
|
-
|
10
|
+
config.image :rails do |image|
|
11
|
+
image.provision :chef_solo do |chef|
|
12
|
+
chef.bootstrap_script = 'script/bootstrap'
|
13
|
+
chef.cookbooks_path = ['cookbooks'] # default
|
6
14
|
chef.add_recipe 'ruby'
|
7
15
|
chef.add_recipe 'mysql::server'
|
8
16
|
chef.add_recipe 'mysql::client'
|
9
17
|
chef.json = {
|
10
18
|
"ruby" => {
|
11
19
|
"gems" => ['args_parser', 'mysql2']
|
12
|
-
},
|
13
|
-
"mysql" => {
|
14
|
-
"server_root_password" => "root",
|
15
|
-
"bind_address" => '127.0.0.1',
|
16
|
-
"client" => {
|
17
|
-
"packages" => ["mysql-client", "libmysqlclient-dev"]
|
18
|
-
}
|
19
20
|
}
|
20
21
|
}
|
21
22
|
end
|
23
|
+
end
|
24
|
+
|
25
|
+
config.group :oven do |group|
|
26
|
+
|
27
|
+
group.images = [:basic, :rails]
|
28
|
+
group.user = 'root'
|
29
|
+
group.password = 'password'
|
30
|
+
|
31
|
+
group.member :oven1 do |m|
|
32
|
+
m.host = "192.168.1.100"
|
33
|
+
end
|
34
|
+
|
35
|
+
group.member :oven2 do |m|
|
36
|
+
m.host = "192.168.1.101"
|
37
|
+
m.password = 'samIam'
|
38
|
+
end
|
22
39
|
|
23
40
|
end
|
24
41
|
|
25
|
-
end
|
42
|
+
end
|
43
|
+
|
data/knife.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
#whatev
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Action
|
3
|
+
module Config
|
4
|
+
module Validate
|
5
|
+
class Image < Base
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
# check to ensure the image exists
|
9
|
+
image = env[:config].images[env[:image]]
|
10
|
+
|
11
|
+
if not image
|
12
|
+
env[:ui].error "image ':#{env[:image]}' is not defined"
|
13
|
+
return
|
14
|
+
end
|
15
|
+
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Action
|
3
|
+
module Config
|
4
|
+
module Validate
|
5
|
+
class Provisioner < Base
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
provisioner = env[:config].images[env[:image]].provisioner
|
9
|
+
|
10
|
+
if not provisioner
|
11
|
+
env[:ui].error "provisioner for image ':#{env[:image]}' is not defined"
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
if errors = provisioner.errors
|
16
|
+
errors.each do |key, val|
|
17
|
+
env[:ui].error "image :#{env[:image]} provisioner error -> #{key} #{val}"
|
18
|
+
end
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
@app.call(env)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module Caterer
|
4
|
+
module Action
|
5
|
+
module Provisioner
|
6
|
+
class Base < Action::Base
|
7
|
+
|
8
|
+
def provisioner(env)
|
9
|
+
config = env[:config].images[env[:image]].provisioner
|
10
|
+
"Caterer::Provisioner::#{config.name.to_s.classify}".constantize.new(env[:server], config)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Action
|
3
|
+
module Provisioner
|
4
|
+
autoload :Base, 'caterer/action/provisioner/base'
|
5
|
+
autoload :Bootstrap, 'caterer/action/provisioner/bootstrap'
|
6
|
+
autoload :Cleanup, 'caterer/action/provisioner/cleanup'
|
7
|
+
autoload :Prepare, 'caterer/action/provisioner/prepare'
|
8
|
+
autoload :Provision, 'caterer/action/provisioner/provision'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Action
|
3
|
+
module Server
|
4
|
+
module Validate
|
5
|
+
class SSH < Base
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
ready = env[:server].ssh.ready?
|
9
|
+
|
10
|
+
if not ready
|
11
|
+
env[:ui].error "unable to ssh into #{env[:server].host}"
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Action
|
3
|
+
autoload :Base, 'caterer/action/base'
|
4
|
+
autoload :Config, 'caterer/action/config'
|
5
|
+
autoload :Runner, 'caterer/action/runner'
|
6
|
+
autoload :Provisioner, 'caterer/action/provisioner'
|
7
|
+
autoload :Server, 'caterer/action/server'
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# actions
|
2
|
+
Caterer.actions.register(:validate) do
|
3
|
+
Vli::Action::Builder.new do
|
4
|
+
use Caterer::Action::Config::Validate::Image
|
5
|
+
use Caterer::Action::Config::Validate::Provisioner
|
6
|
+
use Caterer::Action::Server::Validate::SSH
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Caterer.actions.register(:prepare) do
|
11
|
+
Vli::Action::Builder.new do
|
12
|
+
use Caterer::Action::Provisioner::Prepare
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Caterer.actions.register(:cleanup) do
|
17
|
+
Vli::Action::Builder.new do
|
18
|
+
use Caterer::Action::Provisioner::Cleanup
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Caterer.actions.register(:bootstrap) do
|
23
|
+
Vli::Action::Builder.new do
|
24
|
+
use Caterer.actions.get(:validate)
|
25
|
+
use Caterer.actions.get(:prepare)
|
26
|
+
use Caterer::Action::Provisioner::Bootstrap
|
27
|
+
use Caterer.actions.get(:cleanup)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Caterer.actions.register(:provision) do
|
32
|
+
Vli::Action::Builder.new do
|
33
|
+
use Caterer.actions.get(:validate)
|
34
|
+
use Caterer.actions.get(:prepare)
|
35
|
+
use Caterer::Action::Provisioner::Provision
|
36
|
+
use Caterer.actions.get(:cleanup)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
Caterer.actions.register(:up) do
|
41
|
+
Vli::Action::Builder.new do
|
42
|
+
use Caterer.actions.get(:validate)
|
43
|
+
use Caterer.actions.get(:prepare)
|
44
|
+
use Caterer::Action::Provisioner::Bootstrap
|
45
|
+
use Caterer::Action::Provisioner::Provision
|
46
|
+
use Caterer.actions.get(:cleanup)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Command
|
3
|
+
class Base < Vli::Command::Base
|
4
|
+
|
5
|
+
def parse_options(opts=nil, options={}, force_argv=true)
|
6
|
+
opts ||= OptionParser.new
|
7
|
+
opts.separator ""
|
8
|
+
opts.on("-c CONFIG", 'assumes Caterfile in current directory')
|
9
|
+
opts.separator ""
|
10
|
+
opts.on("-u USER", "--user USER", 'assumes current username') do |u|
|
11
|
+
options[:user] = u
|
12
|
+
end
|
13
|
+
opts.on('-p PASSWORD', '--password PASSWORD', 'assumes key') do |p|
|
14
|
+
options[:pass] = p
|
15
|
+
end
|
16
|
+
opts.on('-P PORT', '--port PORT', 'assumes 22') do |p|
|
17
|
+
options[:port] = p
|
18
|
+
end
|
19
|
+
opts.on('-i IMAGE', '--image IMAGE', 'corresponds to a image in Caterfile') do |i|
|
20
|
+
options[:image] = i
|
21
|
+
end
|
22
|
+
opts.on('-g GROUP', '--group GROUP', 'corresponds to a group in Caterfile') do |g|
|
23
|
+
options[:group] = g
|
24
|
+
end
|
25
|
+
opts.separator ""
|
26
|
+
|
27
|
+
begin
|
28
|
+
argv = super(opts)
|
29
|
+
raise if force_argv and (not argv or argv.length == 0)
|
30
|
+
argv
|
31
|
+
rescue
|
32
|
+
safe_puts(opts.help)
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def with_target_servers(argv, options={})
|
39
|
+
target_servers(argv, options).each do |server|
|
40
|
+
yield server if block_given?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def target_servers(argv, options={})
|
45
|
+
@servers ||= begin
|
46
|
+
servers = []
|
47
|
+
|
48
|
+
argv.first.split(",").each do |host|
|
49
|
+
|
50
|
+
if group = @env.config.groups[host.to_sym]
|
51
|
+
group.members.each do |member|
|
52
|
+
servers << init_server(group, member, options)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
|
56
|
+
if not host.match /::/
|
57
|
+
host = "default::#{host}"
|
58
|
+
end
|
59
|
+
|
60
|
+
g, m = host.split "::"
|
61
|
+
group = nil
|
62
|
+
member = nil
|
63
|
+
|
64
|
+
if group = @env.config.groups[g.to_sym]
|
65
|
+
member = group.members[m.to_sym]
|
66
|
+
end
|
67
|
+
|
68
|
+
servers << init_server(group, member, options.merge(:host => m))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
servers
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def init_server(group=nil, member=nil, options={})
|
77
|
+
|
78
|
+
group ||= Config::Group.new
|
79
|
+
member ||= Config::Member.new
|
80
|
+
|
81
|
+
opts = {}
|
82
|
+
opts[:alias] = member.name
|
83
|
+
opts[:user] = options[:user] || member.user || group.user
|
84
|
+
opts[:pass] = options[:pass] || member.password || group.password
|
85
|
+
opts[:host] = member.host || options[:host]
|
86
|
+
opts[:port] = options[:port] || member.port
|
87
|
+
opts[:images] = image_list(options) || member.images || group.images
|
88
|
+
|
89
|
+
Server.new(@env, opts)
|
90
|
+
end
|
91
|
+
|
92
|
+
def image_list(options={})
|
93
|
+
if images = options[:image]
|
94
|
+
images.split(',').map(&:to_sym)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|