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 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: Make local #run and #exec work
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.
@@ -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
@@ -2,6 +2,12 @@ require 'fileutils'
2
2
 
3
3
  module ThorSsh
4
4
  class LocalFile
5
+ attr_reader :base
6
+
7
+ def initialize(base)
8
+ @base = base
9
+ end
10
+
5
11
  def exists?(path)
6
12
  File.exists?(path)
7
13
  end
@@ -2,6 +2,12 @@ require 'popen4'
2
2
 
3
3
  module ThorSsh
4
4
  class LocalServer
5
+ attr_reader :base
6
+
7
+ def initialize(base)
8
+ @base = base
9
+ end
10
+
5
11
  def run_with_codes(command)
6
12
  # pid, stdin, stdout, stderr = Open4::popen4(command)
7
13
  # ignored, status = Process::waitpid2 pid
@@ -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 connection.exec!(command)
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
- data = nil
66
- connection.sftp.file.open(path, "rb") do |f|
67
- data = f.read
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 run_with_codes(command)
66
+ return results
48
67
  else
49
- return connection.exec!(command)
68
+ return results.first
50
69
  end
51
70
  end
52
71
 
@@ -1,3 +1,3 @@
1
1
  module ThorSsh
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
data/spec/actions_spec.rb CHANGED
@@ -182,7 +182,6 @@ describe ThorSsh do
182
182
  stdout, stderr, exit_code, exit_signal = @local_test.exec('true', true)
183
183
  exit_code.should == 0
184
184
  end
185
-
186
185
  end
187
186
 
188
187
 
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.7
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-25 00:00:00.000000000 Z
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: 1900233715508289127
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: 1900233715508289127
217
+ hash: 1762345843444454679
218
218
  requirements: []
219
219
  rubyforge_project:
220
220
  rubygems_version: 1.8.22