hocho 0.2.2 → 0.3.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
  SHA256:
3
- metadata.gz: b86467c121e99a2b09b6a09ea852aaa61edcf3cd0ced7f068184284950d5bd8b
4
- data.tar.gz: e9c851f4e6d6d7040c3455c21d91e5e674a7abe95fecd352a2b1319701e65da5
3
+ metadata.gz: 02bd4fdb528bce052b2fbbdf13094a22dd66eaf4cea358cfdf458ad744e16e7c
4
+ data.tar.gz: 133bea775d5dd49cceaca4f24abf0cb47b1bf67583d51879c37643bda8b9d8aa
5
5
  SHA512:
6
- metadata.gz: 6b94585fa2224c38601e50173206fc35499f6e810817491ce0c556e9dfe55bbbc62b309d81139a4d40855c12c19be05cc51deb7cf265bd8970e20e466cae45a2
7
- data.tar.gz: 7ce19d7a13bb657ab41b511eb290306980d1fba32b3b7c8e7011f8a12696bfcfca030ef0c3d2c17c8699a6495f38a61b7147f322b421f82bde98bb66bda762f5
6
+ metadata.gz: 8cc5f789571a9c32c8ef2633ea5ef78b128d85e8ce5c7900bb155138bd944deeb031e7fd2d3715059a1916f8c05837269a8bc9c4426f19218304308aaa41af53
7
+ data.tar.gz: b7985500b353068b4e0a7433db48b396c5f856b29d037bc3208c0420765d38dd8ec986d5a857556b56480fa210f796308d1d54b9c7e2ac8f0b5e1ea738fcc981
data/lib/hocho/command.rb CHANGED
@@ -52,28 +52,40 @@ module Hocho
52
52
  desc "apply HOST", "run itamae"
53
53
  method_option :sudo, type: :boolean, default: false
54
54
  method_option :dry_run, type: :boolean, default: false, aliases: %w(-n)
55
+ method_option :exclude, type: :string, default: '', aliases: %w(-e)
55
56
  method_option :driver, type: :string
56
57
  def apply(name)
57
- host = inventory.filter(name: name).first
58
- unless host
58
+ hosts = inventory.filter({name: name}, exclude_filters: {name: options[:exclude]})
59
+ if hosts.empty?
59
60
  raise "host name=#{name.inspect} not found"
60
61
  end
61
62
 
63
+ if hosts.size > 1
64
+ puts "Running sequencial on:"
65
+ hosts.each do |host|
66
+ puts " * #{host.name}"
67
+ end
68
+ puts
69
+ end
70
+
62
71
  if config[:ask_sudo_password] || options[:sudo]
63
72
  print "sudo password: "
64
- host.sudo_password = $stdin.noecho { $stdin.gets.chomp }
73
+ sudo_password = $stdin.noecho { $stdin.gets.chomp }
65
74
  puts
66
75
  end
67
76
 
68
- Runner.new(
69
- host,
70
- driver: options[:driver],
71
- base_dir: config[:itamae_dir] || '.',
72
- initializers: config[:initializers] || [],
73
- driver_options: config[:driver_options] || {},
74
- ).run(
75
- dry_run: options[:dry_run],
76
- )
77
+ hosts.each do |host|
78
+ host.sudo_password = sudo_password if sudo_password
79
+ Runner.new(
80
+ host,
81
+ driver: options[:driver],
82
+ base_dir: config[:itamae_dir] || '.',
83
+ initializers: config[:initializers] || [],
84
+ driver_options: config[:driver_options] || {},
85
+ ).run(
86
+ dry_run: options[:dry_run],
87
+ )
88
+ end
77
89
  end
78
90
 
79
91
  private
@@ -13,6 +13,7 @@ module Hocho
13
13
  end
14
14
 
15
15
  def run(dry_run: false)
16
+ ssh # Test connection
16
17
  deploy(**@deploy_options) do
17
18
  bundle_install
18
19
  run_itamae(dry_run: dry_run)
@@ -13,8 +13,8 @@ module Hocho
13
13
  @deploy_options = deploy_options
14
14
  end
15
15
 
16
-
17
16
  def run(dry_run: false)
17
+ ssh # Test connection
18
18
  deploy(**@deploy_options) do
19
19
  prepare_mitamae
20
20
  run_mitamae(dry_run: dry_run)
@@ -70,10 +70,12 @@ module Hocho
70
70
 
71
71
  temporary_passphrase = SecureRandom.base64(129).chomp
72
72
 
73
+ derive = system(*%w(openssl enc -pbkdf2), in: File::NULL, out: File::NULL, err: [:child, :out]) ? %w(-pbkdf2) : []
74
+
73
75
  encrypted_password = IO.pipe do |r,w|
74
76
  w.write temporary_passphrase
75
77
  w.close
76
- IO.popen([*%w(openssl enc -aes-128-cbc -pass fd:5 -a), 5 => r], "r+") do |io|
78
+ IO.popen([*%w(openssl enc -aes-128-cbc -pass fd:5 -a -md sha256), *derive, 5 => r], "r+") do |io|
77
79
  io.puts password
78
80
  io.close_write
79
81
  io.read.chomp
@@ -86,7 +88,7 @@ module Hocho
86
88
  raise unless temp_executable.start_with?('/')
87
89
 
88
90
  ssh_run("chmod 0700 #{temp_executable.shellescape}; cat > #{temp_executable.shellescape}; chmod +x #{temp_executable.shellescape}") do |ch|
89
- ch.send_data("#!/bin/bash\nexec openssl enc -aes-128-cbc -d -a -pass env:#{passphrase_env_name} <<< #{encrypted_password.shellescape}\n")
91
+ ch.send_data("#!/bin/bash\nexec openssl enc -aes-128-cbc -d -a -md sha256 -pass env:#{passphrase_env_name} <<< #{encrypted_password.shellescape}\n")
90
92
  ch.eof!
91
93
  end
92
94
 
data/lib/hocho/host.rb CHANGED
@@ -18,11 +18,13 @@ module Hocho
18
18
  @tmpdir = tmpdir
19
19
  @shmdir = shmdir
20
20
  @sudo_password = sudo_password
21
+
22
+ @use_alternate_ssh_options = false
21
23
  end
22
24
 
23
25
  attr_reader :name, :providers, :properties, :tmpdir, :shmdir
24
26
  attr_writer :sudo_password
25
- attr_accessor :tags
27
+ attr_accessor :tags, :use_alternate_ssh_options
26
28
 
27
29
  def to_h
28
30
  {
@@ -42,10 +44,10 @@ module Hocho
42
44
  end
43
45
 
44
46
  def merge!(other)
45
- @tags.merge!(other.tags)
47
+ @tags.merge!(other.tags) if other.tags
46
48
  @tmpdir = other.tmpdir if other.tmpdir
47
49
  @shmdir = other.shmdir if other.shmdir
48
- @properties.merge(other.properties)
50
+ @properties.merge!(other.properties)
49
51
  end
50
52
 
51
53
  def apply_property_providers(providers)
@@ -79,9 +81,25 @@ module Hocho
79
81
  end
80
82
 
81
83
  def ssh_options
84
+ use_alternate_ssh_options? ? alternate_ssh_options : normal_ssh_options
85
+ end
86
+
87
+ def normal_ssh_options
82
88
  (Net::SSH::Config.for(ssh_name) || {}).merge(Hocho::Utils::Symbolize.keys_of(properties[:ssh_options] || {})).merge(@override_ssh_options || {})
83
89
  end
84
90
 
91
+ def alternate_ssh_options
92
+ normal_ssh_options.merge(Hocho::Utils::Symbolize.keys_of(properties.fetch(:alternate_ssh_options, {})))
93
+ end
94
+
95
+ def alternate_ssh_options_available?
96
+ !!properties[:alternate_ssh_options]
97
+ end
98
+
99
+ def use_alternate_ssh_options?
100
+ @use_alternate_ssh_options
101
+ end
102
+
85
103
  def openssh_config(separator='=')
86
104
  ssh_options.flat_map do |key, value|
87
105
  case key
@@ -131,8 +149,11 @@ module Hocho
131
149
  when :port
132
150
  [["Port", value]]
133
151
  when :proxy
134
- if value.kind_of?(Net::SSH::Proxy::Command)
152
+ case value
153
+ when Net::SSH::Proxy::Command
135
154
  [["ProxyCommand", value.command_line_template]]
155
+ when false
156
+ [["ProxyCommand", 'none']]
136
157
  else
137
158
  [["ProxyCommand", value]]
138
159
  end
@@ -173,7 +194,17 @@ module Hocho
173
194
  end
174
195
 
175
196
  def make_ssh_connection
176
- Net::SSH.start(name, nil, ssh_options)
197
+ alt = false
198
+ begin
199
+ Net::SSH.start(name, nil, ssh_options)
200
+ rescue Net::SSH::Exception => e
201
+ raise if alt
202
+ raise unless alternate_ssh_options_available?
203
+ puts "[#{name}] Trying alternate_ssh_options due to #{e.inspect}"
204
+ self.use_alternate_ssh_options = true
205
+ alt = true
206
+ retry
207
+ end
177
208
  end
178
209
  end
179
210
  end
@@ -20,19 +20,32 @@ module Hocho
20
20
  end.values
21
21
  end
22
22
 
23
- def filter(filters)
24
- filters = filters.map do |name, value|
25
- [name.to_s, value.to_s.split(?,).map! { |_| /#{Regexp.escape(_).gsub(/\\*/,'.*')}/ }]
26
- end.to_h
23
+ def filter(include_filters, exclude_filters: [])
24
+ include_filters, exclude_filters = [include_filters, exclude_filters].map do |f|
25
+ f.map do |name, value|
26
+ values = value.to_s.split(?,).map! do |_|
27
+ if _[0] == '/' && _[-1] == '/'
28
+ Regexp.new(_[1...-1])
29
+ else
30
+ /#{Regexp.escape(_).gsub(/\*/,'.*')}/
31
+ end
32
+ end
33
+ [name.to_s, values]
34
+ end.to_h
35
+ end
36
+
37
+ filters = include_filters.map do |name, conditions|
38
+ [name, [conditions, exclude_filters.fetch(name, [])]]
39
+ end
27
40
 
28
41
  hosts.select do |host|
29
- filters.all? do |name, conditions|
42
+ filters.all? do |name, (conditions, exclude_conditions)|
30
43
  case name
31
44
  when 'name'
32
- conditions.any? { |c| host.name.match(c) }
45
+ conditions.any? { |c| host.name.match(c) } && !exclude_conditions.any? { |c| host.name.match(c) }
33
46
  else
34
47
  v = (host.attributes[name] || host.attributes[name.to_sym] || host.tags[name] || host.tags[name.to_sym])
35
- v && conditions.any? { |c| v.to_s.match(c) }
48
+ v && conditions.any? { |c| v.to_s.match(c) } && !exclude_conditions.any?{ |c| v.to_s.match(c) }
36
49
  end
37
50
  end
38
51
  end
@@ -28,9 +28,9 @@ module Hocho
28
28
  Host.new(
29
29
  name.to_s,
30
30
  providers: self.class,
31
- properties: value[:properties],
32
- tags: value[:tags],
33
- ssh_options: value[:ssh_options]
31
+ properties: value[:properties] || {},
32
+ tags: value[:tags] || {},
33
+ ssh_options: value[:ssh_options],
34
34
  )
35
35
  end
36
36
  end
data/lib/hocho/runner.rb CHANGED
@@ -16,7 +16,7 @@ module Hocho
16
16
  attr_reader :host, :driver, :base_dir, :initializers
17
17
 
18
18
  def run(dry_run: false)
19
- puts "Running using #{best_driver_name}"
19
+ puts "=> Running on #{host.name} using #{best_driver_name}"
20
20
  driver_options = @driver_options[best_driver_name] || {}
21
21
  driver = best_driver.new(host, base_dir: base_dir, initializers: initializers, **driver_options)
22
22
  driver.run(dry_run: dry_run)
@@ -1,6 +1,7 @@
1
1
  module Hocho
2
2
  module Utils
3
3
  module Finder
4
+ class NotFound < StandardError; end
4
5
  def self.find(const, prefix, name)
5
6
  retried = false
6
7
  constant_name = name.to_s.gsub(/\A.|_./) { |s| s[-1].upcase }
@@ -17,8 +18,7 @@ module Hocho
17
18
  retried = true
18
19
  retry
19
20
  end
20
-
21
- nil
21
+ raise NotFound, "Couldn't find #{prefix}/#{name}"
22
22
  end
23
23
  end
24
24
  end
data/lib/hocho/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Hocho
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hocho
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sorah (Shota Fukumori)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-10 00:00:00.000000000 Z
11
+ date: 2019-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -167,8 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
167
  - !ruby/object:Gem::Version
168
168
  version: '0'
169
169
  requirements: []
170
- rubyforge_project:
171
- rubygems_version: 2.7.6
170
+ rubygems_version: 3.0.1
172
171
  signing_key:
173
172
  specification_version: 4
174
173
  summary: Server provisioning tool with itamae