xlogin 0.13.11 → 0.14.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: ac93486a9931ac8646625ffff38c05956666aed0d14f60d9a0f1fbcddcf2ef8e
4
- data.tar.gz: bf861069b1b5f508c9143ce97fad0ba6040efb3fd78540936da1050e871ff264
3
+ metadata.gz: bbc5c0255a1328038a84dc96b4e99c1b252c998ece79c03f7e23d22b7c5eba2d
4
+ data.tar.gz: a605c1f6a0bb730e3aab19c13401c902416aee1e985a34a4d3132c014bc36f43
5
5
  SHA512:
6
- metadata.gz: 3249c1f47125e78e490883c9f36a1bc766d16e1810e9fecbaecba9855da2263137889b3887fae6e3335be6c226ea8c8aa2d6b8edad8c3c1c83cbc849c31eea6c
7
- data.tar.gz: becd77aacc551b16d55d8bce42761daa06c7fbf56a11b4399057b9cb3177e445aa49ede693a1561c60b00cd1d19a8b92c36c5aa8cec82982d23538539324aee6
6
+ metadata.gz: c077a17025b8131927de93b9602bc1d8957f4545b38bf2ec58c95d460faf3320d55770c8efc65cce4796eeb11fa5d3e4d3bcd7acbd9b35b44e7beffc1da55b5e
7
+ data.tar.gz: 665cb8e5a6ebde87623135a31ca21d5f2e25408e31e4fc12560fa4ce6095459a686a32317c1a0dabb4eace83224b828999be069a5c84f225fa4dad9dc174a44b
@@ -61,14 +61,14 @@ module Xlogin
61
61
  def generate_templates(dir)
62
62
  FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
63
63
  builtin_templates = Dir.glob(File.join(File.dirname(__FILE__), 'xlogin', 'templates', '*.rb'))
64
- builtin_templates.each { |file| FileUtils.cp(file, DEFAULT_TEMPLATE_DIR) }
64
+ builtin_templates.each{ |file| FileUtils.cp(file, DEFAULT_TEMPLATE_DIR) }
65
65
  end
66
66
 
67
- private
68
67
  def factory
69
68
  @factory ||= Xlogin::Factory.instance
70
69
  end
71
70
 
71
+ private
72
72
  def set(opts = {})
73
73
  @settings ||= {}
74
74
  opts.each do |key, val|
@@ -15,7 +15,7 @@ module Xlogin
15
15
  end
16
16
 
17
17
  def list(config)
18
- puts Xlogin.list(*config[:pattern]).map { |e| e[:name] }.sort.uniq
18
+ puts Xlogin.list(*config[:pattern]).map{ |e| e[:name] }.sort.uniq
19
19
  end
20
20
 
21
21
  def tty(config)
@@ -26,11 +26,11 @@ module Xlogin
26
26
  end
27
27
 
28
28
  def exec(config)
29
- Signal.trap(:INT) { exit 0 }
29
+ Signal.trap(:INT){ exit 0 }
30
30
 
31
31
  jobs = config[:jobs] || 1
32
32
  hosts = Xlogin.list(*config[:pattern])
33
- width = hosts.map { |e| e[:name].length }.max
33
+ width = hosts.map{ |e| e[:name].length }.max
34
34
 
35
35
  Parallel.map(hosts, in_threads: jobs) do |info|
36
36
  buffer = StringIO.new
@@ -43,14 +43,14 @@ module Xlogin
43
43
  loggers << File.expand_path(File.join(config[:"log-dir"], "#{info[:name]}.log"), ENV['PWD']) if config[:"log-dir"]
44
44
 
45
45
  session = Xlogin.get(info.merge(log: loggers))
46
- session.enable(info[:enable]) if info[:enable] && Xlogin.settings.enable?
46
+ session.enable(session.config.enable) if session.config.enable && Xlogin.settings.enable?
47
47
 
48
48
  command_lines = ['', *config[:exec].to_s.split(';').map(&:strip)]
49
- command_lines.each { |line| session.cmd(line) }
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
 
@@ -71,10 +71,10 @@ module Xlogin
71
71
 
72
72
  parser.on('-i PATH', '--inventory', String, 'The PATH to the inventory file.')
73
73
  parser.on('-t PATH', '--template', String, 'The PATH to the template file or directory.')
74
- parser.on('-L PATH', '--log-dir', String, 'The PATH to the log directory.') { |v| v || '.' }
74
+ parser.on('-L PATH', '--log-dir', String, 'The PATH to the log directory.'){ |v| v || '.' }
75
75
 
76
- parser.on('-l', '--list', TrueClass, 'List the inventory.') { |v| config[:runner] = self.method(:list) }
77
- parser.on('-e COMMAND', '--exec', String, 'Execute commands and quit.') { |v| config[:runner] = self.method(:exec); v }
76
+ parser.on('-l', '--list', TrueClass, 'List the inventory.') { |v| config[:runner] = self.method(:list) }
77
+ parser.on('-e COMMAND', '--exec', String, 'Execute commands and quit.'){ |v| config[:runner] = self.method(:exec); v }
78
78
 
79
79
  parser.on('-E KEY=VAL', '--env', /(\w+=\w+)+/, 'Environment variables.')
80
80
  parser.on('-j NUM', '--jobs', Integer, 'The NUM of jobs to execute in parallel.')
@@ -1,5 +1,6 @@
1
1
  require 'addressable/uri'
2
2
  require 'singleton'
3
+ require 'thread'
3
4
  require 'xlogin/session_pool'
4
5
  require 'xlogin/template'
5
6
 
@@ -9,8 +10,10 @@ module Xlogin
9
10
  include Singleton
10
11
 
11
12
  def initialize
12
- @inventory = Hash.new
13
- @templates = Hash.new
13
+ @inventory = Hash.new
14
+ @templates = Hash.new
15
+ @gateways = Hash.new
16
+ @mutex = Mutex.new
14
17
  end
15
18
 
16
19
  def set_inventory(name, **opts)
@@ -28,7 +31,7 @@ module Xlogin
28
31
  values2 = pattern.split(',').map do |entry|
29
32
  key, val = entry.to_s.split(':')
30
33
  key, val = 'name', key if val.nil?
31
- @inventory.values.select { |e| File.fnmatch(val, e[key.to_sym]) }
34
+ @inventory.values.select{ |e| File.fnmatch(val, e[key.to_sym]) }
32
35
  end
33
36
  values2.reduce(&:&)
34
37
  end
@@ -50,6 +53,35 @@ module Xlogin
50
53
  @templates.keys
51
54
  end
52
55
 
56
+ def open_tunnel(tunnel, host, port)
57
+ @mutex.synchronize do
58
+ unless @gateways[tunnel]
59
+ gateway_uri = Addressable::URI.parse(tunnel)
60
+ case gateway_uri.scheme
61
+ when 'ssh'
62
+ username, password = *gateway_uri.userinfo.split(':')
63
+ @gateways[tunnel] = Net::SSH::Gateway.new(
64
+ gateway_uri.host,
65
+ username,
66
+ password: password,
67
+ port: gateway_uri.port || 22
68
+ )
69
+ end
70
+ end
71
+
72
+ gateway = @gateways[tunnel]
73
+ return host, port unless gateway
74
+ return '127.0.0.1', gateway.open(host, port)
75
+ end
76
+ end
77
+
78
+ def close_tunnel(tunnel, port)
79
+ @mutex.synchronize do
80
+ gateway = @gateways[tunnel]
81
+ gateway.close(port) if gateway
82
+ end
83
+ end
84
+
53
85
  def build(type:, **opts)
54
86
  template = get_template(type)
55
87
  raise Xlogin::Error.new("Template not found: '#{type}'") unless template
@@ -13,7 +13,7 @@ module Xlogin
13
13
 
14
14
  def generate(*patterns, **opts, &block)
15
15
  description = Rake.application.last_description
16
- hostnames = Xlogin.list(*patterns).map { |e| e[:name] }
16
+ hostnames = Xlogin.list(*patterns).map{ |e| e[:name] }
17
17
 
18
18
  task 'all' => hostnames unless opts[:all] == false
19
19
  hostnames.each do |hostname|
@@ -111,7 +111,7 @@ module Xlogin
111
111
  end
112
112
 
113
113
  module SessionModule
114
- def msg(text, prefix: "[INFO]", chomp: false, **color)
114
+ def log_message(text, prefix: "[INFO]", chomp: false, **color)
115
115
  default_color = { color: :green }
116
116
 
117
117
  log("\n")
@@ -22,16 +22,16 @@ module Xlogin
22
22
  end
23
23
 
24
24
  @name = opts[:name] || @host
25
+ @tunnel = opts[:tunnel] || opts[:via]
25
26
  @config = ReadOnlyStruct.new(opts)
26
27
  @template = template
27
28
  @username, @password = uri.userinfo.to_s.split(':')
28
29
 
29
- forward = @config.forward || @config.via
30
- ssh_tunnel(forward) if forward
31
30
  max_retry = @config.retry || 1
31
+ @host, @port = Xlogin.factory.open_tunnel(@tunnel, @host, @port) if @tunnel
32
32
 
33
33
  @mutex = Mutex.new
34
- @loggers = [@config.log].flatten.uniq.reduce({}) { |a, e| a.merge(e => build_logger(e)) }
34
+ @loggers = [@config.log].flatten.uniq.reduce({}){ |a, e| a.merge(e => build_logger(e)) }
35
35
 
36
36
  begin
37
37
  args = Hash.new
@@ -73,13 +73,13 @@ module Xlogin
73
73
  end
74
74
 
75
75
  def puts(*args, &block)
76
- args = args.flat_map { |arg| instance_exec(arg, &@template.interrupt!) }.compact if @template.interrupt!
76
+ args = args.flat_map{ |arg| instance_exec(arg, &@template.interrupt!) }.compact if @template.interrupt!
77
77
  args.empty? ? super('', &block) : super(*args, &block)
78
78
  end
79
79
 
80
80
  def waitfor(*args, &block)
81
81
  args = [prompt_pattern] if args.empty?
82
- @mutex.synchronize { _waitfor(*args, &block) }
82
+ @mutex.synchronize{ _waitfor(*args, &block) }
83
83
  end
84
84
 
85
85
  def close
@@ -90,17 +90,13 @@ module Xlogin
90
90
  logger.close
91
91
  end
92
92
 
93
- if @gateway
94
- @gateway.close(@port)
95
- @gateway.shutdown!
96
- end
97
-
93
+ Xlogin.factory.close_tunnel(@tunnel, @port) if @tunnel
98
94
  super
99
95
  end
100
96
  end
101
97
 
102
98
  def log(text)
103
- @loggers.each { |_, logger| logger.syswrite(text) if logger }
99
+ @loggers.each{ |_, logger| logger.syswrite(text) if logger }
104
100
  end
105
101
 
106
102
  def enable_log(log = $stdout)
@@ -127,7 +123,7 @@ module Xlogin
127
123
  block.call(recv) if block
128
124
  end
129
125
 
130
- _, process = @template.prompt.find { |r, p| r =~ line && p }
126
+ _, process = @template.prompt.find{ |r, p| r =~ line && p }
131
127
  if process
132
128
  instance_eval(&process)
133
129
  line += _waitfor(*args, &block)
@@ -136,23 +132,6 @@ module Xlogin
136
132
  return line
137
133
  end
138
134
 
139
- def ssh_tunnel(gateway)
140
- gateway_uri = Addressable::URI.parse(gateway)
141
- case gateway_uri.scheme
142
- when 'ssh'
143
- username, password = *gateway_uri.userinfo.split(':')
144
- @gateway = Net::SSH::Gateway.new(
145
- gateway_uri.host,
146
- username,
147
- password: password,
148
- port: gateway_uri.port || 22
149
- )
150
-
151
- @port = @gateway.open(@host, @port)
152
- @host = '127.0.0.1'
153
- end
154
- end
155
-
156
135
  def build_logger(log)
157
136
  case log
158
137
  when String
@@ -22,16 +22,16 @@ module Xlogin
22
22
  end
23
23
 
24
24
  def size=(val)
25
- @mutex.synchronize { @size = val }
25
+ @mutex.synchronize{ @size = val }
26
26
  end
27
27
 
28
28
  def idle=(val)
29
- @mutex.synchronize { @idle = val }
29
+ @mutex.synchronize{ @idle = val }
30
30
  end
31
31
 
32
32
  def with
33
33
  session = deq
34
- Thread.handle_interrupt(Exception => :immediate) { yield session }
34
+ Thread.handle_interrupt(Exception => :immediate){ yield session }
35
35
  ensure
36
36
  enq session
37
37
  end
@@ -47,12 +47,12 @@ module Xlogin
47
47
  klass = Class.new(Xlogin.const_get(uri.scheme.capitalize))
48
48
  klass.class_exec(self) do |template|
49
49
  scopes = [*opts[:scope]].compact
50
- scopes.each { |scope| template.instance_eval(&template.scopes[scope]) }
50
+ scopes.each{ |scope| template.instance_eval(&template.scopes[scope]) }
51
51
 
52
52
  template.methods.each do |name, block|
53
53
  case name.to_s
54
54
  when 'enable'
55
- define_method(name) { |args = nil| instance_exec(args || opts[:enable], &block) }
55
+ define_method(name){ |args = nil| instance_exec(args || opts[:enable], &block) }
56
56
  else
57
57
  define_method(name, &block)
58
58
  end
@@ -64,7 +64,7 @@ module Xlogin
64
64
 
65
65
  def method_missing(name, *, &block)
66
66
  super unless RESERVED_METHODS.include?(name)
67
- bind(name) { |*args| instance_exec(*args, &block) }
67
+ bind(name){ |*args| instance_exec(*args, &block) }
68
68
  end
69
69
 
70
70
  end
@@ -1,3 +1,3 @@
1
1
  module Xlogin
2
- VERSION = "0.13.11"
2
+ VERSION = "0.14.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xlogin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.11
4
+ version: 0.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - haccht