j-cap-recipes 0.0.14 → 0.0.15
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.
- 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
|
-
[](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
|