xlogin 0.13.11 → 0.14.1

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
  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