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
@@ -0,0 +1,28 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Command
|
3
|
+
class Bootstrap < Base
|
4
|
+
|
5
|
+
def execute
|
6
|
+
options = {}
|
7
|
+
opts = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: cater bootstrap HOST [options]"
|
9
|
+
opts.separator ""
|
10
|
+
opts.on("-s SCRIPT", "--script SCRIPT", 'optional bootstrap script') do |s|
|
11
|
+
options[:script] = s
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Parse the options
|
16
|
+
argv = parse_options(opts, options, true)
|
17
|
+
return if not argv
|
18
|
+
|
19
|
+
with_target_servers(argv, options) do |server|
|
20
|
+
server.bootstrap({:script => options[:script]})
|
21
|
+
end
|
22
|
+
|
23
|
+
0
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Command
|
3
|
+
class Provision < Base
|
4
|
+
|
5
|
+
def execute
|
6
|
+
options = {}
|
7
|
+
opts = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: cater provision HOST [options]"
|
9
|
+
end
|
10
|
+
|
11
|
+
# Parse the options
|
12
|
+
argv = parse_options(opts, options, true)
|
13
|
+
return if not argv
|
14
|
+
|
15
|
+
with_target_servers(argv, options) do |server|
|
16
|
+
server.provision
|
17
|
+
end
|
18
|
+
|
19
|
+
0
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Command
|
3
|
+
class Reboot < Base
|
4
|
+
|
5
|
+
def execute
|
6
|
+
options = {}
|
7
|
+
opts = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: cater provision HOST [options]"
|
9
|
+
end
|
10
|
+
|
11
|
+
# Parse the options
|
12
|
+
argv = parse_options(opts, options, true)
|
13
|
+
return if not argv
|
14
|
+
|
15
|
+
@env.ui.info options
|
16
|
+
@env.ui.info argv
|
17
|
+
0
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/caterer/command/test.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
module Caterer
|
2
2
|
module Command
|
3
|
-
class Test <
|
3
|
+
class Test < Base
|
4
4
|
|
5
5
|
def execute
|
6
|
-
|
6
|
+
options = {}
|
7
|
+
opts = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: cater test"
|
9
|
+
end
|
10
|
+
|
11
|
+
# Parse the options
|
12
|
+
argv = parse_options(opts, options, false)
|
13
|
+
|
7
14
|
0
|
8
15
|
end
|
9
16
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Command
|
3
|
+
class Up < Base
|
4
|
+
|
5
|
+
def execute
|
6
|
+
options = {}
|
7
|
+
opts = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: cater provision HOST [options]"
|
9
|
+
opts.separator ""
|
10
|
+
opts.on("-s SCRIPT", "--script SCRIPT", 'optional bootstrap script') do |s|
|
11
|
+
options[:script] = s
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Parse the options
|
16
|
+
argv = parse_options(opts, options, true)
|
17
|
+
return if not argv
|
18
|
+
|
19
|
+
with_target_servers(argv, options) do |server|
|
20
|
+
server.up({:script => options[:script]})
|
21
|
+
end
|
22
|
+
|
23
|
+
0
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/caterer/command.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
module Caterer
|
2
2
|
module Command
|
3
|
-
autoload :
|
3
|
+
autoload :Base, 'caterer/command/base'
|
4
|
+
autoload :Bootstrap, 'caterer/command/bootstrap'
|
5
|
+
autoload :Provision, 'caterer/command/provision'
|
6
|
+
autoload :Reboot, 'caterer/command/reboot'
|
7
|
+
autoload :Test, 'caterer/command/test'
|
8
|
+
autoload :Up, 'caterer/command/up'
|
4
9
|
end
|
5
10
|
end
|
data/lib/caterer/commands.rb
CHANGED
@@ -1 +1,6 @@
|
|
1
|
-
|
1
|
+
# commands
|
2
|
+
Caterer.commands.register(:test) { Caterer::Command::Test }
|
3
|
+
Caterer.commands.register(:bootstrap) { Caterer::Command::Bootstrap }
|
4
|
+
Caterer.commands.register(:provision) { Caterer::Command::Provision }
|
5
|
+
Caterer.commands.register(:up) { Caterer::Command::Up }
|
6
|
+
Caterer.commands.register(:reboot) { Caterer::Command::Reboot }
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'net/scp'
|
4
|
+
require 'log4r'
|
5
|
+
|
6
|
+
module Caterer
|
7
|
+
module Communication
|
8
|
+
class SSH
|
9
|
+
include Util::ANSIEscapeCodeRemover
|
10
|
+
include Util::Retryable
|
11
|
+
|
12
|
+
def initialize(server)
|
13
|
+
@server = server
|
14
|
+
@connection = nil
|
15
|
+
@logger = Log4r::Logger.new("caterer::communication::ssh")
|
16
|
+
end
|
17
|
+
|
18
|
+
def ready?
|
19
|
+
@logger.debug("Checking whether SSH is ready...")
|
20
|
+
|
21
|
+
Timeout.timeout(30) do
|
22
|
+
connect
|
23
|
+
end
|
24
|
+
|
25
|
+
# If we reached this point then we successfully connected
|
26
|
+
@logger.info("SSH is ready!")
|
27
|
+
true
|
28
|
+
rescue => e
|
29
|
+
# The above errors represent various reasons that SSH may not be
|
30
|
+
# ready yet. Return false.
|
31
|
+
@logger.info("SSH not up: #{e.inspect}")
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
|
35
|
+
def execute(command, opts={}, &block)
|
36
|
+
connect do |connection|
|
37
|
+
shell_execute(connection, command, opts, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def sudo(command, opts={}, &block)
|
42
|
+
sudo = (@server.username == 'root') ? false : true
|
43
|
+
execute(command, opts.merge({:sudo => sudo}), &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
def upload(from, to)
|
47
|
+
@logger.debug("Uploading: #{from} to #{to}")
|
48
|
+
|
49
|
+
# Do an SCP-based upload...
|
50
|
+
connect do |connection|
|
51
|
+
opts = {}
|
52
|
+
opts[:recursive] = true if from.is_a?(String) and File.directory?(from)
|
53
|
+
scp = Net::SCP.new(connection)
|
54
|
+
scp.upload!(from, to, opts)
|
55
|
+
end
|
56
|
+
rescue Net::SCP::Error => e
|
57
|
+
# If we get the exit code of 127, then this means SCP is unavailable.
|
58
|
+
raise "scp unavailable" if e.message =~ /\(127\)/
|
59
|
+
|
60
|
+
# Otherwise, just raise the error up
|
61
|
+
raise
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# Opens an SSH connection and yields it to a block.
|
67
|
+
def connect
|
68
|
+
if @connection && !@connection.closed?
|
69
|
+
# There is a chance that the socket is closed despite us checking
|
70
|
+
# 'closed?' above. To test this we need to send data through the
|
71
|
+
# socket.
|
72
|
+
begin
|
73
|
+
@connection.exec!("")
|
74
|
+
rescue IOError
|
75
|
+
@logger.info("Connection has been closed. Not re-using.")
|
76
|
+
@connection = nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# If the @connection is still around, then it is valid,
|
80
|
+
# and we use it.
|
81
|
+
if @connection
|
82
|
+
@logger.debug("Re-using SSH connection.")
|
83
|
+
return yield @connection if block_given?
|
84
|
+
return
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Connect to SSH, giving it a few tries
|
89
|
+
connection = nil
|
90
|
+
# These are the exceptions that we retry because they represent
|
91
|
+
# errors that are generally fixed from a retry and don't
|
92
|
+
# necessarily represent immediate failure cases.
|
93
|
+
exceptions = [
|
94
|
+
Errno::ECONNREFUSED,
|
95
|
+
Errno::EHOSTUNREACH,
|
96
|
+
Net::SSH::Disconnect,
|
97
|
+
Timeout::Error
|
98
|
+
]
|
99
|
+
|
100
|
+
@logger.info("Connecting to SSH: (#{@server.host}:#{@server.port}")
|
101
|
+
@server.ui.info "Connecting..."
|
102
|
+
connection = retryable(:tries => 10, :on => exceptions) do
|
103
|
+
Net::SSH.start(@server.host, @server.username, @server.ssh_opts)
|
104
|
+
end
|
105
|
+
|
106
|
+
@connection = connection
|
107
|
+
|
108
|
+
# This is hacky but actually helps with some issues where
|
109
|
+
# Net::SSH is simply not robust enough to handle... see
|
110
|
+
# issue #391, #455, etc.
|
111
|
+
# sleep 4
|
112
|
+
|
113
|
+
# Yield the connection that is ready to be used and
|
114
|
+
# return the value of the block
|
115
|
+
return yield connection if block_given?
|
116
|
+
end
|
117
|
+
|
118
|
+
# Executes the command on an SSH connection within a login shell.
|
119
|
+
def shell_execute(connection, command, opts={})
|
120
|
+
|
121
|
+
opts[:sudo] ||= false
|
122
|
+
opts[:stream] ||= false
|
123
|
+
|
124
|
+
@logger.info("Execute: #{command} (opts=#{opts.inspect})")
|
125
|
+
exit_status = nil
|
126
|
+
|
127
|
+
# Determine the shell to execute. If we are using `sudo` then we
|
128
|
+
# need to wrap the shell in a `sudo` call.
|
129
|
+
shell = "bash -l"
|
130
|
+
shell = "sudo -H #{shell}" if opts[:sudo]
|
131
|
+
|
132
|
+
# Open the channel so we can execute or command
|
133
|
+
channel = connection.open_channel do |ch|
|
134
|
+
ch.exec(shell) do |ch2, _|
|
135
|
+
# Setup the channel callbacks so we can get data and exit status
|
136
|
+
ch2.on_data do |ch3, data|
|
137
|
+
@logger.debug("stdout: #{data}")
|
138
|
+
if block_given?
|
139
|
+
# Filter out the clear screen command
|
140
|
+
data = remove_ansi_escape_codes(data)
|
141
|
+
yield :stdout, data
|
142
|
+
end
|
143
|
+
if opts[:stream]
|
144
|
+
@server.ui.info data, {:prefix => false, :new_line => false}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
ch2.on_extended_data do |ch3, type, data|
|
149
|
+
@logger.debug("stderr: #{data}")
|
150
|
+
if block_given?
|
151
|
+
# Filter out the clear screen command
|
152
|
+
data = remove_ansi_escape_codes(data)
|
153
|
+
yield :stderr, data
|
154
|
+
end
|
155
|
+
if opts[:stream]
|
156
|
+
@server.ui.info data, {:prefix => false, :new_line => false}
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
ch2.on_request("exit-status") do |ch3, data|
|
161
|
+
exit_status = data.read_long
|
162
|
+
@logger.debug("Exit status: #{exit_status}")
|
163
|
+
end
|
164
|
+
|
165
|
+
# Set the terminal
|
166
|
+
ch2.send_data "export TERM=vt100\n"
|
167
|
+
|
168
|
+
# Output the command
|
169
|
+
ch2.send_data "#{command}\n"
|
170
|
+
|
171
|
+
# Remember to exit or this channel will hang open
|
172
|
+
ch2.send_data "exit\n"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Wait for the channel to complete
|
177
|
+
channel.wait
|
178
|
+
|
179
|
+
# Return the final exit status
|
180
|
+
return exit_status
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
data/lib/caterer/config/base.rb
CHANGED
@@ -1,17 +1,30 @@
|
|
1
|
-
module Caterer
|
1
|
+
module Caterer
|
2
|
+
module Config
|
3
|
+
class Base
|
2
4
|
|
3
|
-
|
4
|
-
attr_accessor :roles
|
5
|
+
attr_reader :images, :groups
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def initialize
|
8
|
+
@images = {}
|
9
|
+
@groups = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def image(name)
|
13
|
+
@images[name] ||= Image.new(name)
|
14
|
+
yield @images[name] if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def group(name)
|
18
|
+
@groups[name] ||= Group.new(name)
|
19
|
+
yield @groups[name] if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
def member(name, &block)
|
23
|
+
group(:default) do |d|
|
24
|
+
d.member(name, &block)
|
25
|
+
end
|
26
|
+
end
|
9
27
|
|
10
|
-
def role(name)
|
11
|
-
role = Caterer::Config::Role.new(name)
|
12
|
-
yield role if block_given?
|
13
|
-
@roles << role
|
14
28
|
end
|
15
29
|
end
|
16
|
-
|
17
30
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Config
|
3
|
+
class Group
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
attr_accessor :images, :members, :user, :password
|
7
|
+
|
8
|
+
def initialize(name=nil)
|
9
|
+
@name = name
|
10
|
+
@images = []
|
11
|
+
@members = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_image(image)
|
15
|
+
@images << image
|
16
|
+
end
|
17
|
+
|
18
|
+
def member(name)
|
19
|
+
@members[name] ||= Member.new(name)
|
20
|
+
yield @members[name] if block_given?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module Caterer
|
4
|
+
module Config
|
5
|
+
class Image
|
6
|
+
|
7
|
+
attr_reader :name, :provisioner
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name
|
11
|
+
end
|
12
|
+
|
13
|
+
def provision(type)
|
14
|
+
@provisioner = "Caterer::Config::Provision::#{type.to_s.classify}".constantize.new(type)
|
15
|
+
yield @provisioner if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,18 +1,42 @@
|
|
1
|
-
module Caterer
|
1
|
+
module Caterer
|
2
|
+
module Config
|
3
|
+
module Provision
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
5
|
+
class ChefSolo
|
6
|
+
|
7
|
+
attr_reader :name, :run_list
|
8
|
+
attr_accessor :json, :cookbooks_path, :roles_path, :data_bags_path, :bootstrap_script
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
@run_list = []
|
13
|
+
@json = {}
|
14
|
+
@cookbooks_path = ['cookbooks']
|
15
|
+
@roles_path = ['roles']
|
16
|
+
@data_bags_path = ['data_bags']
|
17
|
+
end
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
19
|
+
def add_recipe(recipe)
|
20
|
+
@run_list << "recipe[#{recipe}]"
|
21
|
+
end
|
15
22
|
|
16
|
-
|
23
|
+
def add_role(role)
|
24
|
+
@run_list << "role[#{role}]"
|
25
|
+
end
|
26
|
+
|
27
|
+
def errors
|
28
|
+
errors = {}
|
17
29
|
|
30
|
+
if not @run_list.length > 0
|
31
|
+
errors[:run_list] = "is empty"
|
32
|
+
end
|
33
|
+
|
34
|
+
if errors.length > 0
|
35
|
+
errors
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
18
42
|
end
|
data/lib/caterer/config.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
module Caterer
|
2
2
|
module Config
|
3
3
|
autoload :Base, 'caterer/config/base'
|
4
|
-
autoload :
|
4
|
+
autoload :Cluster, 'caterer/config/cluster'
|
5
|
+
autoload :Group, 'caterer/config/group'
|
6
|
+
autoload :Member, 'caterer/config/member'
|
7
|
+
autoload :Node, 'caterer/config/node'
|
8
|
+
autoload :Image, 'caterer/config/image'
|
5
9
|
autoload :Provision, 'caterer/config/provision'
|
6
10
|
end
|
7
11
|
end
|
data/lib/caterer/environment.rb
CHANGED
@@ -9,42 +9,68 @@ module Caterer
|
|
9
9
|
opts = {
|
10
10
|
:cwd => nil,
|
11
11
|
:caterfile_name => nil,
|
12
|
-
:ui_class => nil
|
12
|
+
:ui_class => nil,
|
13
|
+
:custom_config => nil
|
13
14
|
}.merge(opts)
|
14
15
|
|
15
16
|
opts[:cwd] ||= ENV["CATERER_CWD"] if ENV.has_key?("CATERER_CWD")
|
16
17
|
opts[:cwd] ||= Dir.pwd
|
17
|
-
opts[:cwd] = Pathname.new(opts[:cwd])
|
18
18
|
|
19
19
|
opts[:caterfile_name] ||= []
|
20
|
-
opts[:caterfile_name] = [opts[:caterfile_name]] if !opts[:
|
20
|
+
opts[:caterfile_name] = [opts[:caterfile_name]] if !opts[:caterfile_name].is_a?(Array)
|
21
21
|
opts[:caterfile_name] += ["Caterfile"]
|
22
22
|
|
23
|
-
@cwd = opts[:cwd]
|
23
|
+
@cwd = Pathname.new(opts[:cwd])
|
24
24
|
@caterfile_name = opts[:caterfile_name]
|
25
|
+
@custom_config = opts[:custom_config]
|
25
26
|
|
26
27
|
ui_class = opts[:ui_class] || Vli::UI::Silent
|
27
28
|
@ui = ui_class.new("cater")
|
28
29
|
|
29
30
|
end
|
30
31
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
32
|
+
def action_runner
|
33
|
+
@action_runner ||= Vli::Action::Runner.new(action_registry) do
|
34
|
+
{
|
35
|
+
:action_runner => action_runner,
|
36
|
+
:ui => @ui
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def action_registry
|
42
|
+
Caterer.actions
|
43
|
+
end
|
44
|
+
|
45
|
+
def config
|
46
|
+
@config ||= begin
|
47
|
+
load_default_config
|
48
|
+
load_custom_config
|
49
|
+
Caterer.config
|
50
|
+
end
|
34
51
|
end
|
52
|
+
alias :load! :config
|
35
53
|
|
36
54
|
def load_default_config
|
37
|
-
|
38
|
-
# require 'config/default'
|
55
|
+
require_relative '../../config/default'
|
39
56
|
end
|
40
57
|
|
41
58
|
def load_custom_config
|
42
|
-
@
|
43
|
-
|
44
|
-
|
59
|
+
if @custom_config
|
60
|
+
# if it's been explicitly defined, load it
|
61
|
+
load_config_file @custom_config
|
62
|
+
else
|
63
|
+
# lets try a few variations
|
64
|
+
@caterfile_name.each do |config_file|
|
65
|
+
load_config_file "#{@cwd}/#{config_file}"
|
66
|
+
end
|
45
67
|
end
|
46
68
|
end
|
47
69
|
|
70
|
+
def load_config_file(file)
|
71
|
+
load file if File.exists? file
|
72
|
+
end
|
73
|
+
|
48
74
|
def cli(*args)
|
49
75
|
Cli.new(args.flatten, self).execute
|
50
76
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Caterer
|
2
|
+
module Provisioner
|
3
|
+
class Base
|
4
|
+
|
5
|
+
attr_reader :server
|
6
|
+
|
7
|
+
def initialize(server, config=nil)
|
8
|
+
@server = server
|
9
|
+
@config = config
|
10
|
+
end
|
11
|
+
|
12
|
+
def bootstrap(script=nil); end
|
13
|
+
def prepare; end
|
14
|
+
def provision; end
|
15
|
+
def cleanup; end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|