cartage-remote 1.1 → 2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # The Host which remote commands will be run on.
5
+ class Cartage::Remote::Host
6
+ # The user on the remote host.
7
+ attr_reader :user
8
+ # The address of the remote host.
9
+ attr_reader :address
10
+ # The port of the SSH connection to the remote host.
11
+ attr_reader :port
12
+
13
+ # The (optional) build script defined as part of this host.
14
+ attr_reader :build
15
+ # The (optional) prebuild script defined as part of this host.
16
+ attr_reader :prebuild
17
+ # The (optional) postbuild script defined as part of this host.
18
+ attr_reader :postbuild
19
+
20
+ # The Fog::SSH instance for this server. Must run #configure_ssh before
21
+ # using.
22
+ attr_reader :ssh
23
+ # The Fog::SCP instance for this server. Must run #configure_ssh before
24
+ # using.
25
+ attr_reader :scp
26
+
27
+ HOST_RE = /\A(?:(?<user>[^@]+)@)?(?<address>[^@:]+)(?::(?<port>[^:]+))?\z/
28
+
29
+ # Initialize the Host from a +host+ object (an OpenStruct from a parsed
30
+ # Cartage configuration) or a +host+ string (<tt>[user@]address[:port]</tt>).
31
+ #
32
+ # If +ssh_config+ is provided, prepare the SSH connections.
33
+ def initialize(host, ssh_config = nil)
34
+ @keys = @key_data = @build = @prebuild = @postbuild = nil
35
+
36
+ case host
37
+ when OpenStruct
38
+ @user = host.user
39
+ @address = host.address || host.host
40
+ @port = host.port
41
+
42
+ if host.keys.kind_of?(OpenStruct)
43
+ @key_data = host.keys.to_h.values
44
+ else
45
+ @keys = Array(host.keys).flat_map { |key|
46
+ Pathname.glob(Pathname(key).expand_path)
47
+ }
48
+ end
49
+ @build = host.build
50
+ @prebuild = host.prebuild
51
+ @postbuild = host.postbuild
52
+ when HOST_RE
53
+ @user = Regexp.last_match[:user]
54
+ @address = Regexp.last_match[:address]
55
+ @port = Regexp.last_match[:port]
56
+ end
57
+
58
+ if address.nil? || address.empty?
59
+ fail ArgumentError, 'Invalid remote host, no address specified.'
60
+ end
61
+
62
+ @user = ENV['USER'] if user.nil? || user.empty?
63
+
64
+ configure_ssh(ssh_config) if ssh_config
65
+ end
66
+
67
+ # Configure the Fog::SSH and Fog::SCP connections using the provided
68
+ # ssh_config.
69
+ def configure_ssh(ssh_config)
70
+ require 'fog'
71
+
72
+ if @key_data
73
+ ssh_config[:key_data] = @key_data
74
+ ssh_config[:keys] = nil
75
+ elsif @keys
76
+ ssh_config[:key_data] = nil
77
+ ssh_config[:keys] = @keys
78
+ end
79
+
80
+ options = { paranoid: true, port: port }.
81
+ merge(ssh_config).
82
+ delete_if { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }
83
+
84
+ @ssh = Fog::SSH.new(address, user, options)
85
+ @scp = Fog::SCP.new(address, user, options)
86
+ end
87
+
88
+ # This Host, formatted nicely.
89
+ def to_s
90
+ "#{user}@#{address}:#{port}".gsub(/^@|:$/, '')
91
+ end
92
+
93
+ # Convert this Host to a hash format.
94
+ def to_hash
95
+ {
96
+ user: user,
97
+ address: address,
98
+ port: port
99
+ }.delete_if { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) }
100
+ end
101
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem 'minitest'
4
+ require 'minitest/autorun'
5
+ require 'minitest/pretty_diff'
6
+ require 'minitest/focus'
7
+ require 'minitest/moar'
8
+ require 'minitest/bisect'
9
+ require 'minitest-bonus-assertions'
10
+
11
+ require 'cartage/minitest'
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest_config'
4
+
5
+ describe 'Cartage::Remote' do
6
+ let(:string_host) {
7
+ 'suser@saddress:sport'
8
+ }
9
+ let(:hash_host) {
10
+ {
11
+ user: 'huser',
12
+ address: 'haddress',
13
+ host: 'hhost',
14
+ port: 'hport'
15
+ }
16
+ }
17
+
18
+ let(:remote_config) {
19
+ {
20
+ hosts: {
21
+ default: hash_host
22
+ }
23
+ }
24
+ }
25
+ let(:config_hash) {
26
+ {
27
+ root_path: '/a/b/c',
28
+ name: 'test',
29
+ timestamp: 'value',
30
+ plugins: {
31
+ remote: remote_config
32
+ }
33
+ }
34
+ }
35
+ let(:config) { Cartage::Config.new(config_hash) }
36
+ let(:cartage) { Cartage.new(config) }
37
+ let(:subject) { cartage.remote }
38
+
39
+ def self.it_verifies_configuration(focus: false, &block)
40
+ self.focus if focus
41
+ it 'fails if there is no host with the given name' do
42
+ remote_config[:host] = 'foo'
43
+ ex = assert_raises RuntimeError do
44
+ instance_exec(&block)
45
+ end
46
+ assert_equal 'No host foo present', ex.message
47
+ end
48
+
49
+ self.focus if focus
50
+ it 'fails if there are no hosts present' do
51
+ remote_config[:hosts] = {}
52
+
53
+ ex = assert_raises ArgumentError do
54
+ instance_exec(&block)
55
+ end
56
+ assert_equal 'No hosts present', ex.message
57
+ end
58
+
59
+ self.focus if focus
60
+ it 'warns if a host is missing some configuration' do
61
+ remote_config[:hosts][:foo] = {}
62
+
63
+ error = <<-EOS
64
+ Host foo invalid: No host address present
65
+ EOS
66
+
67
+ assert_output nil, error do
68
+ instance_exec(&block)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe '#resolve_plugin_config!' do
74
+ it 'errors with implicit and explicit hosts' do
75
+ ex = assert_raises ArgumentError do
76
+ remote_config[:server] = 'something'
77
+ cartage
78
+ end
79
+
80
+ assert_match(/implicit and explicit/, ex.message)
81
+ end
82
+
83
+ it 'requires host address' do
84
+ remote_config.delete(:hosts)
85
+ remote_config[:server] = {}
86
+
87
+ ex = assert_raises ArgumentError do
88
+ cartage
89
+ end
90
+
91
+ assert_match(/no address/, ex.message)
92
+ end
93
+
94
+ it 'converts the implicit default into explicit' do
95
+ remote_config.delete(:hosts)
96
+ remote_config[:server] = hash_host
97
+
98
+ assert_equal remote_config[:hosts], cartage.config(for_plugin: :remote).
99
+ dig(:hosts).to_hash
100
+ end
101
+
102
+ it 'converts the implicit default into explicit' do
103
+ remote_config.delete(:hosts)
104
+ remote_config[:server] = hash_host
105
+
106
+ assert_equal remote_config[:hosts], cartage.config(for_plugin: :remote).
107
+ dig(:hosts).to_hash
108
+ end
109
+ end
110
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cartage-remote
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.1'
4
+ version: 2.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Austin Ziegler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-26 00:00:00.000000000 Z
11
+ date: 2016-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cartage
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.1'
19
+ version: 2.0.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.1'
26
+ version: 2.0.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: micromachine
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.2'
33
+ version: '2.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.2'
40
+ version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: fog
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,20 +52,48 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.27'
55
+ - !ruby/object:Gem::Dependency
56
+ name: net-ssh
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-scp
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.2'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.2'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: minitest
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '5.5'
89
+ version: '5.9'
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '5.5'
96
+ version: '5.9'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rdoc
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -84,14 +112,14 @@ dependencies:
84
112
  name: rake
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
- - - "~>"
115
+ - - ">="
88
116
  - !ruby/object:Gem::Version
89
117
  version: '10.0'
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
- - - "~>"
122
+ - - ">="
95
123
  - !ruby/object:Gem::Version
96
124
  version: '10.0'
97
125
  - !ruby/object:Gem::Dependency
@@ -137,19 +165,19 @@ dependencies:
137
165
  - !ruby/object:Gem::Version
138
166
  version: '1.5'
139
167
  - !ruby/object:Gem::Dependency
140
- name: hoe-geminabox
168
+ name: hoe-travis
141
169
  requirement: !ruby/object:Gem::Requirement
142
170
  requirements:
143
171
  - - "~>"
144
172
  - !ruby/object:Gem::Version
145
- version: '0.3'
173
+ version: '1.2'
146
174
  type: :development
147
175
  prerelease: false
148
176
  version_requirements: !ruby/object:Gem::Requirement
149
177
  requirements:
150
178
  - - "~>"
151
179
  - !ruby/object:Gem::Version
152
- version: '0.3'
180
+ version: '1.2'
153
181
  - !ruby/object:Gem::Dependency
154
182
  name: minitest-autotest
155
183
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +206,20 @@ dependencies:
178
206
  - - "~>"
179
207
  - !ruby/object:Gem::Version
180
208
  version: '1.2'
209
+ - !ruby/object:Gem::Dependency
210
+ name: minitest-bonus-assertions
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '2.0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '2.0'
181
223
  - !ruby/object:Gem::Dependency
182
224
  name: minitest-focus
183
225
  requirement: !ruby/object:Gem::Requirement
@@ -240,46 +282,43 @@ dependencies:
240
282
  requirements:
241
283
  - - "~>"
242
284
  - !ruby/object:Gem::Version
243
- version: '3.13'
285
+ version: '3.15'
244
286
  type: :development
245
287
  prerelease: false
246
288
  version_requirements: !ruby/object:Gem::Requirement
247
289
  requirements:
248
290
  - - "~>"
249
291
  - !ruby/object:Gem::Version
250
- version: '3.13'
292
+ version: '3.15'
251
293
  description: |-
252
294
  cartage-remote is a plug-in for {cartage}[https://github.com/KineticCafe/cartage]
253
295
  to build a package on a remote machine with cartage.
254
296
 
255
297
  Cartage provides a repeatable means to create a package for a Rails application
256
298
  that can be used in deployment with a configuration tool like Ansible, Chef,
257
- Puppet, or Salt. The package is created with its dependencies bundled in
258
- `vendor/bundle`, so it can be deployed in environments with strict access
259
- control rules and without requiring development tool access.
299
+ Puppet, or Salt.
260
300
  email:
261
301
  - aziegler@kineticcafe.com
262
302
  executables: []
263
303
  extensions: []
264
304
  extra_rdoc_files:
265
- - Contributing.rdoc
266
- - History.rdoc
267
- - Licence.rdoc
305
+ - Contributing.md
306
+ - History.md
307
+ - Licence.md
268
308
  - Manifest.txt
269
309
  - README.rdoc
270
310
  files:
271
- - ".autotest"
272
- - ".gemtest"
273
- - ".minitest.rb"
274
- - Contributing.rdoc
275
- - Gemfile
276
- - History.rdoc
277
- - Licence.rdoc
311
+ - Contributing.md
312
+ - History.md
313
+ - Licence.md
278
314
  - Manifest.txt
279
315
  - README.rdoc
280
316
  - Rakefile
281
- - lib/cartage/remote.rb
282
- - lib/cartage/remote/command.rb
317
+ - lib/cartage/commands/remote.rb
318
+ - lib/cartage/plugins/remote.rb
319
+ - lib/cartage/remote/host.rb
320
+ - test/minitest_config.rb
321
+ - test/test_cartage_remote.rb
283
322
  homepage: https://github.com/KineticCafe/cartage-remote/
284
323
  licenses:
285
324
  - MIT
@@ -292,17 +331,17 @@ require_paths:
292
331
  - lib
293
332
  required_ruby_version: !ruby/object:Gem::Requirement
294
333
  requirements:
295
- - - ">="
334
+ - - "~>"
296
335
  - !ruby/object:Gem::Version
297
- version: '0'
336
+ version: '2.0'
298
337
  required_rubygems_version: !ruby/object:Gem::Requirement
299
338
  requirements:
300
- - - ">="
339
+ - - ">"
301
340
  - !ruby/object:Gem::Version
302
- version: '0'
341
+ version: 1.3.1
303
342
  requirements: []
304
343
  rubyforge_project:
305
- rubygems_version: 2.2.2
344
+ rubygems_version: 2.6.4
306
345
  signing_key:
307
346
  specification_version: 4
308
347
  summary: cartage-remote is a plug-in for {cartage}[https://github.com/KineticCafe/cartage]