kontena-cli 1.4.0.pre7 → 1.4.0.pre8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/kontena/cli/services/deploy_command.rb +2 -1
- data/lib/kontena/cli/services/services_helper.rb +2 -1
- data/lib/kontena/cli/stacks/common.rb +36 -3
- data/lib/kontena/cli/stacks/deploy_command.rb +1 -1
- data/lib/kontena/cli/stacks/install_command.rb +2 -0
- data/lib/kontena/cli/stacks/upgrade_command.rb +2 -0
- data/lib/kontena/cli/stacks/validate_command.rb +2 -0
- data/lib/kontena/cli/stacks/yaml/custom_validators/hooks_validator.rb +43 -1
- data/lib/kontena/cli/stacks/yaml/reader.rb +25 -22
- data/lib/kontena/cli/stacks/yaml/stack_file_loader/file_loader.rb +1 -1
- data/spec/kontena/cli/stacks/common_spec.rb +29 -5
- data/spec/kontena/cli/stacks/install_command_spec.rb +99 -1
- data/spec/kontena/cli/stacks/yaml/reader_spec.rb +21 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5fbe13d6c43974ce734828c192b42c582b56a04
|
4
|
+
data.tar.gz: a2de0cbe2555ea75327028a9f1f6417f839a876f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ed72921adf1a691ed03ea9ec1223800191136b686d89c0e1ca2af21306755e83cb9844c69db3831da566a1592d700d12c2126a99ae9f620c1817d0bf3ce6441
|
7
|
+
data.tar.gz: f1fd2b0a344552704f2e3c1de967daed63e9cf66532791af1040aea5f19262b7b123b2ee1f19d1799525cb02556784192fa9329b2e68a00636cfebc01c31463d
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.4.0.
|
1
|
+
1.4.0.pre8
|
@@ -7,6 +7,7 @@ module Kontena::Cli::Services
|
|
7
7
|
include ServicesHelper
|
8
8
|
|
9
9
|
parameter "NAME", "Service name"
|
10
|
+
option '--[no-]wait', :flag, 'Do not wait for service deployment', default: true
|
10
11
|
option '--force', :flag, 'Force deploy even if service does not have any changes'
|
11
12
|
|
12
13
|
def execute
|
@@ -17,7 +18,7 @@ module Kontena::Cli::Services
|
|
17
18
|
data[:force] = true if force?
|
18
19
|
spinner "Deploying service #{name.colorize(:cyan)} " do
|
19
20
|
deployment = deploy_service(token, name, data)
|
20
|
-
wait_for_deploy_to_finish(token, deployment)
|
21
|
+
wait_for_deploy_to_finish(token, deployment) if wait?
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -94,9 +94,17 @@ module Kontena::Cli::Stacks
|
|
94
94
|
def self.included(where)
|
95
95
|
where.prepend InstanceMethods
|
96
96
|
|
97
|
-
where.option '--values-from', '[FILE]', 'Read variable values from YAML' do |filename|
|
97
|
+
where.option '--values-from', '[FILE]', 'Read variable values from a YAML file', multivalued: true do |filename|
|
98
98
|
values_from_file.merge!(::YAML.safe_load(File.read(filename)))
|
99
|
-
|
99
|
+
filename
|
100
|
+
end
|
101
|
+
|
102
|
+
where.option '--values-from-stack', '[STACK_NAME]', 'Read variable values from an installed stack', multivalued: true do |stackname|
|
103
|
+
variables = read_values_from_stacks(stackname)
|
104
|
+
Kontena.logger.debug { "Received variables from stack #{stackname} on Master: #{variables.inspect}" }
|
105
|
+
warn "Stack #{stackname} does not have any values for variables" if variables.empty?
|
106
|
+
values_from_installed_stacks.merge!(variables)
|
107
|
+
stackname
|
100
108
|
end
|
101
109
|
|
102
110
|
where.option '-v', "VARIABLE=VALUE", "Set stack variable values, example: -v domain=example.com. Can be used multiple times.", multivalued: true, attribute_name: :var_option do |var_pair|
|
@@ -106,6 +114,27 @@ module Kontena::Cli::Stacks
|
|
106
114
|
end
|
107
115
|
|
108
116
|
module InstanceMethods
|
117
|
+
def read_values_from_stacks(stackname)
|
118
|
+
result = {}
|
119
|
+
response = client.get("stacks/#{current_grid}/#{stackname}")
|
120
|
+
result.merge!(response['variables']) if response['variables']
|
121
|
+
if response['children']
|
122
|
+
response['children'].each do |child_info|
|
123
|
+
result.merge!(
|
124
|
+
read_values_from_stacks(child_info['name']).tap do |child_result|
|
125
|
+
child_result.keys.each do |key|
|
126
|
+
new_key = child_info['name'].dup # foofoo-redis-monitor
|
127
|
+
new_key.sub!("#{stackname}-", '') # monitor
|
128
|
+
new_key.concat ".#{key}" # monitor.foovariable
|
129
|
+
child_result[new_key] = child_result.delete(key)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
result
|
136
|
+
end
|
137
|
+
|
109
138
|
def values_from_file
|
110
139
|
@values_from_file ||= {}
|
111
140
|
end
|
@@ -114,8 +143,12 @@ module Kontena::Cli::Stacks
|
|
114
143
|
@values_from_value_options ||= {}
|
115
144
|
end
|
116
145
|
|
146
|
+
def values_from_installed_stacks
|
147
|
+
@values_from_installed_stacks ||= {}
|
148
|
+
end
|
149
|
+
|
117
150
|
def values_from_options
|
118
|
-
@values_from_options ||= values_from_file.merge(values_from_value_options)
|
151
|
+
@values_from_options ||= values_from_installed_stacks.merge(values_from_file).merge(values_from_value_options)
|
119
152
|
end
|
120
153
|
|
121
154
|
# Transforms a hash
|
@@ -10,7 +10,7 @@ module Kontena::Cli::Stacks
|
|
10
10
|
|
11
11
|
parameter "NAME", "Stack name"
|
12
12
|
|
13
|
-
option '--[no-]wait', :flag, 'Do not wait service deployment', default: true
|
13
|
+
option '--[no-]wait', :flag, 'Do not wait for service deployment', default: true
|
14
14
|
|
15
15
|
requires_current_master
|
16
16
|
requires_current_master_token
|
@@ -139,9 +139,11 @@ module Kontena::Cli::Stacks
|
|
139
139
|
else
|
140
140
|
cmd = ['stack', 'install', '--name', stackname]
|
141
141
|
cmd.concat ['--parent-name', stack['parent_name']] if stack['parent_name']
|
142
|
+
|
142
143
|
stack['variables'].merge(dependency_values_from_options(stackname)).each do |k, v|
|
143
144
|
cmd.concat ['-v', "#{k}=#{v}"]
|
144
145
|
end
|
146
|
+
|
145
147
|
cmd << '--no-deploy'
|
146
148
|
cmd << data[:local][:loader].source
|
147
149
|
caret "Installing new dependency #{cmd.last} as #{stackname}"
|
@@ -51,6 +51,8 @@ module Kontena::Cli::Stacks
|
|
51
51
|
|
52
52
|
validate_dependencies if dependencies?
|
53
53
|
|
54
|
+
stack # runs validations
|
55
|
+
|
54
56
|
hint_on_validation_notifications(reader.notifications, dependencies? ? loader.source : nil)
|
55
57
|
abort_on_validation_errors(reader.errors, dependencies? ? loader.source : nil)
|
56
58
|
|
@@ -11,7 +11,7 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
11
11
|
end
|
12
12
|
|
13
13
|
value.keys.each do |hook|
|
14
|
-
unless %w(pre_build post_start).include?(hook)
|
14
|
+
unless %w(pre_build pre_start post_start pre_stop).include?(hook)
|
15
15
|
errors[key] = "invalid hook #{hook}"
|
16
16
|
end
|
17
17
|
end
|
@@ -20,9 +20,17 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
20
20
|
validate_pre_build_hooks(key, value['pre_build'], errors)
|
21
21
|
end
|
22
22
|
|
23
|
+
if value['pre_start']
|
24
|
+
validate_pre_start_hooks(key, value['pre_start'], errors)
|
25
|
+
end
|
26
|
+
|
23
27
|
if value['post_start']
|
24
28
|
validate_post_start_hooks(key, value['post_start'], errors)
|
25
29
|
end
|
30
|
+
|
31
|
+
if value['pre_stop']
|
32
|
+
validate_pre_stop_hooks(key, value['pre_stop'], errors)
|
33
|
+
end
|
26
34
|
end
|
27
35
|
|
28
36
|
def validate_pre_build_hooks(key, pre_build_hooks, errors)
|
@@ -40,6 +48,23 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
40
48
|
end
|
41
49
|
end
|
42
50
|
|
51
|
+
def validate_pre_start_hooks(key, pre_start_hooks, errors)
|
52
|
+
unless pre_start_hooks.is_a?(Array)
|
53
|
+
errors[key] = { 'pre_start' => 'must be an array' }
|
54
|
+
return
|
55
|
+
end
|
56
|
+
pre_start_validation = {
|
57
|
+
'name' => 'string',
|
58
|
+
'instances' => (-> (value) { value.is_a?(Integer) || value == '*' }),
|
59
|
+
'cmd' => 'string',
|
60
|
+
'oneshot' => HashValidator.optional('boolean')
|
61
|
+
}
|
62
|
+
validator = HashValidator.validator_for(pre_start_validation)
|
63
|
+
pre_start_hooks.each do |pre_start|
|
64
|
+
validator.validate('hooks.pre_start', pre_start, pre_start_validation, errors)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
43
68
|
def validate_post_start_hooks(key, post_start_hooks, errors)
|
44
69
|
unless post_start_hooks.is_a?(Array)
|
45
70
|
errors[key] = { 'post_start' => 'must be an array' }
|
@@ -56,5 +81,22 @@ module Kontena::Cli::Stacks::YAML::Validations::CustomValidators
|
|
56
81
|
validator.validate('hooks.post_start', post_start, post_start_validation, errors)
|
57
82
|
end
|
58
83
|
end
|
84
|
+
|
85
|
+
def validate_pre_stop_hooks(key, pre_stop_hooks, errors)
|
86
|
+
unless pre_stop_hooks.is_a?(Array)
|
87
|
+
errors[key] = { 'pre_stop' => 'must be an array' }
|
88
|
+
return
|
89
|
+
end
|
90
|
+
pre_stop_validation = {
|
91
|
+
'name' => 'string',
|
92
|
+
'instances' => (-> (value) { value.is_a?(Integer) || value == '*' }),
|
93
|
+
'cmd' => 'string',
|
94
|
+
'oneshot' => HashValidator.optional('boolean')
|
95
|
+
}
|
96
|
+
validator = HashValidator.validator_for(pre_stop_validation)
|
97
|
+
pre_stop_hooks.each do |pre_stop|
|
98
|
+
validator.validate('hooks.pre_stop', pre_stop, pre_stop_validation, errors)
|
99
|
+
end
|
100
|
+
end
|
59
101
|
end
|
60
102
|
end
|
@@ -201,21 +201,26 @@ module Kontena::Cli::Stacks
|
|
201
201
|
|
202
202
|
validate unless skip_validation
|
203
203
|
|
204
|
-
{}
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
204
|
+
result = {}
|
205
|
+
Dir.chdir(from_file? ? File.dirname(File.expand_path(file)) : Dir.pwd) do
|
206
|
+
result['stack'] = raw_yaml['stack']
|
207
|
+
result['version'] = loader.stack_name.version || '0.0.1'
|
208
|
+
result['name'] = name
|
209
|
+
result['registry'] = loader.registry
|
210
|
+
result['expose'] = fully_interpolated_yaml['expose']
|
211
|
+
result['services'] = errors.empty? ? parse_services(service_name) : {}
|
212
|
+
result['volumes'] = errors.empty? ? parse_volumes : {}
|
213
|
+
result['dependencies'] = dependencies
|
214
|
+
result['source'] = raw_content
|
215
|
+
result['variables'] = variable_values(without_defaults: true, without_vault: true)
|
216
|
+
result['parent_name'] = parent_name
|
217
|
+
end
|
218
|
+
if service_name.nil?
|
219
|
+
result['services'].each do |service|
|
220
|
+
errors << { 'services' => { service['name'] => { 'image' => "image is missing" } } } if service['image'].to_s.empty?
|
217
221
|
end
|
218
222
|
end
|
223
|
+
result
|
219
224
|
end
|
220
225
|
|
221
226
|
# Returns an array of hashes containing the dependency tree starting from this file
|
@@ -317,7 +322,6 @@ module Kontena::Cli::Stacks
|
|
317
322
|
service_config.delete('extends')
|
318
323
|
end
|
319
324
|
if name
|
320
|
-
exit_with_error("Image is missing for #{name}. Aborting.") unless service_config['image'] # why isn't this a validation?
|
321
325
|
ServiceGeneratorV2.new(service_config).generate.merge('name' => name)
|
322
326
|
else
|
323
327
|
ServiceGeneratorV2.new(service_config).generate
|
@@ -345,10 +349,10 @@ module Kontena::Cli::Stacks
|
|
345
349
|
end
|
346
350
|
|
347
351
|
def from_external_file(filename, service_name)
|
348
|
-
external_reader =
|
352
|
+
external_reader = FileLoader.new(filename, loader).reader
|
349
353
|
outcome = external_reader.execute(service_name)
|
350
|
-
errors.concat external_reader.errors unless errors.
|
351
|
-
notifications.concat external_reader.notifications unless notifications.
|
354
|
+
errors.concat external_reader.errors unless external_reader.errors.empty? || errors.include?(external_reader.errors)
|
355
|
+
notifications.concat external_reader.notifications unless external_reader.notifications.empty? || notifications.include?(external_reader.notifications)
|
352
356
|
outcome['services']
|
353
357
|
end
|
354
358
|
|
@@ -445,13 +449,12 @@ module Kontena::Cli::Stacks
|
|
445
449
|
end
|
446
450
|
|
447
451
|
def store_failures(data)
|
448
|
-
data['errors']
|
449
|
-
data['notifications']
|
450
|
-
errors << { file => data['errors']
|
451
|
-
notifications << { file => data['notifications'] } unless data['notifications'].empty?
|
452
|
+
data['errors'] ||= data[:errors] || []
|
453
|
+
data['notifications'] ||= data[:notifications] || []
|
454
|
+
errors << { File.basename(file) => data['errors'] } unless data['errors'].empty?
|
455
|
+
notifications << { File.basename(file) => data['notifications'] } unless data['notifications'].empty?
|
452
456
|
end
|
453
457
|
|
454
|
-
|
455
458
|
# @param [Hash] options - service config
|
456
459
|
def normalize_env_vars(options)
|
457
460
|
if options['environment'].kind_of?(Hash)
|
@@ -3,6 +3,10 @@ require "kontena/cli/stacks/yaml/reader"
|
|
3
3
|
|
4
4
|
describe Kontena::Cli::Stacks::Common do
|
5
5
|
include FixturesHelpers
|
6
|
+
include RequirementsHelper
|
7
|
+
include ClientHelpers
|
8
|
+
|
9
|
+
mock_current_master
|
6
10
|
|
7
11
|
let(:klass) do
|
8
12
|
Class.new(Kontena::Command) do
|
@@ -12,10 +16,6 @@ describe Kontena::Cli::Stacks::Common do
|
|
12
16
|
include Kontena::Cli::Stacks::Common::StackNameOption
|
13
17
|
include Kontena::Cli::Stacks::Common::StackValuesToOption
|
14
18
|
include Kontena::Cli::Stacks::Common::StackValuesFromOption
|
15
|
-
|
16
|
-
def what
|
17
|
-
[source]
|
18
|
-
end
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -57,7 +57,7 @@ describe Kontena::Cli::Stacks::Common do
|
|
57
57
|
expect(subject.instance(['-v', 'foo=bar', '-v', 'bar=baz', fixture_path('kontena_v3.yml')]).values_from_options).to match hash_including('foo' => 'bar', 'bar' => 'baz')
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
describe '--values-from' do
|
61
61
|
before do
|
62
62
|
allow(File).to receive(:exist?).with('vars.yml').and_return(true)
|
63
63
|
expect(File).to receive(:read).with('vars.yml').and_return(::YAML.dump('baz' => 'bag', 'bar' => 'boo'))
|
@@ -71,5 +71,29 @@ describe Kontena::Cli::Stacks::Common do
|
|
71
71
|
expect(subject.instance(['-v', 'foo=bar', '-v', 'bar=baz', '--values-from', 'vars.yml', fixture_path('kontena_v3.yml')]).values_from_options).to match hash_including('foo' => 'bar', 'bar' => 'baz', 'baz' => 'bag')
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
describe '--values-from-stack' do
|
76
|
+
let(:instance) { subject.instance(['--values-from-stack', 'redisproxy', fixture_path('kontena_v3.yml')]) }
|
77
|
+
|
78
|
+
it 'reads all dependent stack variables' do
|
79
|
+
expect(client).to receive(:get).with('stacks/test-grid/redisproxy').and_return(
|
80
|
+
'variables' => { 'foo' => 'bar' },
|
81
|
+
'children' => [ { 'name' => 'redisproxy-redis1' } ]
|
82
|
+
)
|
83
|
+
|
84
|
+
expect(client).to receive(:get).with('stacks/test-grid/redisproxy-redis1').and_return(
|
85
|
+
'variables' => { 'redisvar' => 'test' },
|
86
|
+
'children' => [ { 'name' => 'redisproxy-redis1-monitor' } ]
|
87
|
+
)
|
88
|
+
|
89
|
+
expect(client).to receive(:get).with('stacks/test-grid/redisproxy-redis1-monitor').and_return(
|
90
|
+
'variables' => { 'monitorvar' => 'test2' },
|
91
|
+
'children' => []
|
92
|
+
)
|
93
|
+
|
94
|
+
expect(instance.values_from_options).to match hash_including('foo' => 'bar', 'redis1.redisvar' => 'test', 'redis1.monitor.monitorvar' => 'test2')
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
74
98
|
end
|
75
99
|
end
|
@@ -65,7 +65,7 @@ describe Kontena::Cli::Stacks::InstallCommand do
|
|
65
65
|
context '--[no-]deploy' do
|
66
66
|
it 'runs deploy for the stack after install by default' do
|
67
67
|
expect(client).to receive(:post).with(
|
68
|
-
|
68
|
+
'grids/test-grid/stacks', hash_including(stack_expectation)
|
69
69
|
)
|
70
70
|
expect(Kontena).to receive(:run!).with(['stack', 'deploy', 'stackname']).and_return(true)
|
71
71
|
subject.run([fixture_path('kontena_v3.yml')])
|
@@ -82,4 +82,102 @@ describe Kontena::Cli::Stacks::InstallCommand do
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
context 'variable value input' do
|
87
|
+
let(:expectation) do
|
88
|
+
{
|
89
|
+
'services' => array_including(
|
90
|
+
hash_including(
|
91
|
+
'name' => 'mysql',
|
92
|
+
'image' => 'mysqlimage:latest',
|
93
|
+
'env' => array_including(
|
94
|
+
'TEST_VAR=abc'
|
95
|
+
)
|
96
|
+
),
|
97
|
+
hash_including(
|
98
|
+
'name' => 'wordpress',
|
99
|
+
'image' => 'wordpress:def'
|
100
|
+
)
|
101
|
+
)
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '--values-from' do
|
106
|
+
it 'sends stack to master, loading values from a file' do
|
107
|
+
allow(File).to receive(:exist?).with('values.yml').and_return(true)
|
108
|
+
expect(File).to receive(:read).with('values.yml').and_return(
|
109
|
+
YAML.dump('TEST_ENV_VAR' => 'abc', 'MYSQL_IMAGE' => 'mysqlimage', 'tag' => 'def')
|
110
|
+
)
|
111
|
+
expect(client).to receive(:post) do |path, data|
|
112
|
+
expect(path).to eq 'grids/test-grid/stacks'
|
113
|
+
expect(data).to match hash_including(expectation)
|
114
|
+
end.and_return({})
|
115
|
+
subject.run(['--no-deploy', '--values-from', 'values.yml', fixture_path('stack-with-variables.yml')])
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '--values-from-stack' do
|
120
|
+
it 'sends stack to master, loading values from another stack on master' do
|
121
|
+
expect(client).to receive(:get).with('stacks/test-grid/otherdep').and_return(
|
122
|
+
'variables' => { 'foo' => 'bar' },
|
123
|
+
'children' => [
|
124
|
+
{ 'name' => 'otherdep-dep_1' } ,
|
125
|
+
{ 'name' => 'otherdep-dep_2' }
|
126
|
+
]
|
127
|
+
)
|
128
|
+
|
129
|
+
expect(client).to receive(:get).with('stacks/test-grid/otherdep-dep_1').and_return(
|
130
|
+
'variables' => { 'dep1var' => 'test' },
|
131
|
+
'children' => [
|
132
|
+
{ 'name' => 'otherdep-dep_1-dep_1' }
|
133
|
+
]
|
134
|
+
)
|
135
|
+
|
136
|
+
expect(client).to receive(:get).with('stacks/test-grid/otherdep-dep_1-dep_1').and_return(
|
137
|
+
'variables' => { 'dep1dep1var' => 'test11' },
|
138
|
+
'children' => []
|
139
|
+
)
|
140
|
+
|
141
|
+
expect(client).to receive(:get).with('stacks/test-grid/otherdep-dep_2').and_return(
|
142
|
+
'variables' => { 'dep2var' => 'test2' },
|
143
|
+
'children' => [ ]
|
144
|
+
)
|
145
|
+
|
146
|
+
expect(Kontena).to receive(:run!).with(["stack", "install", "-n", "deptest-dep_1", "--parent-name", "deptest", '-v', 'dep1var=test', '-v', 'dep_1.dep1dep1var=test11', '--no-deploy', fixture_path('stack-with-dependencies-dep-1.yml')]).and_return(true)
|
147
|
+
expect(Kontena).to receive(:run!).with(["stack", "install", "-n", "deptest-dep_2", "--parent-name", "deptest", '-v', 'dep_var=1', '-v', 'dep2var=test2', '--no-deploy', fixture_path('stack-with-dependencies-dep-2.yml')]).and_return(true)
|
148
|
+
|
149
|
+
allow(client).to receive(:post).and_return({})
|
150
|
+
|
151
|
+
subject.run(['--values-from-stack', 'otherdep', '-n', 'deptest', '--no-deploy', fixture_path('stack-with-dependencies.yml')])
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '-v' do
|
156
|
+
it 'sends stack to master, loading values from command line' do
|
157
|
+
expect(client).to receive(:post) do |path, data|
|
158
|
+
expect(path).to eq 'grids/test-grid/stacks'
|
159
|
+
expect(data).to match hash_including(expectation)
|
160
|
+
end.and_return({})
|
161
|
+
YAML.dump('TEST_ENV_VAR' => 'abc', 'MYSQL_IMAGE' => 'mysqlimage', 'tag' => 'def')
|
162
|
+
subject.run(['--no-deploy', '-v', 'TEST_ENV_VAR=abc', '-v', 'MYSQL_IMAGE=mysqlimage', '-v', 'tag=def', fixture_path('stack-with-variables.yml')])
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe 'combination of value inputs' do
|
167
|
+
it 'can combine multiple inputs' do
|
168
|
+
allow(File).to receive(:exist?).with('values.yml').and_return(true)
|
169
|
+
expect(File).to receive(:read).with('values.yml').and_return(
|
170
|
+
YAML.dump('TEST_ENV_VAR' => 'abc')
|
171
|
+
)
|
172
|
+
allow(client).to receive(:get).with('stacks/test-grid/foostack').and_return(
|
173
|
+
'variables' => { 'MYSQL_IMAGE' => 'mysqlimage' }
|
174
|
+
)
|
175
|
+
expect(client).to receive(:post) do |path, data|
|
176
|
+
expect(path).to eq 'grids/test-grid/stacks'
|
177
|
+
expect(data).to match hash_including(expectation)
|
178
|
+
end.and_return({})
|
179
|
+
subject.run(['--no-deploy', '--values-from-stack', 'foostack', '--values-from', 'values.yml', '-v', 'tag=def', fixture_path('stack-with-variables.yml')])
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
85
183
|
end
|
@@ -120,17 +120,15 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
120
120
|
it 'merges validation errors' do
|
121
121
|
expect(File).to receive(:read).with(fixture_path('docker-compose_v2.yml')).and_return(fixture('docker-compose-invalid.yml'))
|
122
122
|
outcome = subject.execute
|
123
|
-
expect(
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
'wordpress' => {
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
]
|
133
|
-
}])
|
123
|
+
expect(subject.errors).to match array_including(
|
124
|
+
hash_including(
|
125
|
+
'docker-compose_v2.yml' => array_including(
|
126
|
+
hash_including(
|
127
|
+
'services' => { 'wordpress' => { 'networks' => 'key not expected' } }
|
128
|
+
)
|
129
|
+
)
|
130
|
+
)
|
131
|
+
)
|
134
132
|
end
|
135
133
|
end
|
136
134
|
|
@@ -324,7 +322,12 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
324
322
|
|
325
323
|
it 'expands build option to absolute path' do
|
326
324
|
outcome = subject.execute
|
327
|
-
expect(outcome['services']
|
325
|
+
expect(outcome['services']).to match array_including(
|
326
|
+
hash_including(
|
327
|
+
'name' => 'webapp',
|
328
|
+
'build' => hash_including('context' => fixture_path(''))
|
329
|
+
)
|
330
|
+
)
|
328
331
|
end
|
329
332
|
end
|
330
333
|
|
@@ -335,7 +338,12 @@ describe Kontena::Cli::Stacks::YAML::Reader do
|
|
335
338
|
|
336
339
|
it 'expands build context to absolute path' do
|
337
340
|
outcome = subject.execute
|
338
|
-
expect(outcome['services']
|
341
|
+
expect(outcome['services']).to match array_including(
|
342
|
+
hash_including(
|
343
|
+
'name' => 'webapp',
|
344
|
+
'build' => hash_including('context' => fixture_path(''))
|
345
|
+
)
|
346
|
+
)
|
339
347
|
end
|
340
348
|
end
|
341
349
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kontena-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.0.
|
4
|
+
version: 1.4.0.pre8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kontena, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|