pec2 0.5.1 → 0.6.0

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: cb66795b5285c636e91c6f868d3a8232ace8e6b0
4
- data.tar.gz: e6adbd3a3fb3ecf2c79f9328b748b8a12fd0a6d1
3
+ metadata.gz: 550ba6ff5b0de826f866deeafc7d97eb159980b9
4
+ data.tar.gz: 6fcf46712f036133de9c7c489c8cc30fbb80dc72
5
5
  SHA512:
6
- metadata.gz: 3eccd5049cebf61354803fdfe964051778b1ed79a13cf4589a482a28a91c1d477fed4c285497536f1b7fa1cdb88f5472dd9c633b7700f22a0ffbfb7e8f0e961a
7
- data.tar.gz: c20e2e77b347f67499b19d9fc855ed5eb2488beb54c0237ff5ca8cc6007062b5d980932ad1e4e976d81625aded3f7ee043e49607813a94b72b20f64840bdba71
6
+ metadata.gz: 6935e5dda4e21de298670ee7c20eff00d7e031db0d92aaaee9bc2d0cb189c7f8c8baefe7592bf9d99de52fe1466e930f4a78aed03949ae822905e8379b2c6816
7
+ data.tar.gz: 93dd2d07b2852a0729c51f5c7862a337615ac53b40b5a59f8d3509dc55d7efc2cc4f563894132a527c4304f3a17fb2dc167a5233e3f37d7e4f33679a7ed22337
data/lib/pec2/cli.rb CHANGED
@@ -20,7 +20,6 @@ module Pec2
20
20
  option :sudo_password, aliases: '-s', type: :string, desc: 'sudo_password'
21
21
  option :tag, aliases: '-t', type: :hash, default: {}, desc: 'tag'
22
22
  option :user, aliases: '-u', type: :string, desc: 'user'
23
- option :log, aliases: '-o', type: :string, desc: 'log'
24
23
  option :parallel, aliases: '-p', type: :numeric, desc: 'parallel'
25
24
  option :print, aliases: '-P', type: :boolean, default: false, desc: 'print stdout.'
26
25
  option :resolve, aliases: '--resolve', type: :string, default: 'private_ip_address', enum: ['private_ip_address', 'public_ip_address', 'name_tag'], desc: 'resolve'
@@ -43,12 +42,7 @@ module Pec2
43
42
  @logger.info(%Q{connection size #{addresses.size}.})
44
43
  @logger.info(%Q{listing connection to #{addresses.join(', ')}.})
45
44
 
46
- tf = Tempfile.open("pec2") { |fp|
47
- fp.puts(addresses.join("\n"))
48
- fp
49
- }
50
-
51
- pssh = Pssh.new(options, tf.path, addresses.size)
45
+ pssh = Pssh.new(options, addresses, addresses.size)
52
46
 
53
47
  interactive = options[:command] ? false : true
54
48
 
@@ -60,11 +54,9 @@ module Pec2
60
54
  else
61
55
  ret = pssh.exec_pssh_command(options[:command])
62
56
  unless ret
63
- tf.close
64
57
  exit 1
65
58
  end
66
59
  end
67
- tf.close
68
60
  end
69
61
 
70
62
  desc 'version', 'show version'
data/lib/pec2/pssh.rb CHANGED
@@ -1,40 +1,70 @@
1
- require 'shellwords'
1
+ require 'net/ssh'
2
+ require 'parallel'
3
+ require 'colorize'
2
4
 
3
5
  module Pec2
4
6
  class Pssh
5
7
 
6
- PSSH_PATH = File.expand_path('../../../exe/bin/pssh', __FILE__)
7
-
8
- def initialize(options, hosts_file, parallel = 1)
9
- @pssh_command = "#{PSSH_PATH} -t 0 -x '-tt' -h #{hosts_file} -O StrictHostKeyChecking=no"
10
- if options[:print]
11
- @pssh_command = "#{@pssh_command} -P"
12
- end
13
-
14
- if options[:user]
15
- @pssh_command = "#{@pssh_command} -l #{options[:user]}"
16
- end
17
-
18
- if options[:log]
19
- @pssh_command = "#{@pssh_command} -o #{options[:log]}"
20
- end
21
-
22
- @pssh_command = "#{@pssh_command} -p #{options[:parallel] || parallel}"
8
+ def initialize(options, servers, parallel = 1)
9
+ @parallel = parallel
10
+ color_index = 0
11
+ colors = String.colors.select{ |color|
12
+ !color.to_s.start_with?('light_') && !color.to_s.include?('red') && !color.to_s.include?('yellow')
13
+ }
14
+ @servers = servers.map { |server|
15
+ result = {}
16
+ result[:host] = server
17
+ result[:color] = colors[color_index]
18
+ if colors.size == color_index + 1
19
+ color_index = 0
20
+ else
21
+ color_index = color_index + 1
22
+ end
23
+ result
24
+ }
25
+ @user = options[:user]
26
+ @print = options[:print]
23
27
  @sudo_password = options[:sudo_password]
24
- end
25
-
26
- def build_pssh_command(command)
27
- if @sudo_password
28
- %Q{(echo #{@sudo_password}) | #{@pssh_command} -I #{Shellwords.escape(command)}}
29
- else
30
- %Q{#{@pssh_command} -i #{Shellwords.escape(command)}}
31
- end
28
+ @ssh_options = {
29
+ verify_host_key: false,
30
+ user_known_hosts_file: '/dev/null',
31
+ }
32
+ @logger = Logger.new(STDOUT)
32
33
  end
33
34
 
34
35
  def exec_pssh_command(command)
35
36
  return false if command.nil? || command.empty?
36
- build_command = build_pssh_command(command)
37
- system(build_command)
37
+ error_servers = []
38
+ Parallel.each(@servers, in_threads: @parallel) do |server|
39
+ begin
40
+ Net::SSH.start(server[:host], @user, @ssh_options) do |ssh|
41
+ channel = ssh.open_channel do |channel, success|
42
+ channel.on_data do |channel, data|
43
+ if data =~ /^\[sudo\] password for /
44
+ channel.send_data "#{@sudo_password}\n"
45
+ else
46
+ data.to_s.lines.each do |line|
47
+ if @print
48
+ print %Q{#{server[:host]}:#{line}}.colorize(server[:color])
49
+ end
50
+ end
51
+ end
52
+ end
53
+ channel.request_pty
54
+ channel.exec(command)
55
+ channel.wait
56
+ end
57
+ channel.wait
58
+ end
59
+ rescue => e
60
+ error_servers << server[:host]
61
+ puts "\n#{e.message}\n#{e.backtrace.join("\n")}"
62
+ end
63
+ end
64
+ if error_servers.size > 0
65
+ @logger.error "error servers => #{error_servers.join(', ')}".colorize(:red)
66
+ end
67
+ return true
38
68
  end
39
69
  end
40
70
  end
data/lib/pec2/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Pec2
2
2
  # pec2 version
3
- VERSION = "0.5.1"
3
+ VERSION = "0.6.0"
4
4
  end
data/pec2.gemspec CHANGED
@@ -18,8 +18,11 @@ Gem::Specification.new do |gem|
18
18
  gem.require_paths = ['lib']
19
19
 
20
20
  gem.add_dependency 'thor'
21
- gem.add_dependency 'aws-sdk'
21
+ gem.add_dependency 'aws-sdk', '~> 2.x'
22
22
  gem.add_dependency 'hashie'
23
+ gem.add_dependency 'net-ssh'
24
+ gem.add_dependency 'parallel'
25
+ gem.add_dependency 'colorize'
23
26
 
24
27
  gem.add_development_dependency 'bundler'
25
28
  gem.add_development_dependency 'pry'
data/spec/cli_spec.rb CHANGED
@@ -21,7 +21,6 @@ describe Pec2::CLI do
21
21
  expect(output).to include('--sudo-password')
22
22
  expect(output).to include('--tag')
23
23
  expect(output).to include('--user')
24
- expect(output).to include('--log')
25
24
  expect(output).to include('--parallel')
26
25
  expect(output).to include('--print')
27
26
  end
data/spec/pssh_spec.rb CHANGED
@@ -1,14 +1,9 @@
1
1
  require 'spec_helper'
2
2
  require 'pec2'
3
- require 'tempfile'
4
3
 
5
4
  describe Pec2::Pssh do
6
5
  before do
7
- @tf = Tempfile.open("pec2") { |fp|
8
- fp.puts("127.0.0.1")
9
- fp
10
- }
11
- @pssh = Pssh.new({}, @tf.path)
6
+ @pssh = Pssh.new({}, ["127.0.0.1"])
12
7
  end
13
8
 
14
9
  it "test exec_pssh_command empty" do
@@ -23,54 +18,6 @@ describe Pec2::Pssh do
23
18
  expect(ret).to eq(false)
24
19
  end
25
20
 
26
- it "test build_pssh_command empty" do
27
- pssh_command = @pssh.build_pssh_command('')
28
-
29
- expect(pssh_command).to include(%Q{-O StrictHostKeyChecking=no})
30
- expect(pssh_command).to include(%Q{-t 0 -x '-tt'})
31
- expect(pssh_command).to include(%Q{-i ''})
32
- end
33
-
34
- it "test build_pssh_command" do
35
- pssh_command = @pssh.build_pssh_command('hostname')
36
-
37
- expect(pssh_command).not_to start_with(%Q{(echo password) |})
38
- expect(pssh_command).to include(%Q{-O StrictHostKeyChecking=no})
39
- expect(pssh_command).to include(%Q{-t 0 -x '-tt'})
40
- expect(pssh_command).to include(%Q{-i hostname})
41
- end
42
-
43
- it "test build_pssh_command with user option" do
44
- pssh = Pssh.new({ user: 'app' }, @tf.path)
45
- pssh_command = pssh.build_pssh_command('hostname')
46
- expect(pssh_command).to include(%Q{ -l app})
47
- end
48
-
49
- it "test build_pssh_command with log option" do
50
- pssh = Pssh.new({ log: 'hoge.log' }, @tf.path)
51
- pssh_command = pssh.build_pssh_command('hostname')
52
- expect(pssh_command).to include(%Q{ -o hoge.log})
53
- end
54
-
55
- it "test build_pssh_command with parallel option" do
56
- pssh = Pssh.new({ parallel: 10 }, @tf.path)
57
- pssh_command = pssh.build_pssh_command('hostname')
58
- expect(pssh_command).to include(%Q{ -p 10})
59
- end
60
-
61
- it "test build_pssh_command with print option" do
62
- pssh = Pssh.new({ print: true }, @tf.path)
63
- pssh_command = pssh.build_pssh_command('hostname')
64
- expect(pssh_command).to include(%Q{ -P})
65
- end
66
-
67
- it "test build_pssh_command with sudo_password option" do
68
- pssh = Pssh.new({ sudo_password: 'password' }, @tf.path)
69
- pssh_command = pssh.build_pssh_command('hostname')
70
- expect(pssh_command).to start_with(%Q{(echo password) |})
71
- end
72
-
73
21
  after do
74
- @tf.close
75
22
  end
76
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pec2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - toyama0919
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-22 00:00:00.000000000 Z
11
+ date: 2017-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -26,6 +26,20 @@ dependencies:
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: aws-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.x
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.x
41
+ - !ruby/object:Gem::Dependency
42
+ name: hashie
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -39,7 +53,35 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: hashie
56
+ name: net-ssh
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: parallel
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: colorize
43
85
  requirement: !ruby/object:Gem::Requirement
44
86
  requirements:
45
87
  - - ">="
@@ -167,26 +209,6 @@ files:
167
209
  - README.md
168
210
  - Rakefile
169
211
  - bin/pec2
170
- - exe/bin/pnuke
171
- - exe/bin/prsync
172
- - exe/bin/pscp
173
- - exe/bin/pslurp
174
- - exe/bin/pssh
175
- - exe/bin/pssh-askpass
176
- - exe/man/man1/pnuke.1
177
- - exe/man/man1/prsync.1
178
- - exe/man/man1/pscp.1
179
- - exe/man/man1/pslurp.1
180
- - exe/man/man1/pssh.1
181
- - exe/psshlib/__init__.py
182
- - exe/psshlib/askpass_client.py
183
- - exe/psshlib/askpass_server.py
184
- - exe/psshlib/cli.py
185
- - exe/psshlib/color.py
186
- - exe/psshlib/manager.py
187
- - exe/psshlib/psshutil.py
188
- - exe/psshlib/task.py
189
- - exe/psshlib/version.py
190
212
  - lib/pec2.rb
191
213
  - lib/pec2/cli.rb
192
214
  - lib/pec2/constants.rb
@@ -219,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
241
  version: '0'
220
242
  requirements: []
221
243
  rubyforge_project:
222
- rubygems_version: 2.6.8
244
+ rubygems_version: 2.6.13
223
245
  signing_key:
224
246
  specification_version: 4
225
247
  summary: run parallel ssh command. ec2 tag base operation.
data/exe/bin/pnuke DELETED
@@ -1,96 +0,0 @@
1
- #!/usr/bin/env python
2
- # -*- Mode: python -*-
3
-
4
- # Copyright (c) 2009-2012, Andrew McNabb
5
- # Copyright (c) 2003-2008, Brent N. Chun
6
-
7
- """Nukes all processes that match pattern running as user on the set of nodes
8
- in hosts.txt.
9
- """
10
-
11
- import os
12
- import sys
13
-
14
- parent, bindir = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))
15
- if os.path.exists(os.path.join(parent, 'psshlib')):
16
- sys.path.insert(0, parent)
17
-
18
- from psshlib import psshutil
19
- from psshlib.task import Task
20
- from psshlib.manager import Manager, FatalError
21
- from psshlib.cli import common_parser, common_defaults
22
-
23
- _DEFAULT_TIMEOUT = 60
24
-
25
- def option_parser():
26
- parser = common_parser()
27
- parser.usage = "%prog [OPTIONS] pattern"
28
- parser.epilog = "Example: pnuke -h hosts.txt -l irb2 java"
29
- return parser
30
-
31
- def parse_args():
32
- parser = option_parser()
33
- defaults = common_defaults(timeout=_DEFAULT_TIMEOUT)
34
- parser.set_defaults(**defaults)
35
- opts, args = parser.parse_args()
36
-
37
- if len(args) < 1:
38
- parser.error('Pattern not specified.')
39
-
40
- if len(args) > 1:
41
- parser.error('Extra arguments given after the pattern.')
42
-
43
- if not opts.host_files and not opts.host_strings:
44
- parser.error('Hosts not specified.')
45
-
46
- return opts, args
47
-
48
- def do_pnuke(hosts, pattern, opts):
49
- if opts.outdir and not os.path.exists(opts.outdir):
50
- os.makedirs(opts.outdir)
51
- if opts.errdir and not os.path.exists(opts.errdir):
52
- os.makedirs(opts.errdir)
53
- manager = Manager(opts)
54
- for host, port, user in hosts:
55
- cmd = ['ssh', host, '-o', 'NumberOfPasswordPrompts=1']
56
- if opts.options:
57
- for opt in opts.options:
58
- cmd += ['-o', opt]
59
- if user:
60
- cmd += ['-l', user]
61
- if port:
62
- cmd += ['-p', port]
63
- if opts.extra:
64
- cmd.extend(opts.extra)
65
- cmd.append('pkill -9 %s' % pattern)
66
- t = Task(host, port, user, cmd, opts)
67
- manager.add_task(t)
68
- try:
69
- statuses = manager.run()
70
- except FatalError:
71
- sys.exit(1)
72
-
73
- if min(statuses) < 0:
74
- # At least one process was killed.
75
- sys.exit(3)
76
- for status in statuses:
77
- if status == 255:
78
- sys.exit(4)
79
- for status in statuses:
80
- if status != 0:
81
- sys.exit(5)
82
-
83
- if __name__ == "__main__":
84
- opts, args = parse_args()
85
- pattern = args[0]
86
- try:
87
- hosts = psshutil.read_host_files(opts.host_files,
88
- default_user=opts.user)
89
- except IOError:
90
- _, e, _ = sys.exc_info()
91
- sys.stderr.write('Could not open hosts file: %s\n' % e.strerror)
92
- sys.exit(1)
93
- if opts.host_strings:
94
- for s in opts.host_strings:
95
- hosts.extend(psshutil.parse_host_string(s, default_user=opts.user))
96
- do_pnuke(hosts, pattern, opts)