cartage-remote 1.1 → 2.0.rc1

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.
@@ -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]