xlogin 0.9.0 → 0.9.2

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: 21cb559588f816c0f1497df58f3f3dfe819943e8
4
- data.tar.gz: f7742b32f267dddad2afa23cdd0a7928e2a6c589
3
+ metadata.gz: 7920c6bfed2e33fd3aa7e60128ae9b01b2464dec
4
+ data.tar.gz: 6304076fbb457c60020f8fd8875ea147bd162d85
5
5
  SHA512:
6
- metadata.gz: 92d5465fa016af9b0a93338c6826741d75fe153a1c0ad6fb567ee5a89a9e5f658e977d3112d99d17eb6644db33b358e3705c158f6a79238e99d8c54d609a2b7c
7
- data.tar.gz: afe1f174a3e785a8ee8d1d2bcc09d63478e804f1f698f8615611c95c8efa59ca84c2a77d88b0c197b1f6142a95d0aa1495fc379ce202528dad12ba9661742072
6
+ metadata.gz: e9a8f8cbf8ae3eed54beeca00efbbdaf080f98fea77f7c1064d1b904c6d9f2b58fa34e287b406d20327690cb2d01ba4d493f7b1d9da531cb3b7cd9628a3b8535
7
+ data.tar.gz: 03ee0f923e53ddc0f10fc7b37ddd7b20f279da1fe2bbb3db202aeffef6ba3c6b49d93f27c51aab095a2b24f0c7367ecc4d06f16e6df4f74134da7b81011ab9d3
data/lib/xlogin.rb CHANGED
@@ -27,11 +27,11 @@ module Xlogin
27
27
  end
28
28
 
29
29
  def list(*patterns)
30
- factory.list_info(*patterns)
30
+ factory.list_inventory(*patterns)
31
31
  end
32
32
 
33
33
  def get_pool(args, **opts, &block)
34
- pool = Xlogin::SessionPool.new(args, **opts)
34
+ pool = factory.build_pool(args, **opts)
35
35
 
36
36
  return pool unless block
37
37
  block.call(pool)
@@ -57,7 +57,7 @@ module Xlogin
57
57
  end
58
58
 
59
59
  def register(**args)
60
- factory.set_info(**args)
60
+ factory.set_inventory(**args)
61
61
  end
62
62
 
63
63
  def source(*source_files)
@@ -9,7 +9,7 @@ module Xlogin
9
9
  target_host = params.delete(:relay)
10
10
  return super(uri, **params) unless target_host
11
11
 
12
- target_info = Xlogin.factory.get_info(target_host)
12
+ target_info = Xlogin.factory.get_inventory(target_host)
13
13
  target_temp = Xlogin.factory.get_template(target_info[:type])
14
14
  target_uri = Addressable::URI.parse(target_info[:uri])
15
15
 
@@ -1,3 +1,4 @@
1
+ require 'addressable/uri'
1
2
  require 'singleton'
2
3
  require 'xlogin/template'
3
4
 
@@ -11,17 +12,16 @@ module Xlogin
11
12
  @templates = Hash.new
12
13
  end
13
14
 
14
- def set_info(**opts)
15
- name = opts[:name]
16
- return unless name
17
- @inventory[name] = (get_info(name) || {}).merge(opts)
15
+ def set_inventory(**opts)
16
+ return unless name = opts[:name]
17
+ @inventory[name] = (get_inventory(name) || {}).merge(opts)
18
18
  end
19
19
 
20
- def get_info(name)
20
+ def get_inventory(name)
21
21
  @inventory[name]
22
22
  end
23
23
 
24
- def list_info(*patterns)
24
+ def list_inventory(*patterns)
25
25
  return @inventory.values if patterns.empty?
26
26
 
27
27
  values = patterns.map do |pattern|
@@ -47,16 +47,29 @@ module Xlogin
47
47
  @templates.keys
48
48
  end
49
49
 
50
- def build(type:, uri:, **opts)
50
+ def build(type:, **opts)
51
51
  template = get_template(type)
52
- template.build(uri, **opts)
52
+ if opts[:uri]
53
+ template.build(opts[:uri], **opts)
54
+ else
55
+ scheme = opts[:scheme]
56
+ address = opts.values_at(:host, :port).compact.join(':')
57
+ userinfo = opts[:userinfo]
58
+ userinfo ||= opts.values_at(:username, :password).compact.join(':')
59
+
60
+ template.build("#{scheme}://" + [userinfo, address].compact.join('@'), **opts)
61
+ end
53
62
  end
54
63
 
55
- def build_from_hostname(hostname, **opts)
56
- hostinfo = get_info(hostname)
57
- raise SessionError.new("Host not found: '#{hostname}'") unless hostinfo
64
+ def build_from_hostname(args, **opts)
65
+ hostinfo = get_inventory(args)
66
+ raise SessionError.new("Host not found: '#{args}'") unless hostinfo
67
+
68
+ build(hostinfo.merge(name: args, **opts))
69
+ end
58
70
 
59
- build(hostinfo.merge(name: hostname, **opts))
71
+ def build_pool(args, **opts)
72
+ Xlogin::SessionPool.new(args, **opts)
60
73
  end
61
74
 
62
75
  end
@@ -23,7 +23,7 @@ module Xlogin
23
23
 
24
24
  raise SessionError.new("Invalid URI - '#{uri}'") unless @host && @port
25
25
 
26
- @name = opts.delete(:name) || @host
26
+ @name = opts[:name] || @host
27
27
  @config = OpenStruct.new(opts)
28
28
  @template = template
29
29
  @username, @password = uri.userinfo.to_s.split(':')
@@ -31,10 +31,8 @@ module Xlogin
31
31
  ssh_tunnel(@config.via) if @config.via
32
32
  max_retry = @config.retry || 1
33
33
 
34
- @mutex = Mutex.new
35
- @closed = false
36
- @output_logs = [@config.log]
37
- @output_loggers = build_loggers
34
+ @mutex = Mutex.new
35
+ @loggers = [@config.log].flatten.uniq.reduce({}) { |a, e| a.merge(e => build_logger(e)) }
38
36
 
39
37
  begin
40
38
  super(
@@ -48,7 +46,6 @@ module Xlogin
48
46
  )
49
47
  rescue => e
50
48
  retry if (max_retry -= 1) > 0
51
- @closed = true
52
49
  raise e
53
50
  end
54
51
  end
@@ -61,71 +58,65 @@ module Xlogin
61
58
  cmd('').lines.last.chomp
62
59
  end
63
60
 
64
- def cmd(*args, &block)
65
- @mutex.synchronize { super(*args, &block) }
61
+ def duplicate
62
+ @template.build(@uri, **@config.to_h)
66
63
  end
67
64
 
68
65
  def puts(*args, &block)
69
- args = instance_exec(*args, &@template.interrupt) if @template.interrupt
66
+ args = [instance_exec(*args, &@template.interrupt)].flatten if @template.interrupt
70
67
  super(*args, &block)
71
68
  end
72
69
 
73
70
  def waitfor(*args, &block)
74
- args << Regexp.union(*@template.prompt.map(&:first)) if args.empty?
75
- line = super(*args) do |recv|
76
- block.call(recv) if block
77
- output_log(recv)
78
- end
79
-
80
- _, process = @template.prompt.find { |r, p| r =~ line && p }
81
- if process
82
- instance_eval(&process)
83
- line += waitfor(*args, &block)
84
- end
85
- rescue EOFError
86
- @closed = true
87
- ensure
88
- return line
71
+ @mutex.synchronize { _waitfor(*args, &block) }
89
72
  end
90
73
 
91
74
  def close
92
75
  @mutex.synchronize do
93
- @output_loggers.each do |output_log, logger|
94
- next unless logger
95
- logger.close if output_log.kind_of?(String)
76
+ @loggers.values.each do |logger|
77
+ next if logger.nil? || [$stdout, $stderr].include?(logger)
78
+ logger.close
96
79
  end
97
80
  @gateway.shutdown! if @gateway
98
81
 
99
82
  super
100
- @closed = true
101
83
  end
102
84
  end
103
85
 
104
- def closed?
105
- @closed
106
- end
107
-
108
- def duplicate
109
- @template.build(@uri, **config.to_h)
110
- end
111
-
112
- def enable_log(out = $stdout)
113
- @output_loggers = build_loggers(@output_logs + [out])
86
+ def enable_log(log = $stdout)
87
+ @loggers.update(log => build_loggers(log))
114
88
  if block_given?
115
89
  yield
116
- @output_loggers = build_loggers
90
+ disable_log(log)
117
91
  end
118
92
  end
119
93
 
120
- def disable_log(out = $stdout)
121
- @output_loggers = build_loggers(@output_logs - [out])
94
+ def disable_log(log = $stdout)
95
+ @loggers.delete(log)
122
96
  if block_given?
123
97
  yield
124
- @output_loggers = build_loggers
98
+ enable_log(log)
125
99
  end
126
100
  end
127
101
 
128
102
  private
103
+ def _waitfor(*args, &block)
104
+ args << Regexp.union(*@template.prompt.map(&:first)) if args.empty?
105
+ line = method(:waitfor).super_method.call(*args) do |recv|
106
+ block.call(recv) if block
107
+ output_log(recv)
108
+ end
109
+
110
+ _, process = @template.prompt.find { |r, p| r =~ line && p }
111
+ if process
112
+ instance_eval(&process)
113
+ line += _waitfor(*args, &block)
114
+ end
115
+ rescue EOFError
116
+ ensure
117
+ return line
118
+ end
119
+
129
120
  def ssh_tunnel(gateway)
130
121
  gateway_uri = Addressable::URI.parse(gateway)
131
122
  case gateway_uri.scheme
@@ -144,24 +135,19 @@ module Xlogin
144
135
  end
145
136
 
146
137
  def output_log(text)
147
- @output_loggers.each do |_, logger|
148
- next unless logger
149
- logger.syswrite(text)
150
- end
138
+ @loggers.values.each { |logger| logger.syswrite(text) if logger }
151
139
  end
152
140
 
153
- def build_loggers(output_logs = @output_logs)
154
- [output_logs].flatten.uniq.each.with_object({}) do |output_log, loggers|
155
- case output_log
156
- when String
157
- FileUtils.mkdir_p(File.dirname(output_log))
158
- loggers[output_log] = File.open(output_log, 'a+').tap do |logger|
159
- logger.binmode
160
- logger.sync = true
161
- end
162
- when IO, StringIO
163
- loggers[output_log] = output_log
141
+ def build_logger(log)
142
+ case log
143
+ when String
144
+ FileUtils.mkdir_p(File.dirname(log))
145
+ File.open(log, 'a+').tap do |logger|
146
+ logger.binmode
147
+ logger.sync = true
164
148
  end
149
+ when IO, StringIO
150
+ log
165
151
  end
166
152
  end
167
153
  end
@@ -5,76 +5,57 @@ module Xlogin
5
5
  class SessionPool
6
6
 
7
7
  DEFAULT_SIZE = 1
8
- DEFAULT_IDLE = false
9
8
 
10
9
  def initialize(args, **opts)
11
- @args = args
12
- @opts = opts
10
+ @args = args
11
+ @opts = opts
12
+ @size = case @args
13
+ when String then @opts.delete(:size) || DEFAULT_SIZE
14
+ when Hash then @args.delete(:size) || DEFAULT_SIZE
15
+ end
13
16
 
14
17
  @mutex = Mutex.new
15
18
  @queue = Queue.new
16
19
 
17
20
  @created = 0
18
- @watchdog = Hash.new
19
- end
20
-
21
- def size
22
- case @args
23
- when String then @opts[:size] || DEFAULT_SIZE
24
- when Hash then @args[:size] || DEFAULT_SIZE
25
- end
26
- end
27
-
28
- def idle
29
- case @args
30
- when String then @opts[:idle] || DEFAULT_IDLE
31
- when Hash then @args[:idle] || DEFAULT_IDLE
32
- end
33
21
  end
34
22
 
35
23
  def with
36
24
  session = deq
25
+
37
26
  begin
38
- Thread.handle_interrupt(Exception => :immediate) { yield session }
39
- ensure
40
- enq(session)
27
+ session.prompt
28
+ rescue Errno::ECONNABORTED, Errno::ECONNREFUSED, Errno::ECONNRESET
29
+ session.close rescue nil
30
+ @created -= 1
31
+ session = try_create
41
32
  end
33
+
34
+ Thread.handle_interrupt(Exception => :immediate) { yield session }
35
+ ensure
36
+ enq session
42
37
  end
43
38
 
44
39
  private
45
40
  def deq
46
41
  session = try_create
47
- unless session
48
- session, updated = @queue.deq
49
- session = session.duplicate if idle && updated + idle.to_f < Time.now
50
- end
51
-
42
+ session = @queue.deq unless session
52
43
  session
53
44
  end
54
45
 
55
46
  def enq(session)
56
- @mutex.synchronize { update_watchdog(session) }
57
- @queue.enq [session, Time.now]
47
+ @queue.enq session
58
48
  end
59
49
 
60
50
  def try_create
61
51
  @mutex.synchronize do
62
- return unless @created < size
63
-
64
- session = Xlogin.get(@args, **@opts)
65
- update_watchdog(session)
52
+ return unless @created < @size
66
53
 
67
54
  @created += 1
68
- session
55
+ Xlogin.get(@args, **@opts)
69
56
  end
70
57
  end
71
58
 
72
- def update_watchdog(session)
73
- return unless idle
74
-
75
- @watchdog[session].tap { |th| th.kill if th }
76
- @watchdog[session] = Thread.new(session) { |s| sleep(idle.to_f + 1) && s.close }
77
- end
78
59
  end
79
60
 
80
61
  end
@@ -1,3 +1,3 @@
1
1
  module Xlogin
2
- VERSION = "0.9.0"
2
+ VERSION = "0.9.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xlogin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - haccht
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-15 00:00:00.000000000 Z
11
+ date: 2018-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-telnet