mina 0.1.1 → 0.1.2.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.md +16 -0
- data/README.md +13 -535
- data/Rakefile +0 -24
- data/lib/mina/default.rb +1 -1
- data/lib/mina/deploy_helpers.rb +11 -5
- data/lib/mina/helpers.rb +124 -23
- data/lib/mina/tools.rb +1 -0
- data/lib/mina/version.rb +1 -1
- metadata +27 -12
data/HISTORY.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
v0.1.2.pre1 - Jun 12, 2012
|
2
|
+
--------------------------
|
3
|
+
|
4
|
+
### Fixed:
|
5
|
+
* Fixed JRuby support.
|
6
|
+
* Respect .bashrc. (#5)
|
7
|
+
|
8
|
+
### Changed:
|
9
|
+
* Implement `ssh("..", return: true)`.
|
10
|
+
* Rename simulate_mode to simulate_mode?. Same with verbose_mode?.
|
11
|
+
* Show the SSH command in the simulation output.
|
12
|
+
|
13
|
+
### Misc:
|
14
|
+
* Prepare for Tomdoc.
|
15
|
+
* Stop invoking bash needlessly to prettify things.
|
16
|
+
|
1
17
|
v0.1.1 - Jun 07, 2012
|
2
18
|
---------------------
|
3
19
|
|
data/README.md
CHANGED
@@ -11,539 +11,17 @@ is ran separately on their own SSH sessions. Mina only creates *one* SSH
|
|
11
11
|
session per deploy, minimizing the SSH connection overhead.
|
12
12
|
|
13
13
|
$ gem install mina
|
14
|
+
$ mina
|
14
15
|
|
15
|
-
|
16
|
-
--------
|
17
|
-
|
18
|
-
* __Really fast.__ Mina only makes one SSH connection per deploy. It
|
19
|
-
builds a Bash script and executes it remotely, reducing the overhead of
|
20
|
-
creating SSH connections to do processing locally (like Vlad or Capistrano
|
21
|
-
does).
|
22
|
-
|
23
|
-
* __Safe deploys.__ New releases are built on a temp folder. If the deploy
|
24
|
-
script fails at any point, the build is deleted and it'd be as if nothing
|
25
|
-
happened.
|
26
|
-
|
27
|
-
* __Locks.__ Deploy scripts rely on a lockfile ensuring only one deploy can
|
28
|
-
happen at a time.
|
29
|
-
|
30
|
-
* __Works with anything.__ While Mina is built with Rails projects it
|
31
|
-
mind, it can be used on just about any type of project deployable via SSH,
|
32
|
-
Ruby or not.
|
33
|
-
|
34
|
-
* __Built with Rake.__ Setting up tasks will be very familiar! No YAML files
|
35
|
-
here. Everything is written in Ruby, giving you the power to be as flexible in
|
36
|
-
your configuration as needed.
|
37
|
-
|
38
|
-
Setting up a project
|
39
|
-
--------------------
|
40
|
-
|
41
|
-
Let's deploy a project using Mina.
|
42
|
-
|
43
|
-
### Step 1: Create a config/deploy.rb
|
44
|
-
|
45
|
-
In your project, type `mina init` to create a sample of this file.
|
46
|
-
|
47
|
-
This is just a Rake file with tasks!
|
48
|
-
|
49
|
-
$ mina init
|
50
|
-
Created config/deploy.rb.
|
51
|
-
|
52
|
-
See [About deploy.rb](#about_deployrb) for more info on what *deploy.rb* is.
|
53
|
-
|
54
|
-
### Step 2: Set up your server
|
55
|
-
|
56
|
-
Make a directory in your server called `/var/www/flipstack.com` (in *deploy_to*)
|
57
|
-
change it's ownership to the correct user.
|
58
|
-
|
59
|
-
# SSH into your server, then:
|
60
|
-
$ mkdir /var/www/flipstack.com
|
61
|
-
$ chown -R username /var/www/flipstack.com
|
62
|
-
|
63
|
-
# Make sure 'username' is the same as what's on deploy.rb
|
64
|
-
|
65
|
-
### Step 3: Run 'mina setup'
|
66
|
-
|
67
|
-
Now do `mina setup` to set up the [folder structure](#directory_structure) in this
|
68
|
-
path. This will connect to your server via SSH and create the right directories.
|
69
|
-
|
70
|
-
$ mina setup
|
71
|
-
-----> Creating folders... done.
|
72
|
-
|
73
|
-
See [directory structure](#directory_structure) for more info.
|
74
|
-
|
75
|
-
### Step 4: Deploy!
|
76
|
-
|
77
|
-
Use `mina deploy` to run the `deploy` task defined in *config/deploy.rb*.
|
78
|
-
|
79
|
-
$ mina deploy
|
80
|
-
-----> Deploying to 2012-06-12-040248
|
81
|
-
...
|
82
|
-
Lots of things happening...
|
83
|
-
...
|
84
|
-
-----> Done.
|
85
|
-
|
86
|
-
Command line options
|
87
|
-
--------------------
|
88
|
-
|
89
|
-
* `--verbose` - This will show commands being done on the server. Off by
|
90
|
-
default.
|
91
|
-
|
92
|
-
* `--simulate` - This will not invoke any SSH connections; instead, it will
|
93
|
-
simply output the script it builds.
|
94
|
-
|
95
|
-
About deploy.rb
|
96
|
-
---------------
|
97
|
-
|
98
|
-
The file `deploy.rb` is simply a Rakefile invoked by Rake. In fact, `mina` is
|
99
|
-
mostly an alias that invokes Rake to load `deploy.rb`.
|
100
|
-
|
101
|
-
As it's all Rake, you can define tasks that you can invoke using `mina`. In this
|
102
|
-
example, it provides the `mina restart` command.
|
103
|
-
|
104
|
-
``` ruby
|
105
|
-
# Sample config/deploy.rb
|
106
|
-
set :domain, 'your.server.com'
|
107
|
-
|
108
|
-
task :restart do
|
109
|
-
queue 'sudo service restart apache'
|
110
|
-
end
|
111
|
-
```
|
112
|
-
|
113
|
-
The magic of Mina is in the new commands it gives you.
|
114
|
-
|
115
|
-
The `queue` command queues up Bash commands to be ran on the remote server.
|
116
|
-
If you invoke `mina restart`, it will invoke the task above and run the queued
|
117
|
-
commands on the remote server `your.server.com` via SSH.
|
118
|
-
|
119
|
-
See [the command queue](#the_command_queue) for more information on the *queue*
|
120
|
-
command.
|
121
|
-
|
122
|
-
The command queue
|
123
|
-
-----------------
|
124
|
-
|
125
|
-
At the heart of it, Mina is merely sugar on top of Rake to queue commands
|
126
|
-
and execute them remotely at the end.
|
127
|
-
|
128
|
-
Take a look at this minimal *deploy.rb* configuration:
|
129
|
-
|
130
|
-
``` ruby
|
131
|
-
set :user, 'john'
|
132
|
-
set :domain, 'flipstack.com'
|
133
|
-
|
134
|
-
task :logs do
|
135
|
-
queue 'echo "Contents of the log file are as follows:"'
|
136
|
-
queue "tail -f /var/log/apache.log"
|
137
|
-
end
|
138
|
-
```
|
139
|
-
|
140
|
-
Once you type `mina logs` in your terminal, it invokes the *queue*d commands
|
141
|
-
remotely on the server using the command `ssh john@flipstack.com`.
|
142
|
-
|
143
|
-
```
|
144
|
-
# Run it in simulation mode so we see the command it will invoke:
|
145
|
-
$ mina logs --simulate
|
146
|
-
(
|
147
|
-
echo "Contents of the log file are as follows:"
|
148
|
-
tail -f /var/log/apache.log
|
149
|
-
) | ssh john@flipstack.com -- bash -
|
150
|
-
```
|
151
|
-
|
152
|
-
Subtasks
|
153
|
-
--------
|
154
|
-
|
155
|
-
Mina provides the helper `invoke` to invoke other tasks from a
|
156
|
-
task.
|
157
|
-
|
158
|
-
```ruby
|
159
|
-
task :down do
|
160
|
-
invoke :maintenance_on
|
161
|
-
invoke :restart
|
162
|
-
end
|
163
|
-
|
164
|
-
task :maintenance_on
|
165
|
-
queue 'touch maintenance.txt'
|
166
|
-
end
|
167
|
-
|
168
|
-
task :restart
|
169
|
-
queue 'sudo service restart apache'
|
170
|
-
end
|
171
|
-
```
|
172
|
-
|
173
|
-
In this example above, if you type `mina down`, it simply invokes the other
|
174
|
-
subtasks which queues up their commands. The commands will be ran after
|
175
|
-
everything.
|
176
|
-
|
177
|
-
Deploying
|
178
|
-
---------
|
179
|
-
|
180
|
-
Mina provides the `deploy` command which *queue*s up a deploy script for
|
181
|
-
you.
|
182
|
-
|
183
|
-
``` ruby
|
184
|
-
set :domain, 'flipstack.com'
|
185
|
-
set :user, 'flipstack'
|
186
|
-
set :deploy_to, '/var/www/flipstack.com'
|
187
|
-
set :repository, 'http://github.com/flipstack/flipstack.git'
|
188
|
-
|
189
|
-
task :deploy do
|
190
|
-
deploy do
|
191
|
-
# Put things that prepare the empty release folder here.
|
192
|
-
# Commands queued here will be ran on a new release directory.
|
193
|
-
invoke :'git:clone'
|
194
|
-
invoke :'bundle:install'
|
195
|
-
|
196
|
-
# These are instructions to start the app after it's been prepared.
|
197
|
-
to :launch do
|
198
|
-
queue 'touch tmp/restart.txt'
|
199
|
-
end
|
200
|
-
|
201
|
-
# This optional block defines how a broken release should be cleaned up.
|
202
|
-
to :clean do
|
203
|
-
queue 'log "failed deployment"'
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
```
|
208
|
-
|
209
|
-
It works by capturing the *queue*d commands inside the block, wrapping them
|
210
|
-
in a deploy script, then *queue*ing them back in.
|
211
|
-
|
212
|
-
How deploying works
|
213
|
-
-------------------
|
214
|
-
|
215
|
-
Here is an example of a deploy! (Note that some commands have been simplified
|
216
|
-
to illustrate the point better.)
|
217
|
-
|
218
|
-
### Step 1: Build it
|
219
|
-
|
220
|
-
The deploy process builds a new temp folder with instructions you provide.
|
221
|
-
In this example, it will do `git:clone` and `bundle:install`.
|
222
|
-
|
223
|
-
```
|
224
|
-
$ mina deploy --verbose
|
225
|
-
-----> Creating the build path
|
226
|
-
$ mkdir tmp/build-128293482394
|
227
|
-
-----> Cloning the Git repository
|
228
|
-
$ git clone https://github.com/flipstack/flipstack.git . -n --recursive
|
229
|
-
Cloning... done.
|
230
|
-
-----> Installing gem dependencies using Bundler
|
231
|
-
$ bundle install --without development:test
|
232
|
-
Using i18n (0.6.0)
|
233
|
-
Using multi_json (1.0.4)
|
234
|
-
...
|
235
|
-
Your bundle is complete! It was installed to ./vendor/bundle
|
236
|
-
```
|
237
|
-
|
238
|
-
### Step 2: Move it to releases
|
239
|
-
|
240
|
-
Once the project has been built, it will be moved to `releases/`. A symlink
|
241
|
-
called `current/` will be created to point to the active release.
|
242
|
-
|
243
|
-
```
|
244
|
-
-----> Moving to releases/4
|
245
|
-
$ mv "./tmp/build-128293482394" "releases/4"
|
246
|
-
-----> Symlinking to current
|
247
|
-
$ ln -nfs releases/4 current
|
248
|
-
```
|
249
|
-
|
250
|
-
### Step 3: Launch it
|
251
|
-
|
252
|
-
Invoke the commands queued up in the `to :launch` block. These often
|
253
|
-
commands to restart the webserver process. Once this in complete, you're done!
|
254
|
-
|
255
|
-
```
|
256
|
-
-----> Launching
|
257
|
-
$ cd releases/4
|
258
|
-
$ sudo service nginx restart
|
259
|
-
-----> Done. Deployed v4
|
260
|
-
```
|
261
|
-
|
262
|
-
### What about failure?
|
263
|
-
|
264
|
-
If it fails at any point, the release path will be deleted. If any commands are
|
265
|
-
queued using the `to :clean` block, they will be ran. It will be as if nothing
|
266
|
-
happened.
|
267
|
-
|
268
|
-
```
|
269
|
-
# Lets see what happens if a build fails:
|
270
|
-
-----> Launching
|
271
|
-
$ cd releases/4
|
272
|
-
$ sudo service nginx restart
|
273
|
-
Starting nginx... error: can't start service
|
274
|
-
-----> ERROR: Deploy failed.
|
275
|
-
-----> Cleaning up build
|
276
|
-
$ rm -rf tmp/build-128293482394
|
277
|
-
-----> Unlinking current
|
278
|
-
$ ln -nfs releases/3 current
|
279
|
-
OK
|
280
|
-
```
|
281
|
-
|
282
|
-
Directory structure
|
283
|
-
-------------------
|
284
|
-
|
285
|
-
The deploy procedures make the assumption that you have a folder like so:
|
286
|
-
|
287
|
-
/var/www/flipstack.com/ # The deploy_to path
|
288
|
-
|- releases/ # Holds releases, one subdir per release
|
289
|
-
| |- 2012-06-12-838948
|
290
|
-
| |- 2012-06-23-034828
|
291
|
-
| '- ...
|
292
|
-
|- shared/ # Holds files shared between releases
|
293
|
-
| |- logs/ # Log files are usually stored here
|
294
|
-
| `- ...
|
295
|
-
'- current/ # A symlink to the current release in releases/
|
296
|
-
|
297
|
-
It also assumes that the `deploy_to` path is fully writeable/readable for the
|
298
|
-
user we're going to SSH with.
|
299
|
-
|
300
|
-
Configuring settings
|
301
|
-
--------------------
|
302
|
-
|
303
|
-
Settings are managed using the `set` and `settings` methods. This convention is
|
304
|
-
inspired by Sinatra and Vlad.
|
305
|
-
|
306
|
-
``` ruby
|
307
|
-
set :version, "v2.0.5"
|
308
|
-
|
309
|
-
settings.version #=> "v2.0.5"
|
310
|
-
settings.version? #=> true
|
311
|
-
```
|
312
|
-
|
313
|
-
You can also retrieve settings without the `settings.` prefix.
|
314
|
-
|
315
|
-
``` ruby
|
316
|
-
set :version, "v2.0.5"
|
317
|
-
|
318
|
-
version #=> "v2.0.5"
|
319
|
-
version? #=> true
|
320
|
-
```
|
321
|
-
|
322
|
-
### Dynamic values
|
323
|
-
|
324
|
-
You can also give settings using a lambda. When the setting is retrieved, it
|
325
|
-
will be evaluated.
|
326
|
-
|
327
|
-
``` ruby
|
328
|
-
set :tag, lambda { "release/#{version}" }
|
329
|
-
set :version, "v2.0.5"
|
330
|
-
|
331
|
-
tag #=> "release/v2.0.5"
|
332
|
-
```
|
333
|
-
|
334
|
-
### Inside and outside tasks
|
335
|
-
|
336
|
-
All of these are accessible inside and outside tasks.
|
337
|
-
|
338
|
-
``` ruby
|
339
|
-
set :admin_email, "johnsmith@gmail.com"
|
340
|
-
|
341
|
-
task :email do
|
342
|
-
set :message, "Deploy is done"
|
343
|
-
|
344
|
-
system "echo #{message} | mail #{admin_email}"
|
345
|
-
end
|
346
|
-
```
|
347
|
-
|
348
|
-
### Validations
|
349
|
-
|
350
|
-
If you would like an error to be thrown if a setting is not present, add a bang
|
351
|
-
at the end.
|
352
|
-
|
353
|
-
``` ruby
|
354
|
-
task :restart do
|
355
|
-
queue "#{settings.nginx_path!}/sbin/nginx restart"
|
356
|
-
end
|
357
|
-
|
358
|
-
# $ mina restart
|
359
|
-
# Error: You must set the :nginx_path setting
|
360
|
-
```
|
361
|
-
|
362
|
-
Defaults
|
363
|
-
--------
|
364
|
-
|
365
|
-
There are a few deploy-related tasks and settings that are on by default.
|
366
|
-
|
367
|
-
### Base settings
|
368
|
-
|
369
|
-
* `verbose_mode` - True if the `--verbose` flag is on, false otherwise. Used to
|
370
|
-
signal if commands are to be shown.
|
371
|
-
|
372
|
-
* `simulate_mode` - True if `--simulate` flag is on, false otherwise. Used to
|
373
|
-
signal if no SSH connections are to be made, and the scripts will just be
|
374
|
-
printed locally.
|
375
|
-
|
376
|
-
* `term_mode` - If set to `:pretty`, prettifies the output with indentations.
|
377
|
-
(Default with deploys.)
|
378
|
-
|
379
|
-
### SSH settings
|
380
|
-
|
381
|
-
* `domain` - Hostname to SSH to. *Required.*
|
382
|
-
|
383
|
-
* `user` - Username to connect to SSH with. Optional.
|
384
|
-
|
385
|
-
* `identity_file` - Local path to the SSH key to use. Optional.
|
386
|
-
|
387
|
-
``` ruby
|
388
|
-
# Example:
|
389
|
-
set :domain, 'flipstack.me'
|
390
|
-
set :user, 'flipstack_www'
|
391
|
-
set :identity_file, 'flipstack.pem'
|
392
|
-
```
|
393
|
-
|
394
|
-
### Deploy settings
|
395
|
-
|
396
|
-
* `deploy_to` - Path to deploy to. *Required.*
|
397
|
-
|
398
|
-
* `releases_path` - The path to where releases are kept. Defaults to
|
399
|
-
`releases`.
|
400
|
-
|
401
|
-
* `shared_path` - Where shared files are kept. Defaults to
|
402
|
-
`shared`.
|
403
|
-
|
404
|
-
* `current_path` - The path to the symlink to the current release. Defaults to
|
405
|
-
`current`.
|
406
|
-
|
407
|
-
* `lock_file` - The deploy lock file. A deploy does not start if this file is
|
408
|
-
found. Defaults to `deploy.lock`.
|
409
|
-
|
410
|
-
|
411
|
-
``` ruby
|
412
|
-
# Example:
|
413
|
-
set :deploy_to, '/var/www/flipstack.me'
|
414
|
-
set :releases_path, 'releases'
|
415
|
-
set :shared_path, 'shared'
|
416
|
-
set :current_path, 'current'
|
417
|
-
set :lock_file, 'deploy.lock'
|
418
|
-
|
419
|
-
# This means the following paths will be
|
420
|
-
# created on `mina setup`:
|
421
|
-
# /var/www/flipstack.me/
|
422
|
-
# /var/www/flipstack.me/releases/
|
423
|
-
# /var/www/flipstack.me/shared/
|
424
|
-
```
|
425
|
-
|
426
|
-
### Task - setup
|
427
|
-
|
428
|
-
Prepares the `deploy_to` directory for deployments. Sets up subdirectories and
|
429
|
-
sets permissions in the path.
|
430
|
-
|
431
|
-
$ mina setup
|
432
|
-
-----> Setting up
|
433
|
-
$ mkdir -p /var/www/kickstack.me
|
434
|
-
$ chmod g+r,a+rwx /var/www/kickstack.me
|
435
|
-
$ mkdir -p /var/www/kickstack.me/releases
|
436
|
-
$ mkdir -p /var/www/kickstack.me/shared
|
437
|
-
...
|
438
|
-
|
439
|
-
### Task - deploy:force_unlock
|
440
|
-
|
441
|
-
Removes the deploy lock file. If a deploy is terminated midway, it may leave a
|
442
|
-
lock file to signal that deploys shouldn't be made. This forces the removal of
|
443
|
-
that lock file.
|
444
|
-
|
445
|
-
$ mina deploy
|
446
|
-
-----> ERROR: another deployment is ongoing.
|
447
|
-
Delete the lock file to continue.
|
448
|
-
|
449
|
-
$ mina deploy:force_unlock
|
450
|
-
-----> Unlocking
|
451
|
-
$ rm /var/www/kickstack.me/deploy.lock
|
452
|
-
|
453
|
-
$ mina deploy
|
454
|
-
# The deploy should proceed now
|
455
|
-
|
456
|
-
Addons: Git
|
457
|
-
-----------
|
458
|
-
|
459
|
-
To deploy projects using git, add this to your `deploy.rb`:
|
460
|
-
|
461
|
-
``` ruby
|
462
|
-
require 'mina/git'
|
463
|
-
|
464
|
-
set :repository, 'https://github.com/you/your-app.git'
|
465
|
-
```
|
466
|
-
|
467
|
-
### Settings
|
468
|
-
|
469
|
-
This introduces the following settings:
|
470
|
-
|
471
|
-
* `repository` - The repository path to clone from. *Required.*
|
472
|
-
|
473
|
-
* `revision` - The SHA1 of the commit to be deployed. Defaults to whatever is
|
474
|
-
the current HEAD in your local copy.
|
475
|
-
|
476
|
-
### Task - git:clone
|
477
|
-
|
478
|
-
Clones from the repo into the current folder.
|
479
|
-
|
480
|
-
Addons: Bundler
|
481
|
-
---------------
|
482
|
-
|
483
|
-
To manage Bundler installations, add this to your `deploy.rb`:
|
484
|
-
|
485
|
-
``` ruby
|
486
|
-
require 'mina/bundler'
|
487
|
-
```
|
488
|
-
|
489
|
-
### Settings
|
490
|
-
|
491
|
-
This introduces the following settings:
|
492
|
-
|
493
|
-
* `bundle_path` - The path where bundles are going to be installed. Defaults to
|
494
|
-
`./vendor/bundler`.
|
495
|
-
|
496
|
-
* `bundle_options` - Options that will be passed onto `bundle install`.
|
497
|
-
Defaults to
|
498
|
-
`--without development:test --path "#{bundle_path}" --binstubs bin/
|
499
|
-
--deployment"`.
|
500
|
-
|
501
|
-
### Task - bundle:install
|
502
|
-
|
503
|
-
Invokes `bundle:install` on the current directory, creating the bundle
|
504
|
-
path (specified in `bundle_path`), and invoking `bundle install`.
|
505
|
-
|
506
|
-
The `bundle_path` is only created if `bundle_path` is set (which is on
|
507
|
-
by default).
|
508
|
-
|
509
|
-
Addons: Rails
|
16
|
+
Documentation
|
510
17
|
-------------
|
511
18
|
|
512
|
-
|
513
|
-
|
514
|
-
``` ruby
|
515
|
-
require 'mina/rails'
|
516
|
-
```
|
517
|
-
|
518
|
-
### Settings
|
519
|
-
|
520
|
-
This introduces the following settings. All of them are optional.
|
521
|
-
|
522
|
-
* `bundle_prefix` - Prefix to run commands via Bundler. Defaults to
|
523
|
-
`RAILS_ENV="#{rails_env}" bundle exec`.
|
524
|
-
|
525
|
-
* `rake` - The `rake` command. Defaults to `#{bundle_prefix} rake`.
|
526
|
-
|
527
|
-
* `rails` - The `rails` command. Defaults to `#{bundle_prefix} rails`.
|
528
|
-
|
529
|
-
* `rails_env` - The environment to run rake commands in. Defaults to
|
530
|
-
`production`.
|
19
|
+
Please consult the [project documentation](http://nadarei.co/mina) for full
|
20
|
+
details.
|
531
21
|
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
### Task - rails:assets_precompile
|
537
|
-
|
538
|
-
Precompiles assets. This invokes `rake assets:precomplie`.
|
539
|
-
|
540
|
-
It also checks the current version to see if it has assets compiled. If it does,
|
541
|
-
it reuses them, skipping the compilation step. To stop this behavior, invoke
|
542
|
-
the `mina` command with `force_assets=1`.
|
543
|
-
|
544
|
-
### Task - rails:assets_precompile:force
|
545
|
-
|
546
|
-
Precompiles assets. This always skips the "reuse old assets if possible" step.
|
22
|
+
Problems or suggestions? File issues at the [issue tracker][issues]
|
23
|
+
(github.com). You may also look at the [Trello board][trello] (trello.com) we
|
24
|
+
use for development.
|
547
25
|
|
548
26
|
Development & testing
|
549
27
|
---------------------
|
@@ -574,20 +52,20 @@ Try out the test environment:
|
|
574
52
|
|
575
53
|
# To release the gem:
|
576
54
|
# Install the Git changelog helper: https://gist.github.com/2880525
|
55
|
+
# Then:
|
56
|
+
|
577
57
|
$ vim lib/mina/version.rb
|
578
58
|
$ git clog -w
|
579
59
|
$ vim HISTORY.md
|
60
|
+
$ git commit -m "Release v0.8.4."
|
580
61
|
$ rake release
|
581
62
|
|
63
|
+
# Please don't forget to tag the release in github.com/nadarei/mina-docs
|
64
|
+
too!
|
65
|
+
|
582
66
|
$ rake build # Builds the gem file
|
583
67
|
$ rake install # Installs the gem locally
|
584
68
|
|
585
|
-
Issues
|
586
|
-
------
|
587
|
-
|
588
|
-
File issues at the [issue tracker][issues] (github.com). You may also look at
|
589
|
-
the [Trello board][trello] (trello.com) we use for development.
|
590
|
-
|
591
69
|
Acknowledgements
|
592
70
|
----------------
|
593
71
|
|
data/Rakefile
CHANGED
@@ -1,30 +1,6 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
require 'bundler/gem_tasks'
|
3
3
|
|
4
|
-
# Do these:
|
5
|
-
#
|
6
|
-
# *do `gem install reacco`
|
7
|
-
# * install http://github.com/rstacruz/git-update-ghpages
|
8
|
-
|
9
|
-
ENV['github'] ||= 'nadarei/mina'
|
10
|
-
|
11
|
-
namespace :doc do
|
12
|
-
|
13
|
-
task :build do
|
14
|
-
cmd = "reacco --literate --toc --github #{ENV['github']}"
|
15
|
-
cmd << " --analytics=#{ENV['analytics_id']}" if ENV['analytics_id']
|
16
|
-
|
17
|
-
system cmd
|
18
|
-
raise "Failed" unless $?.to_i == 0
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
desc "Updates online documentation"
|
23
|
-
task :deploy => :build do
|
24
|
-
system "git update-ghpages #{ENV['github']} -i doc"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
4
|
task :spec do
|
29
5
|
system "rm Gemfile.lock; sh -c 'rake=0.8 bundle exec rspec'"
|
30
6
|
system "rm Gemfile.lock; sh -c 'rake=0.9 bundle exec rspec'"
|
data/lib/mina/default.rb
CHANGED
data/lib/mina/deploy_helpers.rb
CHANGED
@@ -1,18 +1,24 @@
|
|
1
1
|
module Mina
|
2
|
+
# Helpers for deployment
|
2
3
|
module DeployHelpers
|
3
|
-
#
|
4
|
+
# Wraps the things inside it in a deploy script and queues it.
|
4
5
|
# This generates a script using deploy_script and queues it.
|
6
|
+
#
|
7
|
+
# Returns nothing.
|
8
|
+
#
|
5
9
|
def deploy(&blk)
|
6
10
|
queue deploy_script(&blk)
|
7
11
|
end
|
8
12
|
|
9
13
|
# Wraps the things inside it in a deploy script.
|
10
14
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
15
|
+
# script = deploy_script do
|
16
|
+
# invoke :'git:checkout'
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# queue script
|
14
20
|
#
|
15
|
-
#
|
21
|
+
# Returns the deploy script as a string, ready for `queue`ing.
|
16
22
|
#
|
17
23
|
def deploy_script(&blk)
|
18
24
|
set_default :term_mode, :pretty
|
data/lib/mina/helpers.rb
CHANGED
@@ -1,11 +1,30 @@
|
|
1
1
|
module Mina
|
2
|
+
# Helpers
|
2
3
|
module Helpers
|
4
|
+
|
3
5
|
# Invokes another Rake task.
|
6
|
+
#
|
7
|
+
# Invokes the task given in `task`. Returns nothing.
|
8
|
+
#
|
9
|
+
# invoke :'git:clone'
|
10
|
+
# invoke :restart
|
11
|
+
#
|
4
12
|
def invoke(task)
|
5
13
|
Rake.application.invoke_task task
|
6
14
|
end
|
7
15
|
|
8
|
-
# Evaluates an ERB block and returns a string.
|
16
|
+
# Evaluates an ERB block in the current scope and returns a string.
|
17
|
+
#
|
18
|
+
# a = 1
|
19
|
+
# b = 2
|
20
|
+
#
|
21
|
+
# # Assuming foo.erb is <%= a %> and <%= b %>
|
22
|
+
# puts erb('foo.erb')
|
23
|
+
#
|
24
|
+
# #=> "1 and 2"
|
25
|
+
#
|
26
|
+
# Returns the output string of the ERB template.
|
27
|
+
#
|
9
28
|
def erb(file, b=binding)
|
10
29
|
require 'erb'
|
11
30
|
erb = ERB.new(File.read(file))
|
@@ -20,15 +39,24 @@ module Mina
|
|
20
39
|
# queue "sudo restart"
|
21
40
|
# run!
|
22
41
|
#
|
42
|
+
# Returns nothing.
|
43
|
+
#
|
23
44
|
def run!
|
24
45
|
ssh commands(:default)
|
25
46
|
end
|
26
47
|
|
27
48
|
# Executes a command via SSH.
|
28
49
|
#
|
29
|
-
#
|
50
|
+
# Returns nothing usually, but if `{ return: true }` is given, returns the
|
51
|
+
# STDOUT output of the SSH session.
|
52
|
+
#
|
53
|
+
# options - Hash of options.
|
54
|
+
# :pretty - Prettify the output.
|
55
|
+
# :return - If set to true, returns the output.
|
56
|
+
#
|
57
|
+
# Example
|
30
58
|
#
|
31
|
-
#
|
59
|
+
# ssh("ls", return: true)
|
32
60
|
#
|
33
61
|
def ssh(cmd, options={})
|
34
62
|
cmd = cmd.join("\n") if cmd.is_a?(Array)
|
@@ -36,16 +64,30 @@ module Mina
|
|
36
64
|
require 'shellwords'
|
37
65
|
|
38
66
|
result = 0
|
39
|
-
|
67
|
+
script = Shellwords.escape("true;"+cmd)
|
68
|
+
|
69
|
+
if options[:return] == true
|
70
|
+
result = `#{ssh_command} -- bash -c #{script}`
|
71
|
+
|
72
|
+
elsif simulate_mode?
|
73
|
+
str = "Executing the following via '#{ssh_command}':"
|
74
|
+
puts "#!/usr/bin/env bash"
|
75
|
+
puts "# #{str}"
|
76
|
+
puts "# " + ("-" * str.size)
|
77
|
+
puts "#"
|
78
|
+
|
40
79
|
puts cmd
|
80
|
+
|
41
81
|
elsif settings.term_mode == :pretty
|
42
|
-
code = "#{ssh_command} -- bash -c
|
82
|
+
code = "#{ssh_command} -- bash #{bash_options} -c #{script}"
|
43
83
|
result = pretty_system("#{code} 2>&1")
|
84
|
+
|
44
85
|
elsif settings.term_mode == :exec
|
45
|
-
code = "#{ssh_command} -t -- bash -c
|
86
|
+
code = "#{ssh_command} -t -- bash #{bash_options} -c #{script}"
|
46
87
|
exec code
|
88
|
+
|
47
89
|
else
|
48
|
-
code = "#{ssh_command} -t -- bash -c
|
90
|
+
code = "#{ssh_command} -t -- bash #{bash_options} -c #{script}"
|
49
91
|
system code
|
50
92
|
result = $?
|
51
93
|
end
|
@@ -63,6 +105,7 @@ module Mina
|
|
63
105
|
#
|
64
106
|
# set :domain, 'foo.com'
|
65
107
|
# set :user, 'diggity'
|
108
|
+
#
|
66
109
|
# puts ssh_command
|
67
110
|
# #=> 'ssh diggity@foo.com'
|
68
111
|
#
|
@@ -70,15 +113,21 @@ module Mina
|
|
70
113
|
args = domain!
|
71
114
|
args = "#{user}@#{args}" if user?
|
72
115
|
args << " -i #{identity_file}" if identity_file?
|
116
|
+
args << " -t"
|
73
117
|
"ssh #{args}"
|
74
118
|
end
|
75
119
|
|
76
|
-
# Works like 'system', but indents and puts color.
|
120
|
+
# Internal: Works like 'system', but indents and puts color.
|
121
|
+
#
|
77
122
|
# Returns the exit code in integer form.
|
123
|
+
#
|
78
124
|
def pretty_system(code)
|
125
|
+
require 'shellwords'
|
126
|
+
cmds = Shellwords.shellsplit(code)
|
127
|
+
cmds << "2>&1"
|
128
|
+
|
79
129
|
status =
|
80
|
-
Tools.popen4(
|
81
|
-
i.write "( #{code} ) 2>&1\n"
|
130
|
+
Tools.popen4(*cmds) do |pid, i, o, e|
|
82
131
|
i.close
|
83
132
|
|
84
133
|
last = nil
|
@@ -121,9 +170,12 @@ module Mina
|
|
121
170
|
end
|
122
171
|
|
123
172
|
# Queues code to be ran.
|
173
|
+
#
|
124
174
|
# This queues code to be ran to the current code bucket (defaults to `:default`).
|
125
175
|
# To get the things that have been queued, use commands[:default]
|
126
176
|
#
|
177
|
+
# Returns nothing.
|
178
|
+
#
|
127
179
|
# queue "sudo restart"
|
128
180
|
# queue "true"
|
129
181
|
#
|
@@ -134,6 +186,18 @@ module Mina
|
|
134
186
|
commands(@to) << unindent(code)
|
135
187
|
end
|
136
188
|
|
189
|
+
# Internal: Normalizes indentation on a given string.
|
190
|
+
#
|
191
|
+
# Returns the normalized string without extraneous indentation.
|
192
|
+
#
|
193
|
+
# puts unindent %{
|
194
|
+
# Hello
|
195
|
+
# There
|
196
|
+
# }
|
197
|
+
# # Output:
|
198
|
+
# # Hello
|
199
|
+
# # There
|
200
|
+
#
|
137
201
|
def unindent(code)
|
138
202
|
if code =~ /^\n([ \t]+)/
|
139
203
|
code = code.gsub(/^#{$1}/, '')
|
@@ -142,7 +206,11 @@ module Mina
|
|
142
206
|
code.strip
|
143
207
|
end
|
144
208
|
|
145
|
-
# Returns
|
209
|
+
# Returns an array of queued code strings.
|
210
|
+
#
|
211
|
+
# You may give an optional `aspect`.
|
212
|
+
#
|
213
|
+
# Returns an array of strings.
|
146
214
|
#
|
147
215
|
# queue "sudo restart"
|
148
216
|
# queue "true"
|
@@ -163,16 +231,18 @@ module Mina
|
|
163
231
|
|
164
232
|
# Starts a new block where new #commands are collected.
|
165
233
|
#
|
166
|
-
#
|
167
|
-
# queue "true"
|
168
|
-
# commands.should == ['sudo restart', 'true']
|
234
|
+
# Returns nothing.
|
169
235
|
#
|
170
|
-
#
|
171
|
-
#
|
172
|
-
#
|
173
|
-
# end
|
236
|
+
# queue "sudo restart"
|
237
|
+
# queue "true"
|
238
|
+
# commands.should == ['sudo restart', 'true']
|
174
239
|
#
|
175
|
-
#
|
240
|
+
# isolate do
|
241
|
+
# queue "reload"
|
242
|
+
# commands.should == ['reload']
|
243
|
+
# end
|
244
|
+
#
|
245
|
+
# commands.should == ['sudo restart', 'true']
|
176
246
|
#
|
177
247
|
def isolate(&blk)
|
178
248
|
old, @commands = @commands, nil
|
@@ -184,6 +254,8 @@ module Mina
|
|
184
254
|
# Defines instructions on how to do a certain thing.
|
185
255
|
# This makes the commands that are `queue`d go into a different bucket in commands.
|
186
256
|
#
|
257
|
+
# Returns nothing.
|
258
|
+
#
|
187
259
|
# to :prepare do
|
188
260
|
# run "bundle install"
|
189
261
|
# end
|
@@ -202,6 +274,9 @@ module Mina
|
|
202
274
|
end
|
203
275
|
|
204
276
|
# Sets settings.
|
277
|
+
# Sets given symbol `key` to value in `value`.
|
278
|
+
#
|
279
|
+
# Returns the value.
|
205
280
|
#
|
206
281
|
# set :domain, 'kickflip.me'
|
207
282
|
#
|
@@ -210,6 +285,9 @@ module Mina
|
|
210
285
|
end
|
211
286
|
|
212
287
|
# Sets default settings.
|
288
|
+
# Sets given symbol `key` to value in `value` only if the key isn't set yet.
|
289
|
+
#
|
290
|
+
# Returns the value.
|
213
291
|
#
|
214
292
|
# set_default :term_mode, :pretty
|
215
293
|
# set :term_mode, :system
|
@@ -235,6 +313,9 @@ module Mina
|
|
235
313
|
|
236
314
|
# Hook to get settings.
|
237
315
|
# See #settings for an explanation.
|
316
|
+
#
|
317
|
+
# Returns things.
|
318
|
+
#
|
238
319
|
def method_missing(meth, *args, &blk)
|
239
320
|
settings.send meth, *args
|
240
321
|
end
|
@@ -247,21 +328,37 @@ module Mina
|
|
247
328
|
$stderr.write "#{str}\n"
|
248
329
|
end
|
249
330
|
|
331
|
+
# Converts a bash command to a command that echoes before execution.
|
332
|
+
# Used to show commands in verbose mode. This does nothing unless verbose mode is on.
|
333
|
+
#
|
334
|
+
# Returns a string of the compound bash command, typically in the format of
|
335
|
+
# `echo xx && xx`. However, if `verbose_mode?` is false, it returns the
|
336
|
+
# input string unharmed.
|
337
|
+
#
|
338
|
+
# echo_cmd("ln -nfs releases/2 current")
|
339
|
+
# #=> echo "$ ln -nfs releases/2 current" && ln -nfs releases/2 current
|
340
|
+
#
|
250
341
|
def echo_cmd(str)
|
251
|
-
if verbose_mode
|
342
|
+
if verbose_mode?
|
252
343
|
"echo #{("$ " + str).inspect} &&\n#{str}"
|
253
344
|
else
|
254
345
|
str
|
255
346
|
end
|
256
347
|
end
|
257
348
|
|
258
|
-
# Invoked when Rake exits.
|
349
|
+
# Internal: Invoked when Rake exits.
|
350
|
+
#
|
351
|
+
# Returns nothing.
|
352
|
+
#
|
259
353
|
def mina_cleanup!
|
260
354
|
run! if commands.any?
|
261
355
|
end
|
262
356
|
|
263
357
|
# Checks if Rake was invoked with --verbose.
|
264
|
-
|
358
|
+
#
|
359
|
+
# Returns true or false.
|
360
|
+
#
|
361
|
+
def verbose_mode?
|
265
362
|
if Rake.respond_to?(:verbose)
|
266
363
|
# Rake 0.9.x
|
267
364
|
Rake.verbose == true
|
@@ -271,7 +368,11 @@ module Mina
|
|
271
368
|
end
|
272
369
|
end
|
273
370
|
|
274
|
-
|
371
|
+
# Checks if Rake was invoked with --simulate.
|
372
|
+
#
|
373
|
+
# Returns true or false.
|
374
|
+
#
|
375
|
+
def simulate_mode?
|
275
376
|
!! ENV['simulate']
|
276
377
|
end
|
277
378
|
end
|
data/lib/mina/tools.rb
CHANGED
data/lib/mina/version.rb
CHANGED
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mina
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.2.pre1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Rico Sta. Cruz
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-06-
|
13
|
+
date: 2012-06-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|
17
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,15 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
26
31
|
- !ruby/object:Gem::Dependency
|
27
32
|
name: open4
|
28
|
-
requirement:
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
29
34
|
none: false
|
30
35
|
requirements:
|
31
36
|
- - ! '>='
|
@@ -33,10 +38,15 @@ dependencies:
|
|
33
38
|
version: '0'
|
34
39
|
type: :runtime
|
35
40
|
prerelease: false
|
36
|
-
version_requirements:
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
37
47
|
- !ruby/object:Gem::Dependency
|
38
48
|
name: rspec
|
39
|
-
requirement:
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
40
50
|
none: false
|
41
51
|
requirements:
|
42
52
|
- - ! '>='
|
@@ -44,7 +54,12 @@ dependencies:
|
|
44
54
|
version: '0'
|
45
55
|
type: :development
|
46
56
|
prerelease: false
|
47
|
-
version_requirements:
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
48
63
|
description: Really fast deployer and server automation tool.
|
49
64
|
email:
|
50
65
|
- rico@nadarei.co
|
@@ -109,12 +124,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
109
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
125
|
none: false
|
111
126
|
requirements:
|
112
|
-
- - ! '
|
127
|
+
- - ! '>'
|
113
128
|
- !ruby/object:Gem::Version
|
114
|
-
version:
|
129
|
+
version: 1.3.1
|
115
130
|
requirements: []
|
116
131
|
rubyforge_project:
|
117
|
-
rubygems_version: 1.8.
|
132
|
+
rubygems_version: 1.8.23
|
118
133
|
signing_key:
|
119
134
|
specification_version: 3
|
120
135
|
summary: Really fast deployer and server automation tool.
|