remoting 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 3.0'
4
+ gem 'net-ssh'
5
+
6
+ group :development do
7
+ gem "jeweler", "~> 1.8.3"
8
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,94 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ actionmailer (3.2.3)
5
+ actionpack (= 3.2.3)
6
+ mail (~> 2.4.4)
7
+ actionpack (3.2.3)
8
+ activemodel (= 3.2.3)
9
+ activesupport (= 3.2.3)
10
+ builder (~> 3.0.0)
11
+ erubis (~> 2.7.0)
12
+ journey (~> 1.0.1)
13
+ rack (~> 1.4.0)
14
+ rack-cache (~> 1.2)
15
+ rack-test (~> 0.6.1)
16
+ sprockets (~> 2.1.2)
17
+ activemodel (3.2.3)
18
+ activesupport (= 3.2.3)
19
+ builder (~> 3.0.0)
20
+ activerecord (3.2.3)
21
+ activemodel (= 3.2.3)
22
+ activesupport (= 3.2.3)
23
+ arel (~> 3.0.2)
24
+ tzinfo (~> 0.3.29)
25
+ activeresource (3.2.3)
26
+ activemodel (= 3.2.3)
27
+ activesupport (= 3.2.3)
28
+ activesupport (3.2.3)
29
+ i18n (~> 0.6)
30
+ multi_json (~> 1.0)
31
+ arel (3.0.2)
32
+ builder (3.0.0)
33
+ erubis (2.7.0)
34
+ git (1.2.5)
35
+ hike (1.2.1)
36
+ i18n (0.6.0)
37
+ jeweler (1.8.3)
38
+ bundler (~> 1.0)
39
+ git (>= 1.2.5)
40
+ rake
41
+ rdoc
42
+ journey (1.0.3)
43
+ json (1.7.0)
44
+ mail (2.4.4)
45
+ i18n (>= 0.4.0)
46
+ mime-types (~> 1.16)
47
+ treetop (~> 1.4.8)
48
+ mime-types (1.18)
49
+ multi_json (1.3.4)
50
+ net-ssh (2.3.0)
51
+ polyglot (0.3.3)
52
+ rack (1.4.1)
53
+ rack-cache (1.2)
54
+ rack (>= 0.4)
55
+ rack-ssl (1.3.2)
56
+ rack
57
+ rack-test (0.6.1)
58
+ rack (>= 1.0)
59
+ rails (3.2.3)
60
+ actionmailer (= 3.2.3)
61
+ actionpack (= 3.2.3)
62
+ activerecord (= 3.2.3)
63
+ activeresource (= 3.2.3)
64
+ activesupport (= 3.2.3)
65
+ bundler (~> 1.0)
66
+ railties (= 3.2.3)
67
+ railties (3.2.3)
68
+ actionpack (= 3.2.3)
69
+ activesupport (= 3.2.3)
70
+ rack-ssl (~> 1.3.2)
71
+ rake (>= 0.8.7)
72
+ rdoc (~> 3.4)
73
+ thor (~> 0.14.6)
74
+ rake (0.9.2.2)
75
+ rdoc (3.12)
76
+ json (~> 1.4)
77
+ sprockets (2.1.3)
78
+ hike (~> 1.2)
79
+ rack (~> 1.0)
80
+ tilt (~> 1.1, != 1.3.0)
81
+ thor (0.14.6)
82
+ tilt (1.3.3)
83
+ treetop (1.4.10)
84
+ polyglot
85
+ polyglot (>= 0.3.1)
86
+ tzinfo (0.3.33)
87
+
88
+ PLATFORMS
89
+ ruby
90
+
91
+ DEPENDENCIES
92
+ jeweler (~> 1.8.3)
93
+ net-ssh
94
+ rails (~> 3.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Maurizio Casimirri
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # Remoting
2
+
3
+ *Remoting* is a great way to turn plain rake tasks in scripts to administer the server remotingly. It provides a little framework to run remoting commands over SSH along with a DSL to define remoting scripts.
4
+
5
+ Install
6
+
7
+ gem 'remoting'
8
+
9
+ Update your bundle
10
+
11
+ bundle install
12
+
13
+ Generate `remote.yml` stub
14
+
15
+ rails g remoting:install
16
+
17
+ Edit `config/remote.yml`
18
+
19
+ ``` yml
20
+ remote:
21
+ any_setting_you_like: Here you can define properties that will be available in 'config' struct inside rake tasks!
22
+ example: Below are some tipical configuration settings you may wish to define ...
23
+ login: user@server
24
+ dest: /var/ror/myapp
25
+ repo: git@gitserver:myapp.git
26
+ ruby: 1.9.3
27
+ gemset: myapp
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ Just require `remoting/task` inside your tasks. NOTE: you can also require it globally but is not recommended cause here `String` is patched to enable bash-flavoured syntax.
33
+
34
+ _ex._
35
+
36
+ desc "Restart the server"
37
+ task :restart do
38
+ require 'remoting/task'
39
+
40
+ remote('restart', config.login) do
41
+ mkdir '-p', config.dest.join('tmp')
42
+ touch config.dest.join('tmp', 'restart.txt')
43
+ end
44
+
45
+ end
46
+
47
+ Methods invoked inside the `remote` block are executed inside a ssh session. `remote` takes two arguments: `name` and `login`. `name` serves only for logging purposal while `login` is the login string to access the server supplied in the form of `user@host`
48
+
49
+ ### DSL
50
+
51
+ By examples
52
+
53
+ remote("my task", config.login) do
54
+
55
+ ps("aux") | grep("mysql")
56
+ echo 'noise' > "/dev/null"
57
+ echo 'setting=value' >> "settings.conf"
58
+ tail -100 config.dir.join('log', 'logfile.log')
59
+ command("[[ -f \"path\" ]] && run_a_command")
60
+
61
+ end
62
+
63
+ ### Local Tasks using DSL
64
+
65
+ You can also define local tasks using the same DSL
66
+
67
+ desc "Setup git origin"
68
+ task :init do
69
+ require 'remoting/task'
70
+
71
+ local('init') do
72
+ git :init
73
+ git :remote, :add, :origin, config.repo
74
+ end
75
+ end
76
+
77
+ Methods invoked inside the `local` block are executed locally. `local` takes only the `name` parameter.
78
+
79
+
80
+ ### Interactive tasks
81
+
82
+ Invoking `remote` with `:interactive => true` will tell `remote` to yield the process to ssh, this way you will remotely interact with the server. On the other side everithing that is supposed to be executed after `remote` wont run. Despite this interactive tasks are very useful.
83
+
84
+ #### Example 1. Rails remote console (by popular demand):
85
+
86
+ # my_remote_task.rake
87
+
88
+ desc "Open rails console on server"
89
+ task :console do
90
+ require 'remoting/task'
91
+
92
+ remote('console', config.login, :interactive => true) do
93
+ cd config.dest
94
+ source '$HOME/.rvm/scripts/rvm'
95
+ bundle :exec, "rails c production"
96
+ end
97
+ end
98
+
99
+ #### Example 2. Reloading Apache configuration (involves sudo):
100
+
101
+ task :reload do
102
+ require 'remoting/task'
103
+
104
+ remote('reload', config.login, :interactive => true) do
105
+ sudo "/etc/init.d/apache2 reload"
106
+ end
107
+ end
108
+
109
+
110
+ ## A note on modularity
111
+
112
+ A complete deployment manager (like Capistrano even if probably not as good as it is) can be easily built over *remoting*. Capistrano recipes can be ordinary rake tasks packed as gems. Plus various _deployment strategies_ can be assembled as dependencies of a main `deploy` task.
113
+
114
+ # Gemfile
115
+ gem 'remoting_scm_git' # provides 'remoting:scm:push, remoting:scm:update_remoting_code'
116
+ gem 'remoting_server_passenger' # provides 'remoting:server:restart'
117
+
118
+ # remoting.rake
119
+ desc "Deploy application on server"
120
+ task :deploy => ["remoting:scm:push", "remoting:scm:update_remoting_code", "remoting:bundle", "remoting:server:restart"] do
121
+ end
122
+
123
+
124
+ ## Examples
125
+
126
+ You can find more examples under `examples` source directory
127
+
128
+
129
+ ## Coming Soon
130
+
131
+ * Ability to define bunch of commands as functions
132
+ * Pre-packed strategies
133
+
134
+ ---
135
+
136
+ Copyright (c) 2012 mcasimir
137
+
138
+ Permission is hereby granted, free of charge, to any person obtaining
139
+ a copy of this software and associated documentation files (the
140
+ "Software"), to deal in the Software without restriction, including
141
+ without limitation the rights to use, copy, modify, merge, publish,
142
+ distribute, sublicense, and/or sell copies of the Software, and to
143
+ permit persons to whom the Software is furnished to do so, subject to
144
+ the following conditions:
145
+
146
+ The above copyright notice and this permission notice shall be
147
+ included in all copies or substantial portions of the Software.
148
+
149
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
150
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
151
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
152
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
153
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
154
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
155
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
156
+
157
+
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "remoting"
18
+ gem.homepage = "http://github.com/mcasimir/remoting"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Turn plain rake tasks in scripts to administer the server remote.}
21
+ gem.description = %Q{Remoting is a great way to turn plain rake tasks in scripts to administer the server remote. It provides a little framework to run remoting commands over SSH along with a DSL to define remoting scripts.}
22
+ gem.email = "maurizio.cas@gmail.com"
23
+ gem.authors = ["mcasimir"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.8
@@ -0,0 +1,243 @@
1
+ namespace :remote do
2
+
3
+ task :info do
4
+ require 'remoting/task'
5
+
6
+ remote('info', config.login) do
7
+ source "~/.profile"
8
+ source "$HOME/.rvm/scripts/rvm"
9
+
10
+ which :ruby
11
+ echo "RUBY VERSION: `ruby --version`"
12
+ echo "RUBYGEM VERSION: `gem --version`"
13
+ command "RVM_VER=`rvm --version`"
14
+ echo "RVM VERSION: $RVM_VER"
15
+ end
16
+ end
17
+
18
+ desc "Setup git origin"
19
+ task :init do
20
+ require 'remoting/task'
21
+
22
+ local('init') do
23
+ git :init
24
+ git :remote, :add, :origin, config.repo
25
+ end
26
+ end
27
+
28
+ desc "Initialize remote"
29
+ task :setup do
30
+ require 'remoting/task'
31
+
32
+ remote('setup', config.login) do
33
+ git :clone, config.repo, config.dest
34
+ end
35
+ end
36
+
37
+ desc "Commit everything to remote git repository"
38
+ task :push, [:message] do |t, args|
39
+ require 'remoting/task'
40
+
41
+ message = args[:message] || "commit #{Time.now}"
42
+
43
+ local('push') do
44
+ git :add, "."
45
+ git :commit, "-a", "-m", "\"#{message}\""
46
+ git :push
47
+ end
48
+ end
49
+
50
+ desc "Update remote code pulling from repository"
51
+ task :pull_on_remote do
52
+ require 'remoting/task'
53
+
54
+ schema = config.dest.join('db', 'schema.rb')
55
+ tmp_schema = config.tmp.join("#{config.app}_#{Time.now.to_i}_schema.rb.tmp")
56
+
57
+ remote('pull_on_remote', config.login) do
58
+ cd config.dest
59
+ command("[[ -f \"#{schema}\" ]] && cp #{schema} #{tmp_schema}")
60
+ rm schema
61
+ git :checkout, 'db/schema.rb'
62
+ git :pull
63
+ command("[[ -f \"#{tmp_schema }\" ]] && mv #{tmp_schema} #{schema}")
64
+ end
65
+
66
+ end
67
+
68
+ desc "Restart the server"
69
+ task :restart do
70
+ require 'remoting/task'
71
+
72
+ remote('restart', config.login) do
73
+ mkdir '-p', config.dest.join('tmp')
74
+ touch config.dest.join('tmp', 'restart.txt')
75
+ end
76
+
77
+ end
78
+
79
+ desc "Hard reset repo on server"
80
+ task :reset do
81
+ require 'remoting/task'
82
+
83
+ remote('reset', config.login) do
84
+ cd config.dest
85
+ git :reset , "--hard HEAD"
86
+ git :clean, "-f", "-d"
87
+ end
88
+
89
+ end
90
+
91
+ desc "Run bundle install on the server"
92
+ task :bundle do
93
+ require 'remoting/task'
94
+
95
+ remote('bundle', config.login) do
96
+ source "~/.profile"
97
+ source "$HOME/.rvm/scripts/rvm"
98
+ rvm :use, config.ruby
99
+
100
+ cd config.dest
101
+ export "LANG=en_US.UTF-8"
102
+ command "RAILS_ENV=production", "bundle install", "--without development test", "--deployment"
103
+ end
104
+ end
105
+
106
+ desc "Deploy application on server"
107
+ task :deploy => [:push, :pull_on_remote, :bundle, :restart] do
108
+ end
109
+
110
+ desc "Run rake tasks on server"
111
+ task :rake, [:invocation] do |t, args|
112
+ require 'remoting/task'
113
+
114
+ invocation = args[:invocation]
115
+
116
+ remote('rake', config.login, :interactive => true) do
117
+ source "$HOME/.rvm/scripts/rvm"
118
+ rvm :use, config.ruby
119
+
120
+ cd config.dest
121
+ command("RAILS_ENV=production bundle exec rake #{invocation}")
122
+ end
123
+
124
+ end
125
+
126
+ desc "Open a remote shell session on server"
127
+ task :ssh do
128
+ require 'remoting/task'
129
+ remote('ssh', config.login, :interactive => true) do
130
+ end
131
+ end
132
+
133
+ desc "Dump a remote logfile"
134
+ task :log, [:lines, :filename] do |t, args|
135
+ require 'remoting/task'
136
+
137
+ filename, lines = args.values_at(:lines, :filename)
138
+ filename ||= "production"
139
+ filename = "#{filename}.log" unless filename =~ /\.[a-z]+$/
140
+
141
+ lines ||= 100
142
+
143
+ remote('log', config.login) do
144
+ cd config.dest
145
+ tail "-#{lines} log/#{filename}"
146
+ end
147
+ end
148
+
149
+ task :logs => [:log] do
150
+ end
151
+
152
+
153
+ desc "Run tail -f on logfile"
154
+ task :logtail, [:filename] do |t, args|
155
+ require 'remoting/task'
156
+
157
+ filename= args[:filename]
158
+ filename ||= "production"
159
+ filename = "#{filename}.log" unless filename =~ /\.[a-z]+$/
160
+
161
+ remote('logtail', config.login) do
162
+ cd config.dest
163
+ tail "-f log/#{filename}"
164
+ end
165
+ end
166
+
167
+ desc "Open a remote console"
168
+ task :console do
169
+ require 'remoting/task'
170
+
171
+ remote('console', config.login, :interactive => true) do
172
+ cd config.dest
173
+ source '$HOME/.rvm/scripts/rvm'
174
+ bundle :exec, "rails c production"
175
+ end
176
+ end
177
+
178
+ desc "Update crontab with whenever schedule"
179
+ task :whenever do
180
+ require 'remoting/task'
181
+
182
+ remote('whenever', config.login) do
183
+ cd config.dest
184
+ whenever "-w"
185
+ end
186
+ end
187
+
188
+
189
+ namespace :apache do
190
+ task :ensite do
191
+ require 'remoting/task'
192
+ remote('ensite', config.login, :interactive => true) do
193
+ cd "/etc/apache2/sites-enabled"
194
+ sudo "ln -s #{config.dest.join('config', 'apache.conf')} #{config.app}"
195
+ end
196
+ end
197
+
198
+ task :reload do
199
+ require 'remoting/task'
200
+
201
+ remote('reload', config.login, :interactive => true) do
202
+ sudo "/etc/init.d/apache2 reload"
203
+ end
204
+ end
205
+
206
+ end
207
+
208
+ namespace :assets do
209
+
210
+ desc 'Precompile assets'
211
+ task :precompile do
212
+ require 'remoting/task'
213
+
214
+ remote('rake assets:precompile', config.login) do
215
+
216
+ source "$HOME/.rvm/scripts/rvm"
217
+ rvm :use, config.ruby
218
+ cd config.dest
219
+ command("RAILS_ENV=production bundle exec rake assets:precompile")
220
+ echo 'restarting ...'
221
+ mkdir '-p', config.dest.join('tmp')
222
+ touch config.dest.join('tmp', 'restart.txt')
223
+
224
+ end
225
+ end
226
+ end
227
+
228
+ namespace :db do
229
+
230
+ desc "Migrate remote database"
231
+ task :migrate do |t, args|
232
+ require 'remoting/task'
233
+
234
+ remote('rake db:migrate', config.login) do
235
+ source "$HOME/.rvm/scripts/rvm"
236
+ rvm :use, config.ruby
237
+ cd config.dest
238
+ command("RAILS_ENV=production bundle exec rake db:migrate")
239
+ end
240
+ end
241
+ end
242
+
243
+ end
@@ -0,0 +1,7 @@
1
+ remote:
2
+ login: user@server
3
+ dest: /var/ror/myapp
4
+ repo: git@gitserver:myapp.git
5
+ ruby: 1.9.3
6
+ tmp: /tmp
7
+ app: appname
@@ -0,0 +1,20 @@
1
+ module Remoting
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ def create_remote_yml
5
+
6
+ stub = <<-STUB
7
+ remote:
8
+ login: user@server
9
+ dest: /var/ror/myapp
10
+ repo: git@gitserver:myapp
11
+ ruby: 1.9.3
12
+ gemset: myapp
13
+ STUB
14
+
15
+ create_file "config/remote.yml", stub
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module Remoting
2
+ class Commander
3
+
4
+ def exec(commands)
5
+ do_exec(commands)
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ require 'yaml'
2
+ require 'ostruct'
3
+
4
+ module Remoting
5
+ class Config < OpenStruct
6
+
7
+ def initialize
8
+ hash = YAML.load_file(Rails.root.join('config', 'remote.yml'))
9
+ super(hash["remote"])
10
+ end
11
+
12
+ end
13
+
14
+ def config
15
+ @config ||= Config.new
16
+ end
17
+ module_function :config
18
+ end
@@ -0,0 +1,52 @@
1
+ require 'remoting/dsl/string'
2
+
3
+ module Remoting
4
+ module Dsl
5
+
6
+ class ScriptBuilder
7
+ shadow_methods = %w(gem cd chdir chmod chmod_R chown chown_R cmp compare_file compare_stream copy copy_entry copy_file copy_stream cp cp_r getwd identical? install link ln ln_s ln_sf makedirs mkdir mkdir_p mkpath move mv pwd remove remove_dir remove_entry remove_entry_secure remove_file rm rm_f rm_r rm_rf rmdir rmtree safe_unlink symlink touch uptodate?)
8
+
9
+ shadow_methods.each do |name|
10
+ define_method name do |*args|
11
+ self.command(name, *args)
12
+ end
13
+ end
14
+
15
+ class << self
16
+ def build(&block)
17
+ instance = self.new
18
+ instance.instance_eval(&block)
19
+ instance.commands
20
+ end
21
+ end
22
+
23
+ def initialize
24
+ @commands = []
25
+ end
26
+
27
+ def commands()
28
+ @commands.flatten.map! do |c|
29
+ c.split(/[\r\n]/).map{|l|
30
+ line = l.strip
31
+ line.empty? ? nil : line
32
+ }
33
+ end.flatten.compact.delete_if(&:empty?)
34
+ end
35
+
36
+ def command(*args)
37
+ cmd = args.map(&:to_s).join(" ")
38
+ @commands << cmd
39
+ cmd
40
+ end
41
+
42
+ private
43
+
44
+ def method_missing(*args)
45
+ command(*args)
46
+ end
47
+
48
+
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ class String
2
+ def > (arg)
3
+ self << " > " << "#{arg}"
4
+ arg.clear
5
+ self
6
+ end
7
+
8
+ def >> (arg)
9
+ self << " >> " << "#{arg}"
10
+ arg.clear
11
+ self
12
+ end
13
+
14
+ def | (arg)
15
+ self << " | " << "#{arg}"
16
+ arg.clear
17
+ self
18
+ end
19
+
20
+ def join(*args)
21
+ Pathname.new(self).join(*args).to_s
22
+ end
23
+
24
+ end
@@ -0,0 +1,5 @@
1
+ module Remoting
2
+ class Engine < Rails::Engine
3
+
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ require 'remoting/commander'
2
+
3
+ module Remoting
4
+ class LocalCommander < Commander
5
+
6
+ #overrides
7
+ def do_exec(cmds)
8
+ local(cmds)
9
+ end
10
+
11
+ def local(cmds)
12
+ runline = cmds.map{|c| "#{c} 2>&1"}.join(";")
13
+ # puts "[LOCAL] Executing '#{runline}' ..."
14
+ puts `#{runline}`
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ require 'remoting/commander'
2
+ require 'remoting/ssh'
3
+
4
+ module Remoting
5
+ class RemoteCommander < Commander
6
+
7
+ attr_reader :login, :interactive
8
+ def initialize(login, *args)
9
+ options = args.extract_options!
10
+ @login = login
11
+ @interactive = !!options[:interactive]
12
+ end
13
+
14
+ #overrides
15
+ def do_exec(cmds)
16
+ remote(cmds)
17
+ end
18
+
19
+ def remote(cmds)
20
+ user, host = login.split("@")
21
+
22
+ ssh = ::remoting::Ssh.new(
23
+ :user => user,
24
+ :host => host,
25
+ :interactive => interactive
26
+ )
27
+
28
+ ssh.exec(cmds)
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ require 'thor'
2
+
3
+ module Remoting
4
+ class Shell < Thor::Shell::Color
5
+ def ask_password(*args)
6
+ system "stty -echo"
7
+ res = ask(*args)
8
+ system "stty echo"
9
+ puts("\n")
10
+ res
11
+ end
12
+
13
+ def continue?(message)
14
+ res = yes?(message << " (y/yes)")
15
+ if !res
16
+ say("Cancelled", BLUE)
17
+ end
18
+ res
19
+ end
20
+
21
+ def bold(message)
22
+ say(message, BOLD)
23
+ end
24
+
25
+ def no?(message)
26
+ super(message << " (n/no)")
27
+ end
28
+
29
+ def success(message)
30
+ say(message, GREEN)
31
+ end
32
+
33
+ def error(message)
34
+ say(message, RED)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,57 @@
1
+ require 'net/ssh'
2
+ require 'remoting/shell'
3
+
4
+ module Remoting
5
+ class Ssh
6
+ attr_reader :host, :user
7
+
8
+ def initialize(*args)
9
+ options = args.extract_options!
10
+ @host, @user, @interactive = options.values_at(:host, :user, :interactive)
11
+ end
12
+
13
+
14
+ def shell
15
+ @shell ||= ::remoting::Shell.new
16
+ end
17
+
18
+ def exec(commands)
19
+
20
+ if interactive?
21
+ ssh = %(ssh #{user}@#{host})
22
+ Kernel.exec ssh + %( -t '#{commands.join("; ")}') # this will replace the current process and will never return the shell back
23
+ else
24
+ Net::SSH.start(host, user) do |ssh|
25
+
26
+ ssh.open_channel do |channel|
27
+ channel.exec(commands.join(";")) do |ch, success|
28
+ unless success
29
+ abort
30
+ end
31
+
32
+ channel.on_data do |ch, data|
33
+ say "#{data}"
34
+ end
35
+
36
+ channel.on_extended_data do |ch, type, data|
37
+ shell.error "#{data}"
38
+ end
39
+
40
+ channel.on_close do |ch|
41
+ shell.bold "channel is closing!\n"
42
+ end
43
+ end
44
+ end
45
+
46
+ ssh.loop
47
+ end
48
+ end
49
+
50
+ end # ~ exec
51
+
52
+ def interactive?
53
+ !!@interactive
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,50 @@
1
+ require 'remoting/dsl/script_builder'
2
+ require 'remoting/local_commander'
3
+ require 'remoting/remoting_commander'
4
+ require 'remoting/shell'
5
+
6
+ module Remoting
7
+ module Task
8
+
9
+ def _remoting_task_included
10
+ end
11
+
12
+ def config
13
+ remoting.config
14
+ end
15
+
16
+ def local(name, *args, &block)
17
+ bold("Executing '#{name}' on local ...")
18
+ commands = ::remoting::Dsl::ScriptBuilder.build(&block)
19
+ commander = LocalCommander.new(*args)
20
+ run(commander, commands)
21
+ end
22
+
23
+ def remote(name, login, *args, &block)
24
+ bold("Executing '#{name}' on '#{login}' ...")
25
+ commands = ::remoting::Dsl::ScriptBuilder.build(&block)
26
+ commander = RemoteCommander.new(login, *args)
27
+ run(commander, commands)
28
+ end
29
+
30
+ def run(commander, commands)
31
+ commander.exec(commands)
32
+ end
33
+
34
+ def shell
35
+ @shell ||= ::remoting::Shell.new
36
+ end
37
+
38
+ %w(bold error success yes? no? say continue?).each do |meth|
39
+ eval("def #{meth}(*args);shell.#{meth}(*args);end")
40
+ end
41
+
42
+ end
43
+ end
44
+
45
+ unless self.respond_to?(:_remoting_task_included)
46
+ include remoting::Task
47
+ end
48
+
49
+
50
+
data/lib/remoting.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Remoting
2
+ end
3
+
4
+ require 'remoting/config'
5
+ require 'remoting/engine'
6
+
7
+
data/remoting.gemspec ADDED
@@ -0,0 +1,66 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "remoting"
8
+ s.version = "0.2.8"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["mcasimir"]
12
+ s.date = "2012-05-08"
13
+ s.description = "Remoting is a great way to turn plain rake tasks in scripts to administer the server remote. It provides a little framework to run remoting commands over SSH along with a DSL to define remoting scripts."
14
+ s.email = "maurizio.cas@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "examples/remote.rake",
27
+ "examples/remote.yml",
28
+ "lib/generators/remoting/install_generator.rb",
29
+ "lib/remoting.rb",
30
+ "lib/remoting/commander.rb",
31
+ "lib/remoting/config.rb",
32
+ "lib/remoting/dsl/script_builder.rb",
33
+ "lib/remoting/dsl/string.rb",
34
+ "lib/remoting/engine.rb",
35
+ "lib/remoting/local_commander.rb",
36
+ "lib/remoting/remote_commander.rb",
37
+ "lib/remoting/shell.rb",
38
+ "lib/remoting/ssh.rb",
39
+ "lib/remoting/task.rb",
40
+ "remoting.gemspec"
41
+ ]
42
+ s.homepage = "http://github.com/mcasimir/remoting"
43
+ s.licenses = ["MIT"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = "1.8.24"
46
+ s.summary = "Turn plain rake tasks in scripts to administer the server remote."
47
+
48
+ if s.respond_to? :specification_version then
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<rails>, ["~> 3.0"])
53
+ s.add_runtime_dependency(%q<net-ssh>, [">= 0"])
54
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
55
+ else
56
+ s.add_dependency(%q<rails>, ["~> 3.0"])
57
+ s.add_dependency(%q<net-ssh>, [">= 0"])
58
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<rails>, ["~> 3.0"])
62
+ s.add_dependency(%q<net-ssh>, [">= 0"])
63
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
64
+ end
65
+ end
66
+
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remoting
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.8
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - mcasimir
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: net-ssh
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: jeweler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.8.3
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.8.3
62
+ description: Remoting is a great way to turn plain rake tasks in scripts to administer
63
+ the server remote. It provides a little framework to run remoting commands over
64
+ SSH along with a DSL to define remoting scripts.
65
+ email: maurizio.cas@gmail.com
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files:
69
+ - LICENSE.txt
70
+ - README.md
71
+ files:
72
+ - Gemfile
73
+ - Gemfile.lock
74
+ - LICENSE.txt
75
+ - README.md
76
+ - Rakefile
77
+ - VERSION
78
+ - examples/remote.rake
79
+ - examples/remote.yml
80
+ - lib/generators/remoting/install_generator.rb
81
+ - lib/remoting.rb
82
+ - lib/remoting/commander.rb
83
+ - lib/remoting/config.rb
84
+ - lib/remoting/dsl/script_builder.rb
85
+ - lib/remoting/dsl/string.rb
86
+ - lib/remoting/engine.rb
87
+ - lib/remoting/local_commander.rb
88
+ - lib/remoting/remote_commander.rb
89
+ - lib/remoting/shell.rb
90
+ - lib/remoting/ssh.rb
91
+ - lib/remoting/task.rb
92
+ - remoting.gemspec
93
+ homepage: http://github.com/mcasimir/remoting
94
+ licenses:
95
+ - MIT
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ segments:
107
+ - 0
108
+ hash: -1608284933107565365
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.24
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Turn plain rake tasks in scripts to administer the server remote.
121
+ test_files: []