thor-ssh 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -1
- data/lib/thor-ssh/actions.rb +26 -4
- data/lib/thor-ssh/local_file.rb +6 -0
- data/lib/thor-ssh/local_server.rb +6 -0
- data/lib/thor-ssh/remote_file.rb +16 -50
- data/lib/thor-ssh/remote_server.rb +22 -3
- data/lib/thor-ssh/version.rb +1 -1
- data/spec/actions_spec.rb +0 -1
- metadata +4 -4
data/README.md
CHANGED
@@ -4,6 +4,9 @@ ThorSsh takes thor and allows it to run from local to remote.
|
|
4
4
|
It assumes that the sources are always local and the remotes
|
5
5
|
are always remote.
|
6
6
|
|
7
|
+
## ThorSsh Assumptions
|
8
|
+
For running as_user('other_user') the assumption is that your connection is logged in either as 1) root, or 2) a user who can sudo to root
|
9
|
+
|
7
10
|
## Use
|
8
11
|
gem 'thor-ssh'
|
9
12
|
|
@@ -24,7 +27,7 @@ This is still a work in progress. The main issue is that calling #inside or any
|
|
24
27
|
TODO: Get #inside working
|
25
28
|
TODO: Add other features needed for provisioning system
|
26
29
|
TODO: Make way to copy remote to remote
|
27
|
-
TODO:
|
30
|
+
TODO: Update method blacklist
|
28
31
|
|
29
32
|
## Running Tests
|
30
33
|
The test run through vagrant, which seemed logical since we want to test ssh stuff.
|
data/lib/thor-ssh/actions.rb
CHANGED
@@ -26,9 +26,9 @@ module ThorSsh
|
|
26
26
|
# it is assumed to be local and a normal File class is returned
|
27
27
|
def destination_files
|
28
28
|
if self.destination_connection
|
29
|
-
return @destination_files ||= RemoteFile.new(self.destination_connection)
|
29
|
+
return @destination_files ||= RemoteFile.new(self, self.destination_connection)
|
30
30
|
else
|
31
|
-
return @destination_files ||= LocalFile.new
|
31
|
+
return @destination_files ||= LocalFile.new(self)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -37,12 +37,34 @@ module ThorSsh
|
|
37
37
|
# the destination.
|
38
38
|
def destination_server
|
39
39
|
if self.destination_connection
|
40
|
-
return @destination_server ||= RemoteServer.new(self.destination_connection)
|
40
|
+
return @destination_server ||= RemoteServer.new(self, self.destination_connection)
|
41
41
|
else
|
42
|
-
return @destination_server ||= LocalServer.new
|
42
|
+
return @destination_server ||= LocalServer.new(self)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
|
47
|
+
# As user takes a block and runs the code inside the block as the
|
48
|
+
# specified user. All actions are run as the user
|
49
|
+
#
|
50
|
+
# === Parameters
|
51
|
+
# username<String>:: Who to run as
|
52
|
+
# options<String>:: A hash of options for how to get to this user
|
53
|
+
#
|
54
|
+
# === Options
|
55
|
+
# :shell - Boolean, should this be invoked in the shell for the user
|
56
|
+
def as_user(username, options={})
|
57
|
+
old_run_as_user = @run_as_user
|
58
|
+
@run_as_user = username
|
59
|
+
yield
|
60
|
+
@run_as_user = old_run_as_user
|
61
|
+
end
|
62
|
+
|
63
|
+
# The user commands should be run as as the moment
|
64
|
+
def run_as_user
|
65
|
+
@run_as_user
|
66
|
+
end
|
67
|
+
|
46
68
|
def inside(dir='', config={}, &block)
|
47
69
|
raise "inside is not implemented in thor-ssh, please use full paths"
|
48
70
|
end
|
data/lib/thor-ssh/local_file.rb
CHANGED
data/lib/thor-ssh/remote_file.rb
CHANGED
@@ -2,29 +2,13 @@ require 'net/ssh'
|
|
2
2
|
require 'net/sftp'
|
3
3
|
require 'stringio'
|
4
4
|
|
5
|
-
module ThorSsh
|
6
|
-
class RemoteFileWriter
|
7
|
-
def initialize(connection, file)
|
8
|
-
@connection = connection
|
9
|
-
@file = file
|
10
|
-
@offset = 0
|
11
|
-
end
|
12
|
-
|
13
|
-
def write(data)
|
14
|
-
puts "WRITE: #{data.size} @ #{@offset}"
|
15
|
-
# io = StringIO.new(data)
|
16
|
-
@connection.sftp.write!(@file, @offset, data)
|
17
|
-
|
18
|
-
puts "WROTE1"
|
19
|
-
|
20
|
-
@offset += data.size
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
5
|
+
module ThorSsh
|
24
6
|
class RemoteFile
|
25
7
|
attr_reader :connection
|
8
|
+
attr_reader :base
|
26
9
|
|
27
|
-
def initialize(connection)
|
10
|
+
def initialize(base, connection)
|
11
|
+
@base = base
|
28
12
|
@connection = connection
|
29
13
|
end
|
30
14
|
|
@@ -39,7 +23,7 @@ module ThorSsh
|
|
39
23
|
end
|
40
24
|
|
41
25
|
def run(command)
|
42
|
-
return
|
26
|
+
return base.exec(command)
|
43
27
|
end
|
44
28
|
|
45
29
|
# Creates the directory at the path on the remote server
|
@@ -62,45 +46,27 @@ module ThorSsh
|
|
62
46
|
end
|
63
47
|
|
64
48
|
def binread(path)
|
65
|
-
|
66
|
-
|
67
|
-
data =
|
49
|
+
# If we first logged in as the running user
|
50
|
+
if base.destination_server.running_as_current_user?
|
51
|
+
data = nil
|
52
|
+
connection.sftp.file.open(path, "rb") do |f|
|
53
|
+
data = f.read
|
54
|
+
end
|
55
|
+
else
|
56
|
+
# We just run this as root, when reading we don't need to go back
|
57
|
+
# down to the user
|
58
|
+
data = @remote_test.destination_server.run("cat \"#{path}\"")
|
68
59
|
end
|
69
|
-
|
60
|
+
|
70
61
|
return data
|
71
62
|
end
|
72
63
|
|
73
64
|
# TODO: we should just move this to a more standard thing
|
74
65
|
def binwrite(path, data)
|
75
|
-
# puts "DATA: #{data.size}"
|
76
|
-
# file = connection.sftp.open!(path, 'wb')
|
77
|
-
#
|
78
|
-
# # Write
|
79
|
-
# connection.sftp.write!(file, 0, data)
|
80
|
-
#
|
81
|
-
# # Close
|
82
|
-
# connection.sftp.close!(file)
|
83
|
-
|
84
66
|
io = StringIO.new(data)
|
85
67
|
connection.sftp.upload!(io, path)
|
86
68
|
end
|
87
69
|
|
88
|
-
def open(file_name, mode, &block)
|
89
|
-
# Open file
|
90
|
-
file = connection.sftp.open(file_name, 'wb', &method(:file_opened))#, {:chunk_size => 4096})
|
91
|
-
|
92
|
-
file_writer = RemoteFileWriter.new(connection, file)
|
93
|
-
|
94
|
-
yield(file_writer)
|
95
|
-
|
96
|
-
# Close
|
97
|
-
connection.sftp.close(file)
|
98
|
-
|
99
|
-
# , {:chunk_size => 4096}
|
100
|
-
# connection.sftp.file.open(file_name, mode, &block)
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
70
|
def chmod(mode, file_name)
|
105
71
|
if mode.is_a?(Integer)
|
106
72
|
# Mode is an integer, convert to octal
|
@@ -4,8 +4,10 @@ require 'net/sftp'
|
|
4
4
|
module ThorSsh
|
5
5
|
class RemoteServer
|
6
6
|
attr_reader :connection
|
7
|
+
attr_reader :base
|
7
8
|
|
8
|
-
def initialize(connection)
|
9
|
+
def initialize(base, connection)
|
10
|
+
@base = base
|
9
11
|
@connection = connection
|
10
12
|
end
|
11
13
|
|
@@ -41,12 +43,29 @@ module ThorSsh
|
|
41
43
|
|
42
44
|
return stdout_data, stderr_data, exit_code, exit_signal
|
43
45
|
end
|
46
|
+
|
47
|
+
def running_as_current_user?
|
48
|
+
base.run_as_user && connection.options[:user] != base.run_as_user
|
49
|
+
end
|
44
50
|
|
45
51
|
def run(command, with_codes=false)
|
52
|
+
if running_as_current_user?
|
53
|
+
# We need to change to a different user
|
54
|
+
if base.run_as_user == 'root'
|
55
|
+
# We need to go up to root
|
56
|
+
command = "sudo #{command}"
|
57
|
+
else
|
58
|
+
# We need to go up to root, then down to this user
|
59
|
+
# This involves running sudo (to go up to root), then running
|
60
|
+
# sudo again as the new user, then running the command
|
61
|
+
command = "sudo sudo -u #{base.run_as_user} #{command}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
results = run_with_codes(command)
|
46
65
|
if with_codes
|
47
|
-
return
|
66
|
+
return results
|
48
67
|
else
|
49
|
-
return
|
68
|
+
return results.first
|
50
69
|
end
|
51
70
|
end
|
52
71
|
|
data/lib/thor-ssh/version.rb
CHANGED
data/spec/actions_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thor-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
@@ -205,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
205
205
|
version: '0'
|
206
206
|
segments:
|
207
207
|
- 0
|
208
|
-
hash:
|
208
|
+
hash: 1762345843444454679
|
209
209
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
210
210
|
none: false
|
211
211
|
requirements:
|
@@ -214,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
214
|
version: '0'
|
215
215
|
segments:
|
216
216
|
- 0
|
217
|
-
hash:
|
217
|
+
hash: 1762345843444454679
|
218
218
|
requirements: []
|
219
219
|
rubyforge_project:
|
220
220
|
rubygems_version: 1.8.22
|