kontena-cli 1.2.0 → 1.2.1.rc1
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/stacks/common.rb +1 -1
- data/lib/kontena/cli/stacks/yaml/reader.rb +3 -3
- data/lib/kontena/cli/stacks/yaml/validator_v3.rb +30 -11
- data/lib/kontena/command.rb +1 -0
- data/omnibus/config/software/kontena.rb +1 -0
- data/spec/kontena/cli/stacks/common_spec.rb +102 -0
- data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +19 -0
- data/spec/kontena/kontena_cli_spec.rb +8 -2
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b18a8f9e16992007d8e29291e6205621b696c764
|
4
|
+
data.tar.gz: b48e57f00c487866a628536651900c9ac85abc16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 791b963130649a9850ac5f953557a5c8334ec7b479106293180c9ad2383157709f1e3b82394d8c38fd819a3420d7c6f134fd8260d9f5ff1209d162975de41b0d
|
7
|
+
data.tar.gz: 861eeadeb19f458d1738c46f10dc8c8580f62958d419313f76d13c6be1c080a33c344fa178d8d21e14c2472c7edbd14d92217d6244e2726c6c805b28f3330a33
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.1.rc1
|
@@ -97,7 +97,7 @@ module Kontena::Cli::Stacks
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def stack_read_and_dump(filename, name: nil, values: nil, defaults: nil)
|
100
|
-
reader = reader_from_yaml(filename, name: name, values: values)
|
100
|
+
reader = reader_from_yaml(filename, name: name, values: values, defaults: defaults)
|
101
101
|
stack = stack_from_reader(reader)
|
102
102
|
dump_variables(reader) if values_to
|
103
103
|
stack
|
@@ -73,7 +73,7 @@ module Kontena::Cli::Stacks
|
|
73
73
|
warnings: false
|
74
74
|
)
|
75
75
|
)
|
76
|
-
)
|
76
|
+
) || {}
|
77
77
|
rescue Psych::SyntaxError => ex
|
78
78
|
raise ex, "Error while parsing #{file} : #{ex.message}"
|
79
79
|
end
|
@@ -92,13 +92,13 @@ module Kontena::Cli::Stacks
|
|
92
92
|
raise_on_unknown: true
|
93
93
|
)
|
94
94
|
)
|
95
|
-
)
|
95
|
+
) || {}
|
96
96
|
rescue Psych::SyntaxError => ex
|
97
97
|
raise ex, "Error while parsing #{file} : #{ex.message}"
|
98
98
|
end
|
99
99
|
|
100
100
|
def raw_yaml
|
101
|
-
@raw_yaml ||= ::YAML.safe_load(raw_content)
|
101
|
+
@raw_yaml ||= ::YAML.safe_load(raw_content) || {}
|
102
102
|
end
|
103
103
|
|
104
104
|
# @return [Opto::Group]
|
@@ -31,6 +31,24 @@ module Kontena::Cli::Stacks
|
|
31
31
|
Validations::CustomValidators.load
|
32
32
|
end
|
33
33
|
|
34
|
+
# borrowed from server/app/helpers/volumes_helpers.rb
|
35
|
+
def parse_volume(vol)
|
36
|
+
elements = vol.split(':')
|
37
|
+
if elements.size >= 2 # Bind mount or volume used
|
38
|
+
if elements[0].start_with?('/') && elements[1] && elements[1].start_with?('/') # Bind mount
|
39
|
+
{bind_mount: elements[0], path: elements[1], flags: elements[2..-1].join(',')}
|
40
|
+
elsif !elements[0].start_with?('/') && elements[1].start_with?('/') # Real volume
|
41
|
+
{volume: elements[0], path: elements[1], flags: elements[2..-1].join(',')}
|
42
|
+
else
|
43
|
+
{error: "volume definition not in right format: #{vol}" }
|
44
|
+
end
|
45
|
+
elsif elements.size == 1 && elements[0].start_with?('/') # anon volume
|
46
|
+
{bind_mount: nil, path: elements[0], flags: nil} # anon vols do not support flags
|
47
|
+
else
|
48
|
+
{error: "volume definition not in right format: #{vol}" }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
34
52
|
##
|
35
53
|
# @param [Hash] yaml
|
36
54
|
# @param [TrueClass|FalseClass] strict
|
@@ -55,18 +73,14 @@ module Kontena::Cli::Stacks
|
|
55
73
|
option_errors = validate_options(options)
|
56
74
|
result[:errors] << { 'services' => { service => option_errors.errors } } unless option_errors.valid?
|
57
75
|
if options['volumes']
|
58
|
-
|
59
|
-
mount_points.each do |mount_point, occurences|
|
60
|
-
next unless occurences > 1
|
61
|
-
result[:errors] << { 'services' => { service => { 'volumes' => { mount_point => "mount point defined #{occurences} times" } } } }
|
62
|
-
end
|
63
|
-
|
76
|
+
mount_path_occurences = Hash.new(0)
|
64
77
|
options['volumes'].each do |volume|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
78
|
+
parsed = parse_volume(volume)
|
79
|
+
if parsed[:error]
|
80
|
+
result[:errors] << { 'services' => { service => { 'volumes' => { volume => parsed[:error] } } } }
|
81
|
+
elsif parsed[:path]
|
82
|
+
mount_path_occurences[parsed[:path]] += 1
|
83
|
+
volume_name = parsed[:volume]
|
70
84
|
if volume_name && !volume_name.start_with?('/')
|
71
85
|
if yaml.key?('volumes')
|
72
86
|
unless yaml['volumes'][volume_name]
|
@@ -76,8 +90,13 @@ module Kontena::Cli::Stacks
|
|
76
90
|
result[:errors] << { 'services' => { service => { 'volumes' => { volume => 'defines volume name, but file does not contain volumes definitions' } } } }
|
77
91
|
end
|
78
92
|
end
|
93
|
+
else
|
94
|
+
result[:errors] << { 'services' => { service => { 'volumes' => { volume => 'mount point missing' } } } }
|
79
95
|
end
|
80
96
|
end
|
97
|
+
mount_path_occurences.select {|path, occurences| occurences > 1 }.each do |path, occurences|
|
98
|
+
result[:errors] << { 'services' => { service => { 'volumes' => { path => "mount point defined #{occurences} times" } } } }
|
99
|
+
end
|
81
100
|
end
|
82
101
|
end
|
83
102
|
else
|
data/lib/kontena/command.rb
CHANGED
@@ -210,6 +210,7 @@ class Kontena::Command < Clamp::Command
|
|
210
210
|
if ex.message.include?('Unable to verify certificate')
|
211
211
|
$stderr.puts " [#{Kontena.pastel.red('error')}] The server uses a certificate signed by an unknown authority."
|
212
212
|
$stderr.puts " You can trust this server by copying server CA pem file to: #{Kontena.pastel.yellow("~/.kontena/certs/<hostname>.pem")}"
|
213
|
+
$stderr.puts " If kontena cannot find your system ca bundle, you can set #{Kontena.pastel.yellow('SSL_CERT_DIR=/etc/ssl/certs')} env variable to load them from another location."
|
213
214
|
$stderr.puts " Protip: you can bypass the certificate check by setting #{Kontena.pastel.yellow('SSL_IGNORE_ERRORS=true')} env variable, but any data you send to the server could be intercepted by others."
|
214
215
|
abort
|
215
216
|
else
|
@@ -7,6 +7,7 @@ dependency "libxml2"
|
|
7
7
|
dependency "libxslt"
|
8
8
|
whitelist_file "./wrappers/sh/kontena"
|
9
9
|
build do
|
10
|
+
gem "install rb-readline -v 0.5.4 --no-ri --no-doc"
|
10
11
|
gem "install nokogiri -v 1.6.8 --no-ri --no-doc"
|
11
12
|
gem "install kontena-cli -v #{default_version} --no-ri --no-doc"
|
12
13
|
copy "sh/kontena", "#{install_dir}/bin/kontena"
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "kontena/cli/stacks/common"
|
2
|
+
require "kontena/cli/stacks/yaml/reader"
|
3
|
+
|
4
|
+
describe Kontena::Cli::Stacks::Common do
|
5
|
+
|
6
|
+
let(:klass) do
|
7
|
+
Class.new(Kontena::Command) do
|
8
|
+
include Kontena::Cli::Stacks::Common
|
9
|
+
include Kontena::Cli::Common
|
10
|
+
include Kontena::Cli::Stacks::Common::StackNameParam
|
11
|
+
include Kontena::Cli::Stacks::Common::StackFileOrNameParam
|
12
|
+
include Kontena::Cli::Stacks::Common::StackNameOption
|
13
|
+
include Kontena::Cli::Stacks::Common::StackValuesToOption
|
14
|
+
include Kontena::Cli::Stacks::Common::StackValuesFromOption
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:subject) { klass.new('') }
|
19
|
+
|
20
|
+
context 'stack yaml reader methods' do
|
21
|
+
let(:reader) { double(:reader) }
|
22
|
+
|
23
|
+
before(:each) do
|
24
|
+
allow(reader).to receive(:execute).and_return({ errors: [], notifications: [] })
|
25
|
+
allow(reader).to receive(:raw_content).and_return("")
|
26
|
+
allow(reader).to receive(:stack_name).and_return('foo')
|
27
|
+
allow(subject).to receive(:set_env_variables).and_return(true)
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#stack_read_and_dump' do
|
31
|
+
it 'passes args to reader' do
|
32
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).with('foo', values: { 'value' => 'value' }, defaults: { 'default' => 'default' }).and_return(reader)
|
33
|
+
subject.stack_read_and_dump('foo', name: 'name', values: { 'value' => 'value' }, defaults: { 'default' => 'default' })
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns a stack hash' do
|
37
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).and_return(reader)
|
38
|
+
expect(subject.stack_read_and_dump('foo')).to be_kind_of Hash
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#stack_from_yaml' do
|
43
|
+
it 'passes args to reader' do
|
44
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).with('foo', values: { 'value' => 'value' }, defaults: { 'default' => 'default' }).and_return(reader)
|
45
|
+
subject.stack_from_yaml('foo', name: 'name', values: { 'value' => 'value' }, defaults: { 'default' => 'default' })
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns a stack hash' do
|
49
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).and_return(reader)
|
50
|
+
expect(subject.stack_from_yaml('foo')).to be_kind_of Hash
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#reader_from_yaml' do
|
55
|
+
it 'passes args to reader' do
|
56
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).with('foo', values: { 'value' => 'value' }, defaults: { 'default' => 'default' }).and_return(reader)
|
57
|
+
subject.reader_from_yaml('foo', name: 'name', values: { 'value' => 'value' }, defaults: { 'default' => 'default' })
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns a reader' do
|
61
|
+
expect(Kontena::Cli::Stacks::YAML::Reader).to receive(:new).and_return(reader)
|
62
|
+
expect(subject.reader_from_yaml('foo')).to eq reader
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#stack_name' do
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#stack_from_reader' do
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#stack_from_yaml' do
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#require_config_file' do
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#generate_volumes' do
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#generate_services' do
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#set_env_variables' do
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#current_dir' do
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#display_notifications' do
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#hint_on_validation_notifications' do
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#abort_on_validation_errors' do
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#stacks_client' do
|
101
|
+
end
|
102
|
+
end
|
@@ -324,6 +324,7 @@ describe Kontena::Cli::Stacks::YAML::ValidatorV3 do
|
|
324
324
|
|
325
325
|
}
|
326
326
|
end
|
327
|
+
|
327
328
|
it 'fails validation if volumes are not declared' do
|
328
329
|
result = subject.validate(stack)
|
329
330
|
expect(result[:errors]).not_to be_empty
|
@@ -361,6 +362,24 @@ describe Kontena::Cli::Stacks::YAML::ValidatorV3 do
|
|
361
362
|
expect(result[:errors]).to be_empty
|
362
363
|
end
|
363
364
|
|
365
|
+
it 'validation passes when mount points are defined with :ro' do
|
366
|
+
stack['services']['foo']['volumes'] = ['/var/foo:/foo:ro', '/tmp/foo:/bar:ro']
|
367
|
+
result = subject.validate(stack)
|
368
|
+
expect(result[:errors]).to be_empty
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'validation fails when same mount point is defined multiple times' do
|
372
|
+
stack['services']['foo']['volumes'] = ['/var/foo:/foo', '/tmp/foo:/foo']
|
373
|
+
result = subject.validate(stack)
|
374
|
+
expect(result[:errors]).to include({"services"=>{"foo"=>{"volumes"=>{"/foo"=>"mount point defined 2 times"}}}})
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'validation fails when same mount point is defined multiple times mixing :ro' do
|
378
|
+
stack['services']['foo']['volumes'] = ['/var/foo:/foo', '/tmp/foo:/foo:ro']
|
379
|
+
result = subject.validate(stack)
|
380
|
+
expect(result[:errors]).to include({"services"=>{"foo"=>{"volumes"=>{"/foo"=>"mount point defined 2 times"}}}})
|
381
|
+
end
|
382
|
+
|
364
383
|
it 'bind mount do not need ext volumes' do
|
365
384
|
stack['services']['foo']['volumes'] = ['/var/run/docker.sock:/var/run/docker.sock']
|
366
385
|
result = subject.validate(stack)
|
@@ -12,10 +12,16 @@ describe Kontena do
|
|
12
12
|
Kontena.reset_prompt
|
13
13
|
end
|
14
14
|
|
15
|
-
it 'uses light prompt on
|
16
|
-
|
15
|
+
it 'uses light prompt on simple terminals' do
|
16
|
+
expect(ENV).to receive(:[]).with('KONTENA_SIMPLE_TERM').and_return('true')
|
17
17
|
expect(Kontena.prompt).to be_kind_of(Kontena::LightPrompt)
|
18
18
|
end
|
19
|
+
|
20
|
+
it 'uses fancy prompt on fancy terminals' do
|
21
|
+
expect($stdout).to receive(:tty?).at_least(:once).and_return(true)
|
22
|
+
expect(ENV).to receive(:[]).with('KONTENA_SIMPLE_TERM').and_return(nil)
|
23
|
+
expect(Kontena.prompt).to be_kind_of(TTY::Prompt)
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
describe '#minor_version' do
|
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.2.
|
4
|
+
version: 1.2.1.rc1
|
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-04-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -611,6 +611,7 @@ files:
|
|
611
611
|
- spec/kontena/cli/services/unlink_command_spec.rb
|
612
612
|
- spec/kontena/cli/services/update_command_spec.rb
|
613
613
|
- spec/kontena/cli/stacks/build_command_spec.rb
|
614
|
+
- spec/kontena/cli/stacks/common_spec.rb
|
614
615
|
- spec/kontena/cli/stacks/deploy_command_spec.rb
|
615
616
|
- spec/kontena/cli/stacks/events_command_spec.rb
|
616
617
|
- spec/kontena/cli/stacks/install_command_spec.rb
|
@@ -661,9 +662,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
661
662
|
version: 2.1.0
|
662
663
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
663
664
|
requirements:
|
664
|
-
- - "
|
665
|
+
- - ">"
|
665
666
|
- !ruby/object:Gem::Version
|
666
|
-
version:
|
667
|
+
version: 1.3.1
|
667
668
|
requirements: []
|
668
669
|
rubyforge_project:
|
669
670
|
rubygems_version: 2.6.8
|
@@ -756,6 +757,7 @@ test_files:
|
|
756
757
|
- spec/kontena/cli/services/unlink_command_spec.rb
|
757
758
|
- spec/kontena/cli/services/update_command_spec.rb
|
758
759
|
- spec/kontena/cli/stacks/build_command_spec.rb
|
760
|
+
- spec/kontena/cli/stacks/common_spec.rb
|
759
761
|
- spec/kontena/cli/stacks/deploy_command_spec.rb
|
760
762
|
- spec/kontena/cli/stacks/events_command_spec.rb
|
761
763
|
- spec/kontena/cli/stacks/install_command_spec.rb
|