jssh 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c537fc623582c56e6324e18cb8d6c18e496109b4
4
+ data.tar.gz: 3db80a7f5038a1a84de106ad96ef65e80027c5bc
5
+ SHA512:
6
+ metadata.gz: f9a9c26b683fa6f4fa4f1e98531f4bc0934497c7d8ed2cba3db7e146d512204cbfb16c27de9255b54da51a3cee2a6a8b550208989fd79f1cf1500fa20f7ff74f
7
+ data.tar.gz: 05e5cbd8b1e2ba7c541aae76e28aa4d7f58e4d8adec55069c4228d6024844520dbcc44589de2ae74f3e234d20eb1a0da522d95c7d1e82252ccf205bc8b8ca40c
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jssh.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Jssh
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'jssh'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install jssh
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/jssh/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,200 @@
1
+ #!/bin/env ruby
2
+ require 'net/ssh'
3
+ require 'optparse'
4
+ require 'yaml'
5
+
6
+ class String
7
+ def to_black
8
+ "\033[30m#{self}\033[0m"
9
+ end
10
+ def to_red
11
+ "\033[31m#{self}\033[0m"
12
+ end
13
+ def to_yellow
14
+ "\033[33m#{self}\033[0m"
15
+ end
16
+ def to_blue
17
+ "\033[34m#{self}\033[0m"
18
+ end
19
+ def to_white
20
+ "\033[37m#{self}\033[0m"
21
+ end
22
+ def to_green
23
+ "\033[32m#{self}\033[0m"
24
+ end
25
+ def to_cyan
26
+ "\033[36m#{self}\033[0m"
27
+ end
28
+ def to_magenta
29
+ "\033[35m#{self}\033[0m"
30
+ end
31
+ def to_bold
32
+ "\033[1m#{self}\033[0m"
33
+ end
34
+ def to_underline
35
+ "\033[4m#{self}\033[0m"
36
+ end
37
+ end
38
+
39
+ options = {}
40
+ OptionParser.new do |opts|
41
+ opts.banner = "Usage: jssh [options]"
42
+ opts.on("-f file","--hostfile file", "host file, every host occupy a line") do |v|
43
+ options[:hostfile] = v
44
+ unless File.exists? v
45
+ puts "host file doesn't exists!".to_red
46
+ exit
47
+ end
48
+ end
49
+ opts.on("-h hosts","--hosts hosts", "hosts list") do |v|
50
+ options[:hostlist] = v
51
+ end
52
+ opts.on("-u user","--user user", "user name") do |v|
53
+ options[:user] = v
54
+ end
55
+ opts.on("-p password","--password password", "password") do |v|
56
+ options[:password] = v
57
+ end
58
+ opts.on("-i keyfile", "the ssh id_rsa file") do |v|
59
+ options[:key] = v
60
+ end
61
+ opts.on("--nopause", "no pause for first operation") do |v|
62
+ options[:nopause] = v
63
+ end
64
+ opts.on("-c commands","--command commands", "commands") do |v|
65
+ options[:command] = v
66
+ end
67
+ opts.on("-C cmdfile","--cmdfile cmdfile", "script path") do |v|
68
+ options[:cmdfile] = v
69
+ unless File.exists? v
70
+ puts "command file doesn't exists!".to_red
71
+ exit
72
+ end
73
+ end
74
+ opts.on("--help", "help") do |v|
75
+ puts opts
76
+ exit
77
+ end
78
+ end.parse!
79
+ unless options[:key] || options[:password]
80
+ if File.exists? ENV['HOME']+"/.jsshrc"
81
+ config=YAML::load_file(ENV['HOME']+"/.jsshrc")
82
+ options[:key]||=config['keyfile'] if config['keyfile']
83
+ options[:user]||=config['user'] if config['user']
84
+ else
85
+ options[:key]||=ENV['HOME']+'/.ssh/id_rsa'
86
+ end
87
+ end
88
+ lambda{puts "No command or command file specify";exit}.call unless options[:cmdfile] || options[:command]
89
+ lambda{puts "Please specify the user";exit}.call unless options[:user]
90
+ lambda{puts "Please specify the rsa file or password";exit}.call unless options[:key] || options[:password]
91
+
92
+ class Jssh
93
+ attr_accessor :hosts,:user, :auth_cfg, :cmd, :printer
94
+
95
+ def initialize
96
+ @auth_cfg={}
97
+ self.printer=:on
98
+ @queue=Queue.new
99
+ Thread.new(self) do |rssh|
100
+ while true
101
+ puts rssh.messages.pop if rssh.printer
102
+ end
103
+ end
104
+ end
105
+ def messages
106
+ @queue
107
+ end
108
+ def go(from=0,len=nil)
109
+ len||=self.hosts.size
110
+ to=from+len-1
111
+ password=self.auth_cfg[:password]
112
+ keys=[self.auth_cfg[:key]].reject{|x| x.nil?}
113
+ self.hosts[from..to].each_with_index do |host,i|
114
+ result=""
115
+ begin
116
+ Net::SSH.start(host,self.user,:keys=>keys,:password=>password) do |ssh|
117
+ result=ssh.exec!(self.cmd)
118
+ end
119
+ rescue=>e
120
+ result=e.to_s
121
+ end
122
+ yield host,result if block_given?
123
+ end
124
+ end
125
+ def execute(from=0,len=nil,group_size=10)
126
+ threads=[]
127
+ len||=self.hosts.size
128
+ to=from+len-1
129
+ divider(self.hosts[from..to].size,group_size) do |df,dt|
130
+ threads<<Thread.new(self,from+df,from+dt) do |rssh,f,t|
131
+ rssh.go(f,t) do |h,r|
132
+ output="="*20+h+"="*20+"\n"+r
133
+ rssh.messages.push output
134
+ end
135
+ end
136
+ end
137
+ while threads.find{|t| t.alive? }
138
+ sleep 1
139
+ end
140
+ end
141
+
142
+ private
143
+ def divider(total,gsize)
144
+ gcnt=total/gsize
145
+ gcnt=gcnt+1 if total%gsize!=0
146
+ gcnt.times do |i|
147
+ from,len=i*gsize,gsize
148
+ len=total%gsize if i==gcnt-1
149
+ yield from,len
150
+ end
151
+ end
152
+ end
153
+
154
+ rs=Jssh.new
155
+ if options[:hostfile]
156
+ orig_hosts=File.read(options[:hostfile]).split("\n")
157
+ else
158
+ orig_hosts=options[:hostlist].split(",")
159
+ end
160
+ rs.user=options[:user]
161
+ rs.auth_cfg[:password]=options[:password]
162
+ rs.auth_cfg[:key]=options[:key]
163
+ if options[:cmdfile]
164
+ rs.cmd=File.read(options[:cmdfile])
165
+ else
166
+ rs.cmd=options[:command]
167
+ end
168
+ if options[:nopause]
169
+ rs.hosts=orig_hosts
170
+ rs.execute 0,nil,rs.hosts.size
171
+ puts "Finished!".to_green
172
+ exit
173
+ end
174
+ rs.hosts=orig_hosts.take 1
175
+ rs.execute
176
+ puts "Now the operations on the first host is completed, we're going to it for a check.".to_yellow
177
+ print "Press ENTER to automatic to login #{rs.hosts.first.to_red} ..."
178
+ gets
179
+ if options[:password]
180
+ login_to_first=%Q|expect -c 'spawn ssh #{rs.user}@#{rs.hosts.first}
181
+ expect {
182
+ "*(yes/no)?" { send "yes\r";exp_continue }
183
+ "*assword:" { send "#{options[:password]}\r" }
184
+ }
185
+ interact
186
+ '
187
+ |
188
+ else
189
+ login_to_first="ssh -i #{options[:key]} #{rs.user}@#{rs.hosts.first}"
190
+ end
191
+ system(login_to_first)
192
+ print "Continue to finish all the left operations by parallel(p) or serial(s), [p/s] ".to_yellow
193
+ ans=gets.chomp
194
+ rs.hosts=orig_hosts[1..-1]
195
+ if ans.downcase=='p'
196
+ rs.execute
197
+ else
198
+ rs.execute 0,nil,rs.hosts.size
199
+ end
200
+ puts 'Finished!'.to_green
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jssh/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jssh"
8
+ spec.version = Jssh::VERSION
9
+ spec.authors = ["qjpcpu"]
10
+ spec.email = ["qjpcpu@gmail.com"]
11
+ spec.summary = %q{Execute multiple ssh operation easily.}
12
+ spec.description = %q{Multiple ssh operations.}
13
+ spec.homepage = "https://github.com/qjpcpu/jssh"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_runtime_dependency "net-ssh"
24
+ end
@@ -0,0 +1,5 @@
1
+ require "jssh/version"
2
+
3
+ module Jssh
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,3 @@
1
+ module Jssh
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jssh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - qjpcpu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-ssh
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Multiple ssh operations.
56
+ email:
57
+ - qjpcpu@gmail.com
58
+ executables:
59
+ - jssh
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - bin/jssh
69
+ - jssh.gemspec
70
+ - lib/jssh.rb
71
+ - lib/jssh/version.rb
72
+ homepage: https://github.com/qjpcpu/jssh
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.2.2
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: Execute multiple ssh operation easily.
96
+ test_files: []