deployml 0.3.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/.document +3 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +22 -0
- data/LICENSE.txt +22 -0
- data/README.md +107 -0
- data/Rakefile +35 -0
- data/bin/deployml +5 -0
- data/deployml.gemspec +10 -0
- data/gemspec.yml +21 -0
- data/lib/deployml/cli.rb +192 -0
- data/lib/deployml/configuration.rb +149 -0
- data/lib/deployml/environment.rb +273 -0
- data/lib/deployml/exceptions/config_not_found.rb +4 -0
- data/lib/deployml/exceptions/invalid_config.rb +4 -0
- data/lib/deployml/exceptions/missing_option.rb +6 -0
- data/lib/deployml/exceptions/unknown_environment.rb +4 -0
- data/lib/deployml/exceptions/unknown_framework.rb +6 -0
- data/lib/deployml/exceptions/unknown_server.rb +6 -0
- data/lib/deployml/frameworks/rails2.rb +9 -0
- data/lib/deployml/frameworks/rails3.rb +20 -0
- data/lib/deployml/frameworks.rb +2 -0
- data/lib/deployml/local_shell.rb +54 -0
- data/lib/deployml/options/mongrel.rb +46 -0
- data/lib/deployml/options/thin.rb +72 -0
- data/lib/deployml/options.rb +1 -0
- data/lib/deployml/project.rb +304 -0
- data/lib/deployml/remote_shell.rb +130 -0
- data/lib/deployml/servers/apache.rb +19 -0
- data/lib/deployml/servers/mongrel.rb +41 -0
- data/lib/deployml/servers/thin.rb +41 -0
- data/lib/deployml/servers.rb +3 -0
- data/lib/deployml/shell.rb +46 -0
- data/lib/deployml/version.rb +4 -0
- data/lib/deployml.rb +2 -0
- data/spec/configuration_spec.rb +73 -0
- data/spec/deployml_spec.rb +11 -0
- data/spec/environment_spec.rb +34 -0
- data/spec/helpers/projects/bad_config/config/deploy.yml +1 -0
- data/spec/helpers/projects/basic/config/deploy.yml +3 -0
- data/spec/helpers/projects/invalid_server/config/deploy.yml +4 -0
- data/spec/helpers/projects/missing_config/.gitkeep +0 -0
- data/spec/helpers/projects/missing_dest/config/deploy.yml +2 -0
- data/spec/helpers/projects/missing_source/config/deploy.yml +2 -0
- data/spec/helpers/projects/rails/config/deploy/production.yml +10 -0
- data/spec/helpers/projects/rails/config/deploy/staging.yml +10 -0
- data/spec/helpers/projects/rails/config/deploy.yml +3 -0
- data/spec/helpers/projects.rb +11 -0
- data/spec/project_spec.rb +66 -0
- data/spec/spec_helper.rb +8 -0
- metadata +207 -0
@@ -0,0 +1,273 @@
|
|
1
|
+
require 'deployml/exceptions/missing_option'
|
2
|
+
require 'deployml/exceptions/unknown_server'
|
3
|
+
require 'deployml/exceptions/unknown_framework'
|
4
|
+
require 'deployml/configuration'
|
5
|
+
require 'deployml/local_shell'
|
6
|
+
require 'deployml/remote_shell'
|
7
|
+
require 'deployml/servers'
|
8
|
+
require 'deployml/frameworks'
|
9
|
+
|
10
|
+
module DeploYML
|
11
|
+
class Environment < Configuration
|
12
|
+
|
13
|
+
# Mapping of possible 'server' names to their mixins.
|
14
|
+
SERVERS = {
|
15
|
+
:apache => Servers::Apache,
|
16
|
+
:mongrel => Servers::Mongrel,
|
17
|
+
:thin => Servers::Thin
|
18
|
+
}
|
19
|
+
|
20
|
+
# Mapping of possible 'framework' names to their mixins.
|
21
|
+
FRAMEWORKS = {
|
22
|
+
:rails2 => Frameworks::Rails2,
|
23
|
+
:rails3 => Frameworks::Rails3
|
24
|
+
}
|
25
|
+
|
26
|
+
#
|
27
|
+
# Creates a new deployment environment.
|
28
|
+
#
|
29
|
+
# @param [Symbol, String] name
|
30
|
+
# The name of the deployment environment.
|
31
|
+
#
|
32
|
+
# @param [Hash{String => Object}] config
|
33
|
+
# Environment specific configuration.
|
34
|
+
#
|
35
|
+
# @raise [MissingOption]
|
36
|
+
# Either the `source` or `dest` options were not specified in the
|
37
|
+
# confirmation.
|
38
|
+
#
|
39
|
+
# @since 0.3.0
|
40
|
+
#
|
41
|
+
def initialize(name,config={})
|
42
|
+
super(config)
|
43
|
+
|
44
|
+
unless @source
|
45
|
+
raise(MissingOption,":source option is missing for the #{@name} environment")
|
46
|
+
end
|
47
|
+
|
48
|
+
unless @dest
|
49
|
+
raise(MissingOption,":dest option is missing for the #{@name} environment")
|
50
|
+
end
|
51
|
+
|
52
|
+
@environment ||= name.to_sym
|
53
|
+
|
54
|
+
load_framework!
|
55
|
+
load_server!
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Creates a local shell.
|
60
|
+
#
|
61
|
+
# @yield [shell]
|
62
|
+
# If a block is given, it will be passed the new local shell.
|
63
|
+
#
|
64
|
+
# @yieldparam [LocalShell] shell
|
65
|
+
# The remote shell session.
|
66
|
+
#
|
67
|
+
# @return [LocalShell]
|
68
|
+
# The local shell.
|
69
|
+
#
|
70
|
+
# @since 0.3.0
|
71
|
+
#
|
72
|
+
def local_shell(&block)
|
73
|
+
LocalShell.new(&block)
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Creates a remote shell with the destination server.
|
78
|
+
#
|
79
|
+
# @yield [shell]
|
80
|
+
# If a block is given, it will be passed the new remote shell.
|
81
|
+
#
|
82
|
+
# @yieldparam [RemoteShell] shell
|
83
|
+
# The remote shell.
|
84
|
+
#
|
85
|
+
# @return [RemoteShell]
|
86
|
+
# The remote shell.
|
87
|
+
#
|
88
|
+
# @since 0.3.0
|
89
|
+
#
|
90
|
+
def remote_shell(&block)
|
91
|
+
RemoteShell.new(@dest,&block)
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Runs a command on the destination server, in the destination
|
96
|
+
# directory.
|
97
|
+
#
|
98
|
+
# @return [true]
|
99
|
+
#
|
100
|
+
# @since 0.3.0
|
101
|
+
#
|
102
|
+
def exec(command)
|
103
|
+
remote_shell do |shell|
|
104
|
+
shell.cd(@dest.path)
|
105
|
+
shell.run(command)
|
106
|
+
end
|
107
|
+
|
108
|
+
return true
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Executes a Rake task on the destination server, in the destination
|
113
|
+
# directory.
|
114
|
+
#
|
115
|
+
# @return [true]
|
116
|
+
#
|
117
|
+
# @since 0.3.0
|
118
|
+
#
|
119
|
+
def rake(task,*args)
|
120
|
+
remote_shell do |shell|
|
121
|
+
shell.cd(@dest.path)
|
122
|
+
shell.rake(task,*args)
|
123
|
+
end
|
124
|
+
|
125
|
+
return true
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Starts an SSH session with the destination server.
|
130
|
+
#
|
131
|
+
# @param [Array] args
|
132
|
+
# Additional arguments to pass to SSH.
|
133
|
+
#
|
134
|
+
# @return [true]
|
135
|
+
#
|
136
|
+
# @since 0.3.0
|
137
|
+
#
|
138
|
+
def ssh(*args)
|
139
|
+
RemoteShell.new(@dest).ssh(*args)
|
140
|
+
return true
|
141
|
+
end
|
142
|
+
|
143
|
+
#
|
144
|
+
# Sets up the deployment repository for the project.
|
145
|
+
#
|
146
|
+
# @param [RemoteShell] shell
|
147
|
+
# The remote shell to execute commands through.
|
148
|
+
#
|
149
|
+
# @since 0.3.0
|
150
|
+
#
|
151
|
+
def setup(shell)
|
152
|
+
shell.run 'git', 'clone', '--depth', 1, @source, @dest.path
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# Updates the deployed repository for the project.
|
157
|
+
#
|
158
|
+
# @param [RemoteShell] shell
|
159
|
+
# The remote shell to execute commands through.
|
160
|
+
#
|
161
|
+
# @since 0.3.0
|
162
|
+
#
|
163
|
+
def update(shell)
|
164
|
+
shell.run 'git', 'reset', '--hard', 'HEAD'
|
165
|
+
shell.run 'git', 'pull'
|
166
|
+
end
|
167
|
+
|
168
|
+
#
|
169
|
+
# Place-holder method.
|
170
|
+
#
|
171
|
+
# @param [RemoteShell] shell
|
172
|
+
# The remote shell to execute commands through.
|
173
|
+
#
|
174
|
+
# @since 0.3.0
|
175
|
+
#
|
176
|
+
def install(shell)
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
# Place-holder method.
|
181
|
+
#
|
182
|
+
# @param [RemoteShell] shell
|
183
|
+
# The remote shell to execute commands through.
|
184
|
+
#
|
185
|
+
# @since 0.3.0
|
186
|
+
#
|
187
|
+
def migrate(shell)
|
188
|
+
end
|
189
|
+
|
190
|
+
#
|
191
|
+
# Place-holder method.
|
192
|
+
#
|
193
|
+
# @param [RemoteShell] shell
|
194
|
+
# The remote shell to execute commands through.
|
195
|
+
#
|
196
|
+
# @since 0.3.0
|
197
|
+
#
|
198
|
+
def server_config(shell)
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# Place-holder method.
|
203
|
+
#
|
204
|
+
# @param [RemoteShell] shell
|
205
|
+
# The remote shell to execute commands through.
|
206
|
+
#
|
207
|
+
# @since 0.3.0
|
208
|
+
#
|
209
|
+
def server_start(shell)
|
210
|
+
end
|
211
|
+
|
212
|
+
#
|
213
|
+
# Place-holder method.
|
214
|
+
#
|
215
|
+
# @param [RemoteShell] shell
|
216
|
+
# The remote shell to execute commands through.
|
217
|
+
#
|
218
|
+
# @since 0.3.0
|
219
|
+
#
|
220
|
+
def server_stop(shell)
|
221
|
+
end
|
222
|
+
|
223
|
+
#
|
224
|
+
# Place-holder method.
|
225
|
+
#
|
226
|
+
# @param [RemoteShell] shell
|
227
|
+
# The remote shell to execute commands through.
|
228
|
+
#
|
229
|
+
# @since 0.3.0
|
230
|
+
#
|
231
|
+
def server_restart(shell)
|
232
|
+
end
|
233
|
+
|
234
|
+
protected
|
235
|
+
|
236
|
+
#
|
237
|
+
# Loads the framework configuration.
|
238
|
+
#
|
239
|
+
# @since 0.3.0
|
240
|
+
#
|
241
|
+
def load_framework!
|
242
|
+
if @orm
|
243
|
+
unless FRAMEWORKS.has_key?(@framework)
|
244
|
+
raise(UnknownFramework,"Unknown framework #{@framework}")
|
245
|
+
end
|
246
|
+
|
247
|
+
extend FRAMEWORKS[@framework]
|
248
|
+
|
249
|
+
initialize_framework() if self.respond_to?(:initialize_framework)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
#
|
254
|
+
# Loads the server configuration.
|
255
|
+
#
|
256
|
+
# @raise [UnknownServer]
|
257
|
+
#
|
258
|
+
# @since 0.3.0
|
259
|
+
#
|
260
|
+
def load_server!
|
261
|
+
if @server_name
|
262
|
+
unless SERVERS.has_key?(@server_name)
|
263
|
+
raise(UnknownServer,"Unknown server name #{@server_name}")
|
264
|
+
end
|
265
|
+
|
266
|
+
extend SERVERS[@server_name]
|
267
|
+
|
268
|
+
initialize_server() if self.respond_to?(:initialize_server)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DeploYML
|
2
|
+
module Frameworks
|
3
|
+
module Rails3
|
4
|
+
def install(shell)
|
5
|
+
shell.run 'bundle', 'install', '--deployment'
|
6
|
+
end
|
7
|
+
|
8
|
+
def migrate(shell)
|
9
|
+
task = case @orm
|
10
|
+
when :datamapper
|
11
|
+
'db:autoupgrade'
|
12
|
+
else
|
13
|
+
'db:migrate'
|
14
|
+
end
|
15
|
+
|
16
|
+
shell.run 'rake', task, "RAILS_ENV=#{@environment}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'deployml/shell'
|
2
|
+
|
3
|
+
module DeploYML
|
4
|
+
class LocalShell
|
5
|
+
|
6
|
+
include Shell
|
7
|
+
|
8
|
+
#
|
9
|
+
# Runs a program locally.
|
10
|
+
#
|
11
|
+
# @param [String] program
|
12
|
+
# The name or path of the program to run.
|
13
|
+
#
|
14
|
+
# @param [Array<String>] args
|
15
|
+
# Additional arguments for the program.
|
16
|
+
#
|
17
|
+
def run(program,*args)
|
18
|
+
system(program,*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Prints out a message.
|
23
|
+
#
|
24
|
+
# @param [String] message
|
25
|
+
# The message to print.
|
26
|
+
#
|
27
|
+
def echo(message)
|
28
|
+
puts message
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Changes the current working directory.
|
33
|
+
#
|
34
|
+
# @param [String] path
|
35
|
+
# The path of the new current working directory to use.
|
36
|
+
#
|
37
|
+
# @yield []
|
38
|
+
# If a block is given, then the directory will be changed back after
|
39
|
+
# the block has returned.
|
40
|
+
#
|
41
|
+
def cd(path,&block)
|
42
|
+
if block
|
43
|
+
cwd = Dir.pwd
|
44
|
+
|
45
|
+
Dir.chdir(path)
|
46
|
+
block.call()
|
47
|
+
Dir.chdir(cwd)
|
48
|
+
else
|
49
|
+
Dir.chdir(path)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rprogram/task'
|
2
|
+
|
3
|
+
module DeploYML
|
4
|
+
module Options
|
5
|
+
class Mongrel < RProgram::Task
|
6
|
+
|
7
|
+
DEFAULTS = {
|
8
|
+
:environment => :production,
|
9
|
+
:address => '127.0.0.1',
|
10
|
+
:num_servers => 2
|
11
|
+
}
|
12
|
+
|
13
|
+
long_option :flag => '--environment'
|
14
|
+
long_option :flag => '--port'
|
15
|
+
long_option :flag => '--address'
|
16
|
+
long_option :flag => '--log'
|
17
|
+
long_option :flag => '--pid'
|
18
|
+
long_option :flag => '--chdir'
|
19
|
+
long_option :flag => '--timeout'
|
20
|
+
long_option :flag => '--throttle'
|
21
|
+
long_option :flag => '--mime'
|
22
|
+
long_option :flag => '--root'
|
23
|
+
long_option :flag => '--num-procs'
|
24
|
+
long_option :flag => '--debug'
|
25
|
+
long_option :flag => '--script'
|
26
|
+
long_option :flag => '--num-servers'
|
27
|
+
long_option :flag => '--config'
|
28
|
+
long_option :flag => '--user'
|
29
|
+
long_option :flag => '--group'
|
30
|
+
long_option :flag => '--prefix'
|
31
|
+
long_option :flag => '--help'
|
32
|
+
long_option :flag => '--version'
|
33
|
+
|
34
|
+
#
|
35
|
+
# Initialize the Mongrel options.
|
36
|
+
#
|
37
|
+
# @param [Hash] options
|
38
|
+
# The given options.
|
39
|
+
#
|
40
|
+
def initialize(options={})
|
41
|
+
super(DEFAULTS.merge(options))
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rprogram/task'
|
2
|
+
|
3
|
+
module DeploYML
|
4
|
+
module Options
|
5
|
+
class Thin < RProgram::Task
|
6
|
+
|
7
|
+
# Default options for Thin
|
8
|
+
DEFAULTS = {
|
9
|
+
:environment => :production,
|
10
|
+
:address => '127.0.0.1',
|
11
|
+
:servers => 2
|
12
|
+
}
|
13
|
+
|
14
|
+
# Server options:
|
15
|
+
long_option :flag => '--address'
|
16
|
+
long_option :flag => '--port'
|
17
|
+
long_option :flag => '--socket'
|
18
|
+
long_option :flag => '--swiftiply'
|
19
|
+
long_option :flag => '--adapter'
|
20
|
+
long_option :flag => '--rackup'
|
21
|
+
long_option :flag => '--chdir'
|
22
|
+
long_option :flag => '--stats'
|
23
|
+
|
24
|
+
# Adapter options:
|
25
|
+
long_option :flag => '--environment'
|
26
|
+
long_option :flag => '--prefix'
|
27
|
+
|
28
|
+
# Daemon options:
|
29
|
+
long_option :flag => '--daemonize'
|
30
|
+
long_option :flag => '--log'
|
31
|
+
long_option :flag => '--pid'
|
32
|
+
long_option :flag => '--user'
|
33
|
+
long_option :flag => '--group'
|
34
|
+
long_option :flag => '--tag'
|
35
|
+
|
36
|
+
# Cluster options:
|
37
|
+
long_option :flag => '--servers'
|
38
|
+
long_option :flag => '--only'
|
39
|
+
long_option :flag => '--config'
|
40
|
+
long_option :flag => '--all'
|
41
|
+
long_option :flag => '--onebyone', :name => :one_by_one
|
42
|
+
long_option :flag => '--wait'
|
43
|
+
|
44
|
+
# Tuning options:
|
45
|
+
long_option :flag => '--backend'
|
46
|
+
long_option :flag => '--timeout'
|
47
|
+
long_option :flag => '--force'
|
48
|
+
long_option :flag => '--max-conns', :name => :max_connections
|
49
|
+
long_option :flag => '--max-persistent-conns', :name => :max_persistant_connections
|
50
|
+
long_option :flag => '--threaded'
|
51
|
+
long_option :flag => '--no-epoll'
|
52
|
+
|
53
|
+
# Common options:
|
54
|
+
long_option :flag => '--require'
|
55
|
+
long_option :flag => '--debug'
|
56
|
+
long_option :flag => '--trace'
|
57
|
+
long_option :flag => '--help'
|
58
|
+
long_option :flag => '--version'
|
59
|
+
|
60
|
+
#
|
61
|
+
# Initialize the Thin options.
|
62
|
+
#
|
63
|
+
# @param [Hash] options
|
64
|
+
# The given options.
|
65
|
+
#
|
66
|
+
def initialize(options={})
|
67
|
+
super(DEFAULTS.merge(options))
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'deployml/options/thin'
|