nissh 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3101450e4df71a8c85bfe1291a2afc908548fbb2
4
+ data.tar.gz: 09667cd03ed47386c30ddfe64880c285de8a7fec
5
+ SHA512:
6
+ metadata.gz: 9aaf6594647384a86aa6e6640d3d84d6c0b29642d764eb8b0fcf09756065251469eac7b0b08b36d4e0eccf0ad7718feb8340e233d2fa9b3895adea16c0b0ea4c
7
+ data.tar.gz: 3441ccf451bf16810a3f46d29ca991d01ee8d154b480087b21d9bfe1d0aa9a0f7c44e96ee8dad2b489f4e85ec79fa2747eb783abcba1a04ccba18b6e5d023dcd
data/lib/nissh.rb ADDED
@@ -0,0 +1 @@
1
+ require 'nissh/session'
@@ -0,0 +1,24 @@
1
+ module Nissh
2
+ class Response
3
+
4
+ attr_accessor :stdout, :stderr, :exit_code, :exit_signal, :command
5
+
6
+ def initialize
7
+ reset_output!
8
+ end
9
+
10
+ def success?
11
+ exit_code == 0
12
+ end
13
+
14
+ def output
15
+ "#{stdout}\n#{stderr}"
16
+ end
17
+
18
+ def reset_output!
19
+ @stdout = ""
20
+ @stderr = ""
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,114 @@
1
+ require 'net/ssh'
2
+ require 'nissh/response'
3
+
4
+ module Nissh
5
+ class Session
6
+
7
+ class CommandExecutionFailed < StandardError; end
8
+
9
+ class << self
10
+ attr_accessor :logger
11
+ end
12
+
13
+ attr_reader :session
14
+ attr_accessor :sudo_password
15
+
16
+ def initialize(*args)
17
+ if args.first.is_a?(Net::SSH::Connection::Session)
18
+ @session = args.first
19
+ else
20
+ @session = Net::SSH.start(*args)
21
+ end
22
+ end
23
+
24
+ def execute!(commands, options = {})
25
+ unless commands.is_a?(Array)
26
+ commands = [commands]
27
+ end
28
+
29
+ if options[:sudo]
30
+ commands = commands.map do |command|
31
+ "sudo --stdin #{command}"
32
+ end
33
+ end
34
+
35
+ command = commands.join(' && ')
36
+ log :info, "\e[44;37m=> #{command}\e[0m"
37
+
38
+ response = Nissh::Response.new
39
+ response.command = command
40
+ channel = @session.open_channel do |channel|
41
+ channel.exec(command) do |_, success|
42
+ raise CommandExecutionFailed, "Command \"#{command}\" was unable to execute" unless success
43
+ channel.on_data do |_,data|
44
+ response.stdout += data
45
+ log :debug, data.gsub(/[\r]/, ''), :tab => 4
46
+ end
47
+
48
+ channel.on_extended_data do |_,_,data|
49
+ response.stderr += data.gsub(/\r/, '')
50
+ log :warn, data, :tab => 4
51
+ if data =~ /^\[sudo\] password for/
52
+ password = options[:sudo].is_a?(String) ? options[:sudo] : self.sudo_password
53
+ channel.send_data "#{password}\n"
54
+ end
55
+ end
56
+
57
+ channel.on_request("exit-status") do |_,data|
58
+ response.exit_code = data.read_long
59
+ log :info, "\e[43;37m=> Exit status: #{response.exit_code}\e[0m"
60
+ end
61
+
62
+ channel.on_request("exit-signal") do |_, data|
63
+ response.exit_signal = data.read_long
64
+ end
65
+ end
66
+ end
67
+ channel.wait
68
+ response
69
+ end
70
+
71
+ def execute_with_timeout!(command, timeout = 30)
72
+ Timeout.timeout(timeout) do
73
+ execute!(command)
74
+ end
75
+ rescue Timeout::Error => e
76
+ response = Nissh::Response.new
77
+ response.exit_code -255
78
+ response.stderr = "Command did not finish executing within the allowed #{timeout} seconds."
79
+ response.command = command
80
+ response
81
+ end
82
+
83
+ def execute_with_success!(command, success_code = 0)
84
+ result = execute!(command)
85
+ if result.success?
86
+ result
87
+ else
88
+ false
89
+ end
90
+ end
91
+
92
+ def execute_with_exception!(command, success_code = 0)
93
+ result = execute!(command)
94
+ if result.exit_code == success_code
95
+ result
96
+ else
97
+ raise CommandExecutionFailed, result.output
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ def log(type, text, options = {})
104
+ if self.class.logger
105
+ prefix = "\e[45;37m[#{@session.transport.host}]\e[0m"
106
+ tabs = " " * (options[:tab] || 0)
107
+ text.split(/\n/).each do |line|
108
+ self.class.logger.send(type, prefix + tabs + line)
109
+ end
110
+ end
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,3 @@
1
+ module Nissh
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nissh
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Cooke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: net-ssh
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
27
+ description: A wrapper for net/ssh to make running commands more fun
28
+ email:
29
+ - me@adamcooke.io
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/nissh.rb
35
+ - lib/nissh/response.rb
36
+ - lib/nissh/session.rb
37
+ - lib/nissh/version.rb
38
+ homepage: https://github.com/adamcooke/nissh
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.4.5
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: A wrapper for net/ssh to make running commands more fun
62
+ test_files: []
63
+ has_rdoc: