rsh2 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +2 -2
- data/lib/ros/rake.rb +9 -0
- data/lib/ros/ros.rb +57 -0
- data/lib/ros.rb +4 -0
- data/lib/rsh/box.rb +26 -0
- data/lib/rsh/drivers/ssh.rb +20 -6
- data/readme.md +44 -4
- metadata +6 -3
data/Rakefile
CHANGED
@@ -2,8 +2,8 @@ require 'rake_ext'
|
|
2
2
|
|
3
3
|
project(
|
4
4
|
name: "rsh2",
|
5
|
-
version: "0.0.
|
6
|
-
summary: "Tiny wrapper over Net::SSH
|
5
|
+
version: "0.0.3",
|
6
|
+
summary: "Tiny wrapper over Net::SSH/SFTP + small rake addon for cluster configuration management",
|
7
7
|
|
8
8
|
author: "Alexey Petrushin",
|
9
9
|
homepage: "http://github.com/alexeypetrushin/rssh"
|
data/lib/ros/rake.rb
ADDED
data/lib/ros/ros.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Ros
|
2
|
+
class Dsl
|
3
|
+
attr_reader :package
|
4
|
+
|
5
|
+
def initialize package
|
6
|
+
@package = package
|
7
|
+
end
|
8
|
+
|
9
|
+
def applied? &b
|
10
|
+
package.applied = b
|
11
|
+
end
|
12
|
+
|
13
|
+
def apply &b
|
14
|
+
package.apply = b
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Package
|
19
|
+
attr_accessor :applied, :apply, :name
|
20
|
+
|
21
|
+
def initialize name
|
22
|
+
@name = name
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure_with &b
|
26
|
+
dsl = Dsl.new self
|
27
|
+
dsl.instance_eval &b
|
28
|
+
end
|
29
|
+
|
30
|
+
def apply_to box
|
31
|
+
unless applied and applied.call(box)
|
32
|
+
print "applying '#{name}' to '#{box.options[:host]}'\n"
|
33
|
+
apply.call box
|
34
|
+
print "done\n"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def each_box_cached &b
|
41
|
+
unless @each_box_cached
|
42
|
+
unless Object.private_instance_methods(false).include?(:each_box)
|
43
|
+
raise "you must define 'each_box' method!"
|
44
|
+
end
|
45
|
+
|
46
|
+
@each_box_cached = []
|
47
|
+
each_box do |box|
|
48
|
+
@each_box_cached << box
|
49
|
+
|
50
|
+
# cache ssh connection
|
51
|
+
box.open_connection
|
52
|
+
end
|
53
|
+
end
|
54
|
+
@each_box_cached.each &b
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/ros.rb
ADDED
data/lib/rsh/box.rb
CHANGED
@@ -142,7 +142,33 @@ module Rsh
|
|
142
142
|
driver.exec cmd
|
143
143
|
end
|
144
144
|
|
145
|
+
def home path = nil
|
146
|
+
@home ||= bash('cd ~; pwd').gsub("\n", '')
|
147
|
+
"#{@home}#{path}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def mark key
|
151
|
+
ensure_mark_requrements!
|
152
|
+
bash "touch #{marks_dir}/#{key}"
|
153
|
+
end
|
154
|
+
|
155
|
+
def has_mark? key
|
156
|
+
ensure_mark_requrements!
|
157
|
+
file_exist? "#{marks_dir}/#{key}"
|
158
|
+
end
|
159
|
+
|
145
160
|
protected
|
161
|
+
def marks_dir
|
162
|
+
home "/.marks"
|
163
|
+
end
|
164
|
+
|
165
|
+
def ensure_mark_requrements!
|
166
|
+
unless @ensure_mark_requrements
|
167
|
+
create_directory marks_dir unless directory_exist? marks_dir
|
168
|
+
@ensure_mark_requrements = true
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
146
172
|
def method_missing m, *a, &b
|
147
173
|
driver.send m, *a, &b
|
148
174
|
end
|
data/lib/rsh/drivers/ssh.rb
CHANGED
@@ -9,14 +9,14 @@ module Rsh
|
|
9
9
|
|
10
10
|
def upload_file from_local_path, to_remote_path
|
11
11
|
remote do |ssh, sftp|
|
12
|
-
sftp.upload! from_local_path, to_remote_path
|
12
|
+
sftp.upload! from_local_path, fix_path(to_remote_path)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def download_file from_remote_path, to_local_path
|
17
17
|
File.open to_local_path, "w" do |out|
|
18
18
|
remote do |ssh, sftp|
|
19
|
-
sftp.download! from_remote_path, out #, :recursive => true
|
19
|
+
sftp.download! fix_path(from_remote_path), out #, :recursive => true
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -24,7 +24,7 @@ module Rsh
|
|
24
24
|
def exist? remote_file_path
|
25
25
|
remote do |ssh, sftp|
|
26
26
|
begin
|
27
|
-
fattrs = sftp.stat! remote_file_path
|
27
|
+
fattrs = sftp.stat! fix_path(remote_file_path)
|
28
28
|
fattrs.directory? or fattrs.file? or fattrs.symlink?
|
29
29
|
rescue Net::SFTP::StatusException
|
30
30
|
false
|
@@ -36,7 +36,7 @@ module Rsh
|
|
36
36
|
|
37
37
|
def remove_file remote_file_path
|
38
38
|
remote do |ssh, sftp|
|
39
|
-
sftp.remove! remote_file_path
|
39
|
+
sftp.remove! fix_path(remote_file_path)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -82,17 +82,31 @@ module Rsh
|
|
82
82
|
|
83
83
|
def upload_directory from_local_path, to_remote_path
|
84
84
|
remote do |ssh, sftp|
|
85
|
-
sftp.upload! from_local_path, to_remote_path
|
85
|
+
sftp.upload! from_local_path, fix_path(to_remote_path)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
89
|
def download_directory from_remote_path, to_local_path
|
90
90
|
remote do |ssh, sftp|
|
91
|
-
sftp.download! from_remote_path, to_local_path, :recursive => true
|
91
|
+
sftp.download! fix_path(from_remote_path), to_local_path, :recursive => true
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
95
|
protected
|
96
|
+
def fix_path path
|
97
|
+
path.sub(/^\~/, home)
|
98
|
+
end
|
99
|
+
|
100
|
+
def home
|
101
|
+
unless @home
|
102
|
+
command = 'cd ~; pwd'
|
103
|
+
code, stdout, stderr = exec command
|
104
|
+
raise "can't execute '#{command}'!" unless code == 0
|
105
|
+
@home = stdout.gsub("\n", '')
|
106
|
+
end
|
107
|
+
@home
|
108
|
+
end
|
109
|
+
|
96
110
|
# taken from here http://stackoverflow.com/questions/3386233/how-to-get-exit-status-with-rubys-netssh-library/3386375#3386375
|
97
111
|
def hacked_exec!(ssh, command, &block)
|
98
112
|
stdout_data = ""
|
data/readme.md
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
-
# Tiny wrapper over Net::SSH
|
1
|
+
# Rsh - Tiny wrapper over Net::SSH/SFTP
|
2
2
|
|
3
3
|
Because they are too hard to use and have terrible API design.
|
4
4
|
|
5
5
|
box = Rsh::Box.new host: 'webapp.com', ssh: {user: 'root', password: 'secret'}
|
6
6
|
|
7
|
-
stdout = box.bash 'ls /'
|
8
|
-
code, stdout, stderr = box.exec 'ls /'
|
9
|
-
|
10
7
|
box.upload_directory '/my_project', '/apps/my_project'
|
11
8
|
box.bash 'nohup /apps/my_project/server_start'
|
12
9
|
|
@@ -14,6 +11,49 @@ Honestly my wrapper also not very good. I would like to make API looks like the
|
|
14
11
|
but it requires a lots of time, maybe I'll do it later.
|
15
12
|
So, for now it's just a small wrapper to do ssh/io operations not so painfull.
|
16
13
|
|
14
|
+
# Ros - Small rake addon for configuration/depoyment management and automation
|
15
|
+
|
16
|
+
It may be **usefull if Your claster has about 1-10 boxes**, and tools like Chef, Puppet, Capistrano are too complex and proprietary for your needs.
|
17
|
+
**It's extremely easy**, there are only 3 methods.
|
18
|
+
|
19
|
+
Define your packages, they are just rake tasks, so you probably know how to work with them:
|
20
|
+
|
21
|
+
namespace :os do
|
22
|
+
package :ruby do
|
23
|
+
applied?{|box| box.has_mark? :ruby}
|
24
|
+
apply do |box|
|
25
|
+
box.bash 'apt-get install ruby'
|
26
|
+
box.mark :ruby
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
package :rails => :ruby do
|
31
|
+
applied?{|box| box.has_mark? :rails}
|
32
|
+
apply do |box|
|
33
|
+
box.bash 'gem install rails'
|
34
|
+
box.mark :rails
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Define to what it should be applied:
|
40
|
+
|
41
|
+
def each_box &b
|
42
|
+
host = ENV['host'] || raise(":host not defined!")
|
43
|
+
box = Rsh::Box.new host: host, ssh: {user: 'root', password: 'secret'}
|
44
|
+
b.call box
|
45
|
+
end
|
46
|
+
|
47
|
+
Run it:
|
48
|
+
|
49
|
+
$ rake os:rails host=webapp.com
|
50
|
+
|
51
|
+
**You can use it also for deployment**, exactly the same way, configure it the way you like, it's just rake
|
52
|
+
tasks. And by the way, the *box.mark ...* is just an example check, you can use anything there.
|
53
|
+
|
54
|
+
It checks if the package already has been applied to box, so you can evolve your configuration and apply
|
55
|
+
it multiple times, it will apply only missing packages (or drop the *applied?* clause and it will be applied every run).
|
56
|
+
|
17
57
|
## TODO
|
18
58
|
|
19
59
|
- introduce Entity/Dir/File (the same as in Rush)
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Alexey Petrushin
|
@@ -30,6 +30,9 @@ files:
|
|
30
30
|
- Rakefile
|
31
31
|
- readme.md
|
32
32
|
- lib/old/ssh.rb
|
33
|
+
- lib/ros/rake.rb
|
34
|
+
- lib/ros/ros.rb
|
35
|
+
- lib/ros.rb
|
33
36
|
- lib/rsh/box.rb
|
34
37
|
- lib/rsh/drivers/abstract.rb
|
35
38
|
- lib/rsh/drivers/local.rb
|
@@ -79,6 +82,6 @@ rubyforge_project:
|
|
79
82
|
rubygems_version: 1.3.7
|
80
83
|
signing_key:
|
81
84
|
specification_version: 3
|
82
|
-
summary: Tiny wrapper over Net::SSH
|
85
|
+
summary: Tiny wrapper over Net::SSH/SFTP + small rake addon for cluster configuration management
|
83
86
|
test_files: []
|
84
87
|
|