cartage-remote 1.1 → 2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Contributing.md +68 -0
- data/{History.rdoc → History.md} +11 -0
- data/{Licence.rdoc → Licence.md} +5 -5
- data/Manifest.txt +8 -9
- data/README.rdoc +29 -10
- data/Rakefile +47 -30
- data/lib/cartage/commands/remote.rb +48 -0
- data/lib/cartage/plugins/remote.rb +475 -0
- data/lib/cartage/remote/host.rb +101 -0
- data/test/minitest_config.rb +11 -0
- data/test/test_cartage_remote.rb +110 -0
- metadata +74 -35
- data/.autotest +0 -27
- data/.gemtest +0 -1
- data/.minitest.rb +0 -2
- data/Contributing.rdoc +0 -63
- data/Gemfile +0 -9
- data/lib/cartage/remote.rb +0 -419
- data/lib/cartage/remote/command.rb +0 -22
@@ -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:
|
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:
|
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:
|
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:
|
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: '
|
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: '
|
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.
|
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.
|
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-
|
168
|
+
name: hoe-travis
|
141
169
|
requirement: !ruby/object:Gem::Requirement
|
142
170
|
requirements:
|
143
171
|
- - "~>"
|
144
172
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
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: '
|
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.
|
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.
|
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.
|
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.
|
266
|
-
- History.
|
267
|
-
- Licence.
|
305
|
+
- Contributing.md
|
306
|
+
- History.md
|
307
|
+
- Licence.md
|
268
308
|
- Manifest.txt
|
269
309
|
- README.rdoc
|
270
310
|
files:
|
271
|
-
-
|
272
|
-
-
|
273
|
-
-
|
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
|
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:
|
341
|
+
version: 1.3.1
|
303
342
|
requirements: []
|
304
343
|
rubyforge_project:
|
305
|
-
rubygems_version: 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]
|