jssh 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 802cfe834425216c50891414dec0f5a71b4c6498
4
- data.tar.gz: bca4531307cf24e4c6b654cd7c0a791b0acf8672
3
+ metadata.gz: dd8ac63db606331d0c105e6e284e684a31634683
4
+ data.tar.gz: e4033249bf64dd46edf79457b33397e1a9039b40
5
5
  SHA512:
6
- metadata.gz: 4e7e49858f77e2d1d164d257a1197be768bbab91090a4650dbe811663c9b9d8b0bb944f6f16b268654b77f913bd399dd19b6bfc27b5b56a9d472fd226a82413c
7
- data.tar.gz: dadbd6e0b570a80dd86568bbd5faccd83a30258a57a086333e5cb57358de33864b4938a418cbd8f8aee22c9df1e4503991bc8306529706ae44328527db03d648
6
+ metadata.gz: 593a5f5473b552ea2e9e350abbbf4a6b84570fa9f6de8cd540ced58c5718a76218078cfd574b03bac1758645f992e5ecab2569cfbba476ea597c19acb211d042
7
+ data.tar.gz: bff5756a0b8b6431585bd63a95bc9c9788f7d6193ed254a2b513c23de80597ade2882e3a5adb8de7168035b1d07cf651e32f3f3475a60868e1fb1e4dcf9b27f2
data/bin/jssh CHANGED
@@ -2,42 +2,10 @@
2
2
  require 'net/ssh'
3
3
  require 'optparse'
4
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
5
+ require "jssh"
38
6
 
39
7
  options = {}
40
- OptionParser.new do |opts|
8
+ op=OptionParser.new do |opts|
41
9
  opts.banner = "Usage: jssh [options]"
42
10
  opts.on("-f file","--hostfile file", "host file, every host occupy a line") do |v|
43
11
  options[:hostfile] = v
@@ -61,6 +29,9 @@ OptionParser.new do |opts|
61
29
  opts.on("-b","--break", "pause after first operation") do |v|
62
30
  options[:pause] = v
63
31
  end
32
+ opts.on("-g gsize","--groupsize gsize",OptionParser::OctalInteger, "The size of parallel group, default is 10") do |v|
33
+ options[:gsize] = v
34
+ end
64
35
  opts.on("-c cmdfile","--cmdfile cmdfile", "script path") do |v|
65
36
  options[:cmdfile] = v
66
37
  unless File.exists? v
@@ -68,6 +39,9 @@ OptionParser.new do |opts|
68
39
  exit
69
40
  end
70
41
  end
42
+ opts.on("-o outputfile","--output outputfile", "output file") do |v|
43
+ options[:output] = v
44
+ end
71
45
  opts.on("--help", "help") do |v|
72
46
  puts opts
73
47
  exit
@@ -75,7 +49,12 @@ OptionParser.new do |opts|
75
49
  opts.on("--debug", "debug inputs") do |v|
76
50
  options[:debug]=v
77
51
  end
78
- end.parse!
52
+ end
53
+ begin op.parse!
54
+ rescue => e
55
+ puts e.to_s.to_red
56
+ exit
57
+ end
79
58
 
80
59
  # If neither the rsa file or password specified, go get rsa file in home directory
81
60
  unless options[:key] || options[:password]
@@ -100,75 +79,9 @@ if options[:debug]
100
79
  exit
101
80
  end
102
81
 
103
- lambda{puts "No command or command file specify";exit}.call unless options[:cmdfile] || options[:command]
104
- lambda{puts "Please specify the user";exit}.call unless options[:user]
105
- lambda{puts "Please specify the rsa file or password";exit}.call unless options[:key] || options[:password]
106
-
107
- class Jssh
108
- attr_accessor :hosts,:user, :auth_cfg, :cmd, :printer
109
-
110
- def initialize
111
- @auth_cfg={}
112
- self.printer=:on
113
- @queue=Queue.new
114
- end
115
- def messages
116
- @queue
117
- end
118
-
119
- def go(from=0,len=nil)
120
- len||=self.hosts.size
121
- to=from+len-1
122
- password=self.auth_cfg[:password]
123
- keys=[self.auth_cfg[:key]].reject{|x| x.nil?}
124
- self.hosts[from..to].each_with_index do |host,i|
125
- result=""
126
- begin
127
- Net::SSH.start(host,self.user,:keys=>keys,:password=>password) do |ssh|
128
- result=ssh.exec!(self.cmd)
129
- end
130
- rescue=>e
131
- result=e.to_s
132
- end
133
- yield host,result if block_given?
134
- end
135
- end
136
- def execute(from=0,len=nil,group_size=10)
137
- pr=start_printer(self)
138
- threads=[]
139
- len||=self.hosts.size
140
- to=from+len-1
141
- divider(self.hosts[from..to].size,group_size) do |df,dt|
142
- threads<<Thread.new(self,from+df,from+dt) do |rssh,f,t|
143
- rssh.go(f,t) do |h,r|
144
- output=("="*20+h+"="*20).to_yellow+"\n"+r
145
- rssh.messages.push output
146
- end
147
- end
148
- end
149
- threads.each{|t| t.join}
150
- loop{ break if self.messages.size==0 } if self.printer
151
- Thread.kill pr
152
- end
153
-
154
- private
155
- def start_printer(jssh)
156
- Thread.new(jssh) do |rssh|
157
- while true
158
- puts rssh.messages.pop if rssh.printer
159
- end
160
- end
161
- end
162
- def divider(total,gsize)
163
- gcnt=total/gsize
164
- gcnt=gcnt+1 if total%gsize!=0
165
- gcnt.times do |i|
166
- from,len=i*gsize,gsize
167
- len=total%gsize if i==gcnt-1
168
- yield from,len
169
- end
170
- end
171
- end
82
+ lambda{puts "No command or command file specify".to_red;exit}.call unless options[:cmdfile] || options[:command]
83
+ lambda{puts "Please specify the user".to_red;exit}.call unless options[:user]
84
+ lambda{puts "Please specify the rsa file or password".to_red;exit}.call unless options[:key] || options[:password]
172
85
 
173
86
  rs=Jssh.new
174
87
  if options[:hostfile]
@@ -176,6 +89,9 @@ if options[:hostfile]
176
89
  else
177
90
  orig_hosts=options[:hostlist].split(",")
178
91
  end
92
+
93
+ rs.printer=Printer.new(FileExecutor.new(options[:output])) if options[:output]
94
+
179
95
  rs.user=options[:user]
180
96
  rs.auth_cfg[:password]=options[:password]
181
97
  rs.auth_cfg[:key]=options[:key]
@@ -190,6 +106,7 @@ unless options[:pause]
190
106
  puts "Finished!".to_green
191
107
  exit
192
108
  end
109
+
193
110
  rs.hosts=orig_hosts.take 1
194
111
  rs.execute
195
112
  puts "Now the operations on the first host is completed, we're going to it for a check.".to_yellow
@@ -212,7 +129,10 @@ print "Continue to finish all the left operations by parallel(p) or serial(s), [
212
129
  ans=$stdin.gets.chomp
213
130
  rs.hosts=orig_hosts[1..-1]
214
131
  if ans.downcase=='p'
215
- rs.execute
132
+ options[:gsize]= rs.hosts.size/100 if options[:gsize].nil? || rs.hosts.size/options[:gsize]>100 || options[:gsize]<1
133
+ gs=options[:gsize]==0 ? 1 : options[:gsize]
134
+ rs.printer.instant=false
135
+ rs.execute 0,nil,gs
216
136
  else
217
137
  rs.execute 0,nil,rs.hosts.size
218
138
  end
data/lib/jssh.rb CHANGED
@@ -1,5 +1,74 @@
1
1
  require "jssh/version"
2
+ require "jssh/printer"
3
+ require 'jssh/string'
2
4
 
3
- module Jssh
4
- # Your code goes here...
5
+ class Jssh
6
+ attr_accessor :hosts,:user, :auth_cfg, :cmd, :printer
7
+
8
+ def initialize
9
+ @auth_cfg={}
10
+ self.printer=Printer.new(StdoutExecutor.new)
11
+ @queue=Queue.new
12
+ end
13
+ def messages
14
+ @queue
15
+ end
16
+
17
+ def go(from=0,len=nil)
18
+ len||=self.hosts.size
19
+ to=from+len-1
20
+ password=self.auth_cfg[:password]
21
+ keys=[self.auth_cfg[:key]].reject{|x| x.nil?}
22
+ self.hosts[from..to].each_with_index do |host,i|
23
+ begin
24
+ Net::SSH.start(host,self.user,:keys=>keys,:password=>password) do |ssh|
25
+ result=ssh.exec!(self.cmd) || ''
26
+ ssh.exec!(self.cmd) do |ch,stream,data|
27
+ data||=''
28
+ yield host,data,false if block_given?
29
+ end
30
+ end
31
+ rescue=>e
32
+ result=e.to_s
33
+ end
34
+ result||=''
35
+ yield host,result,true if block_given?
36
+ end
37
+ end
38
+ def execute(from=0,len=nil,group_size=1)
39
+ pr=start_printer(self)
40
+ threads=[]
41
+ len||=self.hosts.size
42
+ to=from+len-1
43
+ divider(self.hosts[from..to].size,group_size) do |df,dt|
44
+ threads<<Thread.new(self,from+df,from+dt) do |rssh,f,t|
45
+ rssh.go(f,t) do |h,r,over|
46
+ rssh.messages.push({'host'=>h,'content'=>r,'finished'=>over})
47
+ end
48
+ end
49
+ end
50
+ threads.each{|t| t.join}
51
+ loop{ break if self.printer.finished? }
52
+ Thread.kill pr
53
+ end
54
+
55
+ private
56
+ def start_printer(jssh)
57
+ jssh.printer.submit_jobs(jssh.hosts)
58
+ Thread.new(jssh) do |rssh|
59
+ while true
60
+ data=rssh.messages.pop
61
+ rssh.printer.print data['host'],data['content'],data['finished']
62
+ end
63
+ end
64
+ end
65
+ def divider(total,gsize)
66
+ gcnt=total/gsize
67
+ gcnt=gcnt+1 if total%gsize!=0
68
+ gcnt.times do |i|
69
+ from,len=i*gsize,gsize
70
+ len=total%gsize if i==gcnt-1 && total%gsize!=0
71
+ yield from,len
72
+ end
73
+ end
5
74
  end
@@ -0,0 +1,45 @@
1
+ class Printer
2
+ attr_accessor :instant
3
+ def initialize(executor)
4
+ self.instant=true
5
+ @executor=executor
6
+ end
7
+ def submit_jobs(hosts)
8
+ @memo={}
9
+ hosts.each{|j| @memo[j]=nil }
10
+ end
11
+ def print(host,content,is_end)
12
+ if self.instant
13
+ lambda{ @executor.puts ("="*20+host+"="*20).to_yellow; @memo[host]='' }.call unless @memo[host]
14
+ @executor.puts content if content
15
+ @memo.delete host if is_end
16
+ else
17
+ @memo[host]=("="*20+host+"="*20).to_yellow+"\n" unless @memo[host]
18
+ @memo[host] << content if content
19
+ lambda{ @executor.puts @memo[host]; @memo.delete host }.call if is_end
20
+ end
21
+ end
22
+ def finished?
23
+ @memo.empty?
24
+ end
25
+ end
26
+
27
+ class StdoutExecutor
28
+ def puts(str)
29
+ $stdout.puts str
30
+ end
31
+ end
32
+ class FileExecutor
33
+ def initialize(filename)
34
+ @file=File.open(filename,'a')
35
+ end
36
+ def puts(str)
37
+ @file.puts str
38
+ end
39
+ end
40
+ class NullExecutor
41
+ def puts(str)
42
+ #Do nothing
43
+ end
44
+ end
45
+
@@ -0,0 +1,23 @@
1
+ class String
2
+ def to_black
3
+ "\033[30m#{self}\033[0m"
4
+ end
5
+ def to_red
6
+ "\033[31m#{self}\033[0m"
7
+ end
8
+ def to_yellow
9
+ "\033[33m#{self}\033[0m"
10
+ end
11
+ def to_blue
12
+ "\033[34m#{self}\033[0m"
13
+ end
14
+ def to_white
15
+ "\033[37m#{self}\033[0m"
16
+ end
17
+ def to_green
18
+ "\033[32m#{self}\033[0m"
19
+ end
20
+ def to_cyan
21
+ "\033[36m#{self}\033[0m"
22
+ end
23
+ end
data/lib/jssh/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module Jssh
2
- VERSION = "0.0.2"
1
+ class Jssh
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - qjpcpu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-03 00:00:00.000000000 Z
11
+ date: 2014-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -68,6 +68,8 @@ files:
68
68
  - bin/jssh
69
69
  - jssh.gemspec
70
70
  - lib/jssh.rb
71
+ - lib/jssh/printer.rb
72
+ - lib/jssh/string.rb
71
73
  - lib/jssh/version.rb
72
74
  homepage: https://github.com/qjpcpu/jssh
73
75
  licenses: