xlogin 0.14.2 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 547e74e0f0fa2ffc7c30a9d809e7459eea4776c7a902e7f30f1c2e109e7b9a6a
4
- data.tar.gz: e810cb9efb8098ce1acd8063f7de24f63876676b03819a06a329a04e010c588c
3
+ metadata.gz: 3c42dda50faff8d019ae126b4283df85aeca1007e119fe486882b06092090168
4
+ data.tar.gz: 5d15694b3a53acdecca601e99039e9121b83d111e5e5070eaaa7fa353936d57a
5
5
  SHA512:
6
- metadata.gz: 17373511e6a0f038ca63e6c7721d45eb3e1f8ef2c8a0f02ae287a0eeb0af51bc59f302ae7aaf27ae2b0d8f6c99673426744c33a1cb052d13d3d6b63a81a130cf
7
- data.tar.gz: f0258f43d91d1043c5cf55ead1e71aba4e25df7cee36c2f6f3e34b528f66c62702280bfa5802840ab985e3a03988b1f0c89da69cd50a09d27d02c2842a7eae68
6
+ metadata.gz: 9ce8c023c0be12b67a33be6ca9fa84eabdc78aa1832d9311b0dd9a55cc82627260effeecdb6395c397fa74f1799b6d3b8382a95e35eeb83099bbca7be903f0c1
7
+ data.tar.gz: ff604b3256270f0b81ddcf455a6f62b77fdc44d5d6f136de86225ecc4fae452d2dee55001c3eee94817d01bdfbfb87f7ee256fa66106b29d5ecd3c4c10a79ea6
@@ -34,21 +34,19 @@ module Xlogin
34
34
  when Hash then factory.build(**args.merge(**opts))
35
35
  when String then factory.build_from_hostname(args, **opts)
36
36
  else
37
- raise SessionError.new("Invalid argument: '#{args}'")
37
+ raise Xlogin::Error.new("Invalid argument: '#{args}'")
38
38
  end
39
39
 
40
40
  return session unless block
41
41
  begin block.call(session) ensure session.close end
42
42
  end
43
- alias_method :create, :get
44
43
 
45
- def get_pool(args, **opts, &block)
44
+ def pool(args, **opts, &block)
46
45
  pool = factory.build_pool(args, **opts)
47
46
 
48
47
  return pool unless block
49
48
  begin block.call(pool) ensure pool.close end
50
49
  end
51
- alias_method :create_pool, :get_pool
52
50
 
53
51
  def configure(&block)
54
52
  instance_eval(&block)
@@ -59,7 +57,7 @@ module Xlogin
59
57
  end
60
58
 
61
59
  def generate_templates(dir)
62
- FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
60
+ FileUtils.mkdir_p(dir)
63
61
  builtin_templates = Dir.glob(File.join(File.dirname(__FILE__), 'xlogin', 'templates', '*.rb'))
64
62
  builtin_templates.each{ |file| FileUtils.cp(file, DEFAULT_TEMPLATE_DIR) }
65
63
  end
@@ -25,7 +25,7 @@ module Xlogin
25
25
  end
26
26
 
27
27
  def exec(config)
28
- Signal.trap(:INT){ exit 0 }
28
+ Signal.trap(:INT){ exit 1 }
29
29
 
30
30
  jobs = config[:jobs] || 1
31
31
  hosts = Xlogin.list(*config[:patterns])
@@ -48,9 +48,9 @@ module Xlogin
48
48
  command_lines = config[:command].flat_map { |e| e.to_s.split(';').map(&:strip) }
49
49
  command_lines.each{ |line| session.cmd(line) }
50
50
 
51
- buffer.string.lines.each{ |line| print prefix + line.gsub("\r", '') } if jobs > 1
51
+ buffer.string.lines.each{ |line| print prefix + line.gsub(/^.*\r/, '') } if jobs > 1
52
52
  rescue => e
53
- buffer.string.lines.each{ |line| print prefix + line.gsub("\r", '') } if jobs > 1
53
+ buffer.string.lines.each{ |line| print prefix + line.gsub(/^.*\r/, '') } if jobs > 1
54
54
  raise e
55
55
  end
56
56
 
@@ -91,6 +91,7 @@ module Xlogin
91
91
  template *config[:template].map { |e| File.expand_path(e, ENV['PWD']) }
92
92
  end
93
93
 
94
+ raise Xlogin::Error.new("Invalid host pattern: '#{config[:patterns].join(' ')}'") if Xlogin.list(*config[:patterns]).empty?
94
95
  config[:runner].call(config)
95
96
  rescue => e
96
97
  $stderr.puts e, '', parser
@@ -13,7 +13,7 @@ module Xlogin
13
13
  def initialize
14
14
  @inventory = Hash.new
15
15
  @templates = Hash.new
16
- @gateways = Hash.new
16
+ @tunnels = Hash.new
17
17
  @mutex = Mutex.new
18
18
  end
19
19
 
@@ -26,18 +26,17 @@ module Xlogin
26
26
  end
27
27
 
28
28
  def list_hostinfo(*patterns)
29
- return [] if patterns == [nil]
30
29
  return @inventory.values if patterns.empty?
31
30
 
32
- values1 = patterns.map do |pattern|
31
+ values1 = patterns.compact.map do |pattern|
33
32
  values2 = pattern.split(',').map do |entry|
34
33
  key, val = entry.to_s.split(':')
35
34
  key, val = 'name', key if val.nil?
36
35
  @inventory.values.select{ |e| File.fnmatch(val, e[key.to_sym]) }
37
36
  end
38
- values2.reduce(&:&)
37
+ values2.reduce(&:&) || []
39
38
  end
40
- values1.reduce(&:|)
39
+ values1.reduce(&:|) || []
41
40
  end
42
41
 
43
42
  def set_template(name, text = nil, &block)
@@ -55,32 +54,40 @@ module Xlogin
55
54
  @templates.keys
56
55
  end
57
56
 
58
- def open_tunnel(tunnel, host, port)
57
+ def open_tunnel(name, host, port)
59
58
  @mutex.synchronize do
60
- unless @gateways[tunnel]
61
- gateway_uri = Addressable::URI.parse(tunnel)
62
- case gateway_uri.scheme
59
+ unless @tunnels[name]
60
+ uri = Addressable::URI.parse(name)
61
+ case uri.scheme
63
62
  when 'ssh'
64
- username, password = *gateway_uri.userinfo.split(':')
65
- @gateways[tunnel] = Net::SSH::Gateway.new(
66
- gateway_uri.host,
63
+ username, password = *uri.userinfo.split(':')
64
+ gateway = Net::SSH::Gateway.new(
65
+ uri.host,
67
66
  username,
68
67
  password: password,
69
- port: gateway_uri.port || 22
68
+ port: uri.port || 22
70
69
  )
70
+
71
+ @tunnels[name] = Struct.new('Tunnel', :gateway, :ports).new(gateway, [])
71
72
  end
72
73
  end
73
74
 
74
- gateway = @gateways[tunnel]
75
- return host, port unless gateway
76
- return '127.0.0.1', gateway.open(host, port)
75
+ if tunnel = @tunnels[name]
76
+ port = tunnel.gateway.open(host, port)
77
+ host = '127.0.0.1'
78
+ tunnel.ports << port
79
+ end
80
+ return host, port
77
81
  end
78
82
  end
79
83
 
80
- def close_tunnel(tunnel, port)
84
+ def close_tunnel(name, port)
81
85
  @mutex.synchronize do
82
- gateway = @gateways[tunnel]
83
- gateway.close(port) if gateway
86
+ if tunnel = @tunnels[name]
87
+ tunnel.ports.delete(port)
88
+ tunnel.gateway.close(port)
89
+ tunnel.gateway.shutdown! if tunnel.ports.empty?
90
+ end
84
91
  end
85
92
  end
86
93
 
@@ -92,7 +92,7 @@ module Xlogin
92
92
  rescue => e
93
93
  RakeTask.shutdown! if fail_on_error
94
94
 
95
- session.comment(e.to_s, prefix: "[ERROR]", chomp: true, color: :white, background: :red)
95
+ session.comment(e.to_s, prefix: "[ERROR]", chomp: true, color: :white, background: :red) if session
96
96
  $stderr.print log_text(buffer.string + "\n").colorize(color: :light_red) if Rake.application.options.always_multitask
97
97
 
98
98
  return false
@@ -101,7 +101,7 @@ module Xlogin
101
101
  end
102
102
 
103
103
  def log_text(text)
104
- text.lines.map{ |line| "#{Time.now.iso8601} - #{name}\t|#{line.gsub(/^\s*[\r]+/, '')}" }.join
104
+ text.lines.map{ |line| "#{Time.now.iso8601} - #{name}\t|#{line.gsub(/^.*\r/, '')}" }.join
105
105
  end
106
106
 
107
107
  end
@@ -109,7 +109,7 @@ module Xlogin
109
109
  module SessionModule
110
110
 
111
111
  def comment(line, prefix: "[INFO]", chomp: false, **color)
112
- write_log("#{prefix} #{line}".colorize(**color))
112
+ write_log("#{prefix} #{line}".colorize({color: :light_white}.merge(**color)))
113
113
  cmd('') unless chomp
114
114
  end
115
115
 
@@ -7,7 +7,7 @@ module Xlogin
7
7
  DEFAULT_POOL_SIZE = 1
8
8
  DEFAULT_POOL_IDLE = 60
9
9
 
10
- attr_reader :size, :idle
10
+ attr_accessor :size, :idle
11
11
 
12
12
  def initialize(args, **opts)
13
13
  @args = args
@@ -18,15 +18,7 @@ module Xlogin
18
18
 
19
19
  @mutex = Mutex.new
20
20
  @queue = Queue.new
21
- @created = 0
22
- end
23
-
24
- def size=(val)
25
- @mutex.synchronize{ @size = val }
26
- end
27
-
28
- def idle=(val)
29
- @mutex.synchronize{ @idle = val }
21
+ @count = 0
30
22
  end
31
23
 
32
24
  def with
@@ -38,20 +30,22 @@ module Xlogin
38
30
 
39
31
  def close
40
32
  until @queue.empty?
41
- session, _ = @queue.deq
33
+ session, _, _ = @queue.deq
42
34
  destroy(session)
43
35
  end
44
36
  end
45
37
 
46
38
  def deq
47
39
  @mutex.synchronize do
48
- if @queue.empty? && @created < @size
49
- @created += 1
40
+ if @queue.empty? && @count < @size
41
+ @count += 1
50
42
  return Xlogin.get(@args, **@opts)
51
43
  end
52
44
  end
53
45
 
54
- session, last_used = @queue.deq
46
+ session, last_used, watch_dog = @queue.deq
47
+
48
+ watch_dog.kill
55
49
  if Time.now - last_used > @idle
56
50
  destroy(session)
57
51
  return deq
@@ -59,23 +53,24 @@ module Xlogin
59
53
 
60
54
  begin
61
55
  raise IOError if session&.sock&.closed?
56
+ return session
62
57
  rescue IOError, EOFError, Errno::ECONNABORTED, Errno::ECONNREFUSED, Errno::ECONNRESET
63
58
  destroy(session)
64
59
  return deq
65
60
  end
66
-
67
- session
68
61
  end
69
62
 
70
63
  def enq(session)
71
64
  last_used = Time.now
72
- @queue.enq [session, last_used]
65
+ watch_dog = Thread.new(session){ |s| sleep(@idle * 1.5) && s.close rescue nil }
66
+ @queue.enq [session, last_used, watch_dog]
73
67
  end
74
68
 
69
+ private
75
70
  def destroy(session)
76
71
  @mutex.synchronize do
77
72
  session.close rescue nil
78
- @created -= 1
73
+ @count -= 1
79
74
  end
80
75
  end
81
76
 
@@ -38,7 +38,7 @@ module Xlogin
38
38
  @sock.syswrite(bs)
39
39
  when @sock
40
40
  begin
41
- log(fh.readpartial(1024))
41
+ write_log(fh.readpartial(1024))
42
42
  rescue Errno::EAGAIN
43
43
  retry
44
44
  end
@@ -47,7 +47,7 @@ module Xlogin
47
47
  end
48
48
  rescue EOFError, Errno::ECONNRESET
49
49
  $stdout.puts "\r\n", "Conneciton closed.", "\r\n"
50
- self.close
50
+ close
51
51
  ensure
52
52
  $stdin.cooked!
53
53
  end
@@ -1,3 +1,3 @@
1
1
  module Xlogin
2
- VERSION = "0.14.2"
2
+ VERSION = "0.15.1"
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.14.2
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - haccht
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-03 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-telnet