j-cap-recipes 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +1 -1
- data/README.md +46 -6
- data/lib/j-cap-recipes.rb +2 -9
- data/lib/j-cap-recipes/default.rb +8 -0
- data/lib/j-cap-recipes/rails.rb +34 -54
- data/lib/j-cap-recipes/railtie.rb +7 -0
- data/lib/j-cap-recipes/tasks/db.rake +74 -0
- data/lib/j-cap-recipes/tasks/handy.rake +12 -2
- data/lib/j-cap-recipes/tasks/rails.rake +12 -24
- data/lib/j-cap-recipes/version.rb +1 -1
- data/lib/sshkit/backends/ssh_command.rb +26 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b96c02150dff5033f67954c8625e207f08050d9
|
4
|
+
data.tar.gz: a9cd1381347921f258d6987953a3155127b1b725
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ffd8d989dcf6292e96a6a04d2d1bb02d7981a3421836af6e6c68bb3be648ca6d3eef9b03e6790a8cdd5daaa6313d6b6798adbc2fdf8d23f7ffa70ad39d026ef
|
7
|
+
data.tar.gz: a1ddaafa9ec4178cb3cd63990eacbadf87aa8e8101f5bbaad55eef9627decfa21625715a904255f611c969faf8939bafefa3c6afdb1b02d3ae18dfdced5dd97c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
## 0.0.15
|
4
|
+
|
5
|
+
* Added new SSHKit backend called SshCommand. It adds support to run interactive commands, example like `rails console`.
|
6
|
+
* Added rails rake task to create datbase backup and restore. You can check `rake -T`
|
7
|
+
* Optimized to run rails console task via SshCommand backend
|
8
|
+
* Added a new task `rails:less_log` to show the current log file via `less`
|
9
|
+
* Update Handy with a new task `config:settings:get` to download remote stage config to local folder.
|
10
|
+
|
3
11
|
## 0.0.14
|
4
12
|
|
5
13
|
* Added airbrake deploy notification task.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -7,7 +7,7 @@ A simple number of capistrano recipes to deploy rails application using Capistra
|
|
7
7
|
|
8
8
|
Add this line to your application's Gemfile:
|
9
9
|
|
10
|
-
gem 'j-cap-recipes',
|
10
|
+
gem 'j-cap-recipes', group: :development
|
11
11
|
|
12
12
|
And then execute:
|
13
13
|
|
@@ -21,7 +21,7 @@ Or install it yourself as:
|
|
21
21
|
|
22
22
|
In the `Capfile` to include all recipes add:
|
23
23
|
|
24
|
-
require 'j-cap-recipes'
|
24
|
+
require 'j-cap-recipes/default'
|
25
25
|
|
26
26
|
If you want to load only specified recipe:
|
27
27
|
|
@@ -37,6 +37,10 @@ If you want to load only specified recipe:
|
|
37
37
|
require 'j-cap-recipes/honeybadger'
|
38
38
|
require 'j-cap-recipes/airbrake'
|
39
39
|
|
40
|
+
Also you need to include rake tasks in your `Rakefile`:
|
41
|
+
|
42
|
+
require 'j-cap-recipes'
|
43
|
+
|
40
44
|
### Nginx
|
41
45
|
### Setup
|
42
46
|
### Check
|
@@ -91,6 +95,7 @@ There are three tasks available:
|
|
91
95
|
- `cap staging config:settings` Show the current staging config files;
|
92
96
|
- `cap staging config:settings:delete` Remove the custom env settings file;
|
93
97
|
- `cap staging config:settings:upload` Update the remote config file with local one;
|
98
|
+
- `cap staging config:settings:get` Download the rmote config file to local one
|
94
99
|
|
95
100
|
### Git
|
96
101
|
|
@@ -128,6 +133,45 @@ after 'deploy:finishing', 'airbrake:deploy'
|
|
128
133
|
|
129
134
|
You can change the default api key using `ENV['API_KEY']`.
|
130
135
|
|
136
|
+
|
137
|
+
### Rake tasks
|
138
|
+
|
139
|
+
Added utility rake task to create database backup for postgresql and rails.
|
140
|
+
|
141
|
+
### SSHKit addon
|
142
|
+
|
143
|
+
`SSHKit::Backend::SshCommand` a new backend to invoke the ssh command using sytem command `ssh`.
|
144
|
+
Now you can easy to execute interactive applications with similar changes. Example:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
namespace :rails do
|
148
|
+
desc 'Execute rails console'
|
149
|
+
task :console do
|
150
|
+
on roles(:app), in: :parallel, backend: :ssh_command do |*args|
|
151
|
+
within release_path do
|
152
|
+
with rails_env: fetch(:rails_env) do
|
153
|
+
execute(:rails, :console)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
And you have a easy and fast way to run remote interactive rails console via command `cap production rails:console`.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
task :less_log do
|
165
|
+
on roles(:app), in: :parallel, backend: :ssh_command do |*args|
|
166
|
+
within current_path.join('log') do
|
167
|
+
execute(:less, '-R', fetch(:rails_env)+'.log')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
173
|
+
And you have way to look to logs `cap production less_log`.
|
174
|
+
|
131
175
|
## Contributing
|
132
176
|
|
133
177
|
1. Fork it
|
@@ -135,7 +179,3 @@ You can change the default api key using `ENV['API_KEY']`.
|
|
135
179
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
136
180
|
4. Push to the branch (`git push origin my-new-feature`)
|
137
181
|
5. Create new Pull Request
|
138
|
-
|
139
|
-
|
140
|
-
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/jetthoughts/j-cap-recipes/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
|
141
|
-
|
data/lib/j-cap-recipes.rb
CHANGED
@@ -1,9 +1,2 @@
|
|
1
|
-
require_relative 'j-cap-recipes/
|
2
|
-
require_relative 'j-cap-recipes/
|
3
|
-
require_relative 'j-cap-recipes/check'
|
4
|
-
require_relative 'j-cap-recipes/delayed_job'
|
5
|
-
require_relative 'j-cap-recipes/monit'
|
6
|
-
require_relative 'j-cap-recipes/nginx'
|
7
|
-
require_relative 'j-cap-recipes/rake'
|
8
|
-
require_relative 'j-cap-recipes/setup'
|
9
|
-
require_relative 'j-cap-recipes/unicorn'
|
1
|
+
require_relative 'j-cap-recipes/version'
|
2
|
+
require_relative 'j-cap-recipes/railtie' if defined?(Rails)
|
data/lib/j-cap-recipes/rails.rb
CHANGED
@@ -1,65 +1,45 @@
|
|
1
|
+
require 'sshkit/backends/ssh_command'
|
2
|
+
require 'sshkit/runners/abstract'
|
3
|
+
|
4
|
+
#Patch to support backend option
|
5
|
+
# Sent PR https://github.com/capistrano/sshkit/pull/117, except constantinize
|
1
6
|
module SSHKit
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
7
|
+
|
8
|
+
module Runner
|
9
|
+
|
10
|
+
class Abstract
|
11
|
+
|
12
|
+
attr_reader :hosts, :options, :block
|
13
|
+
|
14
|
+
def initialize(hosts, options = nil, &block)
|
15
|
+
@hosts = Array(hosts)
|
16
|
+
@options = options || {}
|
17
|
+
@block = block
|
6
18
|
end
|
7
19
|
|
8
20
|
private
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
chan.on_extended_data do |ch, type, data|
|
27
|
-
cmd.stderr = data
|
28
|
-
cmd.full_stderr += data
|
29
|
-
output << cmd
|
30
|
-
end
|
31
|
-
chan.on_request("exit-status") do |ch, data|
|
32
|
-
cmd.stdout = ''
|
33
|
-
cmd.stderr = ''
|
34
|
-
cmd.exit_status = data.read_long
|
35
|
-
output << cmd
|
36
|
-
end
|
37
|
-
#chan.on_request("exit-signal") do |ch, data|
|
38
|
-
# # TODO: This gets called if the program is killed by a signal
|
39
|
-
# # might also be a worthwhile thing to report
|
40
|
-
# exit_signal = data.read_string.to_i
|
41
|
-
# warn ">>> " + exit_signal.inspect
|
42
|
-
# output << cmd
|
43
|
-
#end
|
44
|
-
chan.on_open_failed do |ch|
|
45
|
-
# TODO: What do do here?
|
46
|
-
# I think we should raise something
|
47
|
-
end
|
48
|
-
chan.on_process do |ch|
|
49
|
-
# TODO: I don't know if this is useful
|
50
|
-
end
|
51
|
-
chan.on_eof do |ch|
|
52
|
-
# TODO: chan sends EOF before the exit status has been
|
53
|
-
# writtend
|
54
|
-
end
|
55
|
-
end
|
56
|
-
chan.wait
|
57
|
-
end
|
58
|
-
ssh.loop
|
21
|
+
|
22
|
+
def backend(host, &block)
|
23
|
+
backend_factory.new(host, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def backend_factory
|
27
|
+
case @options[:backend]
|
28
|
+
when Symbol
|
29
|
+
SSHKit::Backend.const_get(@options[:backend].to_s.split('_').collect(&:capitalize).join)
|
30
|
+
when String
|
31
|
+
Kernel.const_get(@options[:backend])
|
32
|
+
when nil
|
33
|
+
SSHKit.config.backend
|
34
|
+
else
|
35
|
+
@options[:backend]
|
59
36
|
end
|
37
|
+
|
60
38
|
end
|
61
39
|
end
|
40
|
+
|
62
41
|
end
|
42
|
+
|
63
43
|
end
|
64
44
|
|
65
45
|
load File.expand_path('../tasks/rails.rake', __FILE__)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
namespace :db do
|
2
|
+
desc 'PG backup'
|
3
|
+
task backup: [:environment, :load_config] do
|
4
|
+
#stamp the filename
|
5
|
+
datestamp = Time.now.strftime('%Y-%m-%d_%H-%M-%S')
|
6
|
+
|
7
|
+
#create backups folder
|
8
|
+
backup_dir = ENV['backup-path'] || Rails.root.join('db', 'backups')
|
9
|
+
mkdir_p(backup_dir)
|
10
|
+
|
11
|
+
config = ActiveRecord::Base.connection_config
|
12
|
+
database_name = ActiveRecord::Base.connection.current_database
|
13
|
+
backup_file = File.join(backup_dir, "#{database_name}_#{datestamp}.dump")
|
14
|
+
|
15
|
+
#dump the backup and zip it up
|
16
|
+
dump_command = "pg_dump #{database_name} -w -F c"
|
17
|
+
dump_command += " -h #{config[:hostname]}" if config[:hostname].present?
|
18
|
+
dump_command += " -U #{config[:username]}" if config[:username].present?
|
19
|
+
dump_command += " > #{backup_file}"
|
20
|
+
|
21
|
+
sh dump_command
|
22
|
+
|
23
|
+
safe_ln backup_file, File.join(backup_dir, "#{database_name}_latest.dump")
|
24
|
+
|
25
|
+
#send_to_amazon backup_file
|
26
|
+
#remove the file on completion so we don't clog up our app
|
27
|
+
#File.delete backup_file
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'PG restore from the last backup file'
|
31
|
+
task restore: [:environment, :load_config] do
|
32
|
+
config = ActiveRecord::Base.connection_config
|
33
|
+
database_name = ActiveRecord::Base.connection.current_database
|
34
|
+
backup_dir = ENV['backup-path'] || Rails.root.join('db', 'backups')
|
35
|
+
backup_file = File.join(backup_dir, "#{database_name}_latest.dump")
|
36
|
+
|
37
|
+
Rake::Task['db:kill_postgres_connections'].invoke
|
38
|
+
Rake::Task['db:drop'].invoke
|
39
|
+
Rake::Task['db:create'].invoke
|
40
|
+
|
41
|
+
restore_command = "pg_restore -d #{database_name} -F c -w #{backup_file}"
|
42
|
+
restore_command = postgres_command_options restore_command, config
|
43
|
+
sh "#{restore_command} || echo 'done'"
|
44
|
+
end
|
45
|
+
|
46
|
+
task :kill_postgres_connections => :environment do
|
47
|
+
database_name = ActiveRecord::Base.connection.current_database
|
48
|
+
command = <<EOF
|
49
|
+
ps xa \
|
50
|
+
| grep postgres: \
|
51
|
+
| grep #{database_name} \
|
52
|
+
| grep -v grep \
|
53
|
+
| awk '{print $1}' \
|
54
|
+
| xargs kill
|
55
|
+
EOF
|
56
|
+
sh command
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def postgres_command_options(str, config)
|
62
|
+
str += " -h #{config[:hostname]}" if config[:hostname].present?
|
63
|
+
str += " -U #{config[:username]}" if config[:username].present?
|
64
|
+
str
|
65
|
+
end
|
66
|
+
|
67
|
+
#TODO: Use setting to get S3 credentials
|
68
|
+
def send_to_amazon(file_path)
|
69
|
+
bucket = "db-backups"
|
70
|
+
file_name = File.basename(file_path)
|
71
|
+
AWS::S3::Base.establish_connection!(:access_key_id => 'YOUR KEY', :secret_access_key => 'YOUR SECRET')
|
72
|
+
#push the file up
|
73
|
+
AWS::S3::S3Object.store(file_name, File.open(file_path), bucket)
|
74
|
+
end
|
@@ -20,11 +20,21 @@ namespace :config do
|
|
20
20
|
desc 'Show current settings'
|
21
21
|
task :show do
|
22
22
|
on roles(:all) do |host|
|
23
|
-
within current_path do
|
24
|
-
execute :cat, '
|
23
|
+
within current_path.join('config') do
|
24
|
+
execute :cat, 'settings.yml'
|
25
|
+
execute :cat, "settings/#{fetch(:stage)}.yml"
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|
29
|
+
|
30
|
+
desc 'Show current settings'
|
31
|
+
task :get do
|
32
|
+
on roles(:all) do |host|
|
33
|
+
local_dir = File.join(Dir.pwd, 'config', 'settings')
|
34
|
+
FileUtils.mkdir_p local_dir
|
35
|
+
download! current_path.join('config', 'settings', "#{fetch(:stage)}.yml"), local_dir
|
36
|
+
end
|
37
|
+
end
|
28
38
|
end
|
29
39
|
|
30
40
|
end
|
@@ -1,34 +1,22 @@
|
|
1
1
|
namespace :rails do
|
2
2
|
desc 'Execute rails console'
|
3
3
|
task :console do
|
4
|
-
on roles(:app) do
|
4
|
+
on roles(:app), in: :parallel, backend: :ssh_command do |*args|
|
5
5
|
within release_path do
|
6
6
|
with rails_env: fetch(:rails_env) do
|
7
|
-
|
8
|
-
execute(:rails, :console) do |ch, data|
|
9
|
-
row += data
|
10
|
-
if command && row.include?(command)
|
11
|
-
row.sub!(/#{command}(\r\n)?/, '')
|
12
|
-
command = nil
|
13
|
-
end
|
14
|
-
|
15
|
-
if row.include?('irb(main):')
|
16
|
-
print row
|
17
|
-
row = ''
|
18
|
-
command = $stdin.gets
|
19
|
-
command = "exit\n" if command == nil
|
20
|
-
ch.send_data command
|
21
|
-
command.chomp!
|
22
|
-
end
|
23
|
-
|
24
|
-
if row.include?("\n")
|
25
|
-
print row
|
26
|
-
row = ''
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
7
|
+
execute(:rails, :console)
|
30
8
|
end
|
31
9
|
end
|
32
10
|
end
|
33
11
|
end
|
12
|
+
|
13
|
+
desc 'Execute less on current env log file'
|
14
|
+
task :less_log do
|
15
|
+
on roles(:app), in: :parallel, backend: :ssh_command do |*args|
|
16
|
+
within current_path.join('log') do
|
17
|
+
execute(:less, '-R', fetch(:rails_env)+'.log')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
34
22
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SSHKit
|
2
|
+
|
3
|
+
module Backend
|
4
|
+
|
5
|
+
class SshCommand < Printer
|
6
|
+
|
7
|
+
def run
|
8
|
+
instance_exec(host, &@block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def within(directory, &block)
|
12
|
+
(@pwd ||= []).push directory.to_s
|
13
|
+
yield
|
14
|
+
ensure
|
15
|
+
@pwd.pop
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute(*args, &block)
|
19
|
+
result = 'ssh %s@%s -t "%s"' % [host.username, String(host.hostname), command(*args).to_command]
|
20
|
+
output << Command.new(result)
|
21
|
+
system(result)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: j-cap-recipes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Nikitochkin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- lib/j-cap-recipes/airbrake.rb
|
71
71
|
- lib/j-cap-recipes/check.rb
|
72
72
|
- lib/j-cap-recipes/database.rb
|
73
|
+
- lib/j-cap-recipes/default.rb
|
73
74
|
- lib/j-cap-recipes/delayed_job.rb
|
74
75
|
- lib/j-cap-recipes/deploy.rb
|
75
76
|
- lib/j-cap-recipes/files.rb
|
@@ -81,11 +82,13 @@ files:
|
|
81
82
|
- lib/j-cap-recipes/monit.rb
|
82
83
|
- lib/j-cap-recipes/nginx.rb
|
83
84
|
- lib/j-cap-recipes/rails.rb
|
85
|
+
- lib/j-cap-recipes/railtie.rb
|
84
86
|
- lib/j-cap-recipes/rake.rb
|
85
87
|
- lib/j-cap-recipes/setup.rb
|
86
88
|
- lib/j-cap-recipes/tasks/airbrake.rake
|
87
89
|
- lib/j-cap-recipes/tasks/check.rake
|
88
90
|
- lib/j-cap-recipes/tasks/database.rake
|
91
|
+
- lib/j-cap-recipes/tasks/db.rake
|
89
92
|
- lib/j-cap-recipes/tasks/delayed_job.rake
|
90
93
|
- lib/j-cap-recipes/tasks/deploy.rake
|
91
94
|
- lib/j-cap-recipes/tasks/files.rake
|
@@ -103,6 +106,7 @@ files:
|
|
103
106
|
- lib/j-cap-recipes/tasks/unicorn.rake
|
104
107
|
- lib/j-cap-recipes/unicorn.rb
|
105
108
|
- lib/j-cap-recipes/version.rb
|
109
|
+
- lib/sshkit/backends/ssh_command.rb
|
106
110
|
homepage: https://github.com/jetthoughts/j-cap-recipes
|
107
111
|
licenses:
|
108
112
|
- MIT
|