kontena-cli 1.0.0 → 1.0.1.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 36c2e185f884687f6fe09fde71a6afc3a9217bae
4
- data.tar.gz: 9b91bec0786e2d8e0267ce3a606397dd872e2170
3
+ metadata.gz: c16073e087d4cdae97421bd4eb5e8dee42b65462
4
+ data.tar.gz: c6f92090afa63cd4f6a416f27823746138d63244
5
5
  SHA512:
6
- metadata.gz: d303382c55ea443921586f667a0c92defee60927d0a9e8894b2079be94864c39b6bc390161bfb6f9a0a54171fba346d00027127f96a60c48f76d7deaa25df073
7
- data.tar.gz: 5152e458b7fba018f77b975353992771ee25a2af3987514c8f395b60c92a0c6bd538b80c1a33df462ec8d25daf9e2e797656a22388a159c278d8f97691b8e955
6
+ metadata.gz: 743dd0816028f2ec8a2a4a2c9d96d3196af3354c00d804c8dd5e996878379c9e9d6329f38a74023c4e40aea9525b7acce8184917a04bf59c174eb5abd670e4b5
7
+ data.tar.gz: c801bd06d17d3f201222acc9a05494b692124fbd428a2cacc994faac08f0f3c2ceaebc5cd8ca125e7acf55ab9acacf3d5d9f04e3d7682fc2e9f16bab1401d35a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.0.1.rc1
@@ -29,8 +29,7 @@ module Kontena::Cli::Stacks
29
29
  if reader.stack_name.nil?
30
30
  exit_with_error "Stack MUST have stack name in YAML top level field 'stack'! Aborting."
31
31
  end
32
- set_env_variables(reader.stack_name, current_grid)
33
- #reader.reload
32
+ set_env_variables(reader.stack_name, current_grid)
34
33
  outcome = reader.execute
35
34
 
36
35
  hint_on_validation_notifications(outcome[:notifications]) if outcome[:notifications].size > 0
@@ -17,9 +17,7 @@ module Kontena::Cli::Stacks
17
17
  deployment = nil
18
18
  spinner "Deploying stack #{pastel.cyan(name)}" do
19
19
  deployment = deploy_stack(name)
20
- deployment['service_deploys'].each do |service_deploy|
21
- wait_for_deploy_to_finish(service_deploy)
22
- end
20
+ wait_for_deploy_to_finish(deployment)
23
21
  end
24
22
  end
25
23
 
@@ -31,14 +29,22 @@ module Kontena::Cli::Stacks
31
29
  # @return [Boolean]
32
30
  def wait_for_deploy_to_finish(deployment, timeout = 600)
33
31
  deployed = false
32
+ progress = []
33
+ states = %w(success error)
34
34
  Timeout::timeout(timeout) do
35
35
  until deployed
36
- deployment = client.get("services/#{deployment['service_id']}/deploys/#{deployment['id']}")
37
- deployed = true if deployment['finished_at']
36
+ deployment = client.get("stacks/#{deployment['stack_id']}/deploys/#{deployment['id']}")
37
+ deployed = true if states.include?(deployment['state'])
38
38
  sleep 1
39
39
  end
40
40
  if deployment['state'] == 'error'
41
- raise deployment['reason']
41
+ deployment['service_deploys'].each do |service_deploy|
42
+ if service_deploy['state'] == 'error'
43
+ puts " #{service_deploy['reason']}"
44
+ end
45
+ end
46
+
47
+ raise 'deploy failed'
42
48
  end
43
49
  end
44
50
 
@@ -7,19 +7,12 @@ module Kontena::Cli::Stacks
7
7
  banner "Shows logs from services in a stack"
8
8
 
9
9
  parameter "NAME", "Stack name"
10
- option ["-t", "--tail"], :flag, "Tail (follow) logs", default: false
11
- option ["-l", "--lines"], "LINES", "How many lines to show", default: '100'
12
- option "--since", "SINCE", "Show logs since given timestamp"
13
10
 
14
11
  requires_current_master
15
12
  requires_current_master_token
16
13
 
17
14
  def execute
18
- query_params = {}
19
- query_params[:limit] = lines if lines
20
- query_params[:since] = since if since
21
-
22
- show_logs("stacks/#{current_grid}/#{name}/container_logs", query_params) do |log|
15
+ show_logs("stacks/#{current_grid}/#{name}/container_logs") do |log|
23
16
  show_log(log)
24
17
  end
25
18
  end
@@ -13,6 +13,7 @@ module Kontena::Cli::Stacks::Registry
13
13
 
14
14
  def execute
15
15
  file = Kontena::Cli::Stacks::YAML::Reader.new(filename, skip_variables: true, replace_missing: "filler")
16
+ file.execute
16
17
  name = "#{file.yaml['stack']}:#{file.yaml['version']}"
17
18
  spinner("Pushing #{pastel.cyan(name)} to stacks registry") do
18
19
  stacks_client.push(file.yaml['stack'], file.yaml['version'], file.raw_content)
@@ -33,8 +33,6 @@ module Kontena::Cli::Stacks
33
33
  @skip_validation = skip_validation
34
34
  @skip_variables = skip_variables
35
35
  @replace_missing = replace_missing
36
- parse_variables unless skip_variables
37
- parse_yaml
38
36
  end
39
37
 
40
38
  def from_registry?
@@ -44,9 +42,10 @@ module Kontena::Cli::Stacks
44
42
  # @return [Opto::Group]
45
43
  def variables
46
44
  return @variables if @variables
47
- yaml = ::YAML.load(interpolate(raw_content, 'filler'))
48
45
  if yaml && yaml.has_key?('variables')
49
- @variables = Opto::Group.new(yaml['variables'], defaults: { from: :env, to: :env })
46
+ variables_yaml = yaml['variables'].to_yaml
47
+ variables_hash = ::YAML.load(replace_dollar_dollars(interpolate(variables_yaml)))
48
+ @variables = Opto::Group.new(variables_hash, defaults: { from: :env, to: :env })
50
49
  else
51
50
  @variables = Opto::Group.new(defaults: { from: :env, to: :env })
52
51
  end
@@ -62,6 +61,11 @@ module Kontena::Cli::Stacks
62
61
  # @param [String] service_name
63
62
  # @return [Hash]
64
63
  def execute(service_name = nil)
64
+ load_yaml(false)
65
+ parse_variables unless skip_variables?
66
+ load_yaml
67
+ validate unless skip_validation?
68
+
65
69
  result = {}
66
70
  Dir.chdir(from_registry? ? Dir.pwd : File.dirname(File.expand_path(file))) do
67
71
  result[:stack] = yaml['stack']
@@ -77,15 +81,8 @@ module Kontena::Cli::Stacks
77
81
  result
78
82
  end
79
83
 
80
- def reload
81
- @errors = []
82
- @notifications = []
83
- @variables = nil
84
- parse_variables unless skip_variables?
85
- parse_yaml
86
- end
87
-
88
84
  def stack_name
85
+ yaml = ::YAML.load(raw_content)
89
86
  yaml['stack'].split('/').last.split(':').first if yaml['stack']
90
87
  end
91
88
 
@@ -102,13 +99,12 @@ module Kontena::Cli::Stacks
102
99
  @content_variables ||= raw_content.scan(/((?<!\$)\$(?!\$)\{?(\w+)\}?)/m)
103
100
  end
104
101
 
105
- def parse_yaml
106
- load_yaml
107
- validate unless skip_validation?
108
- end
109
-
110
- def load_yaml
111
- @yaml = ::YAML.load(replace_dollar_dollars(interpolate(raw_content)))
102
+ def load_yaml(interpolate = true)
103
+ if interpolate
104
+ @yaml = ::YAML.load(replace_dollar_dollars(interpolate(raw_content)))
105
+ else
106
+ @yaml = ::YAML.load(raw_content)
107
+ end
112
108
  rescue Psych::SyntaxError => e
113
109
  raise "Error while parsing #{file}".colorize(:red)+ " "+e.message
114
110
  end
@@ -224,21 +220,17 @@ module Kontena::Cli::Stacks
224
220
 
225
221
  ##
226
222
  # @param [String] text - content of YAML file
227
- def interpolate(text, filler = nil)
223
+ def interpolate(text)
228
224
  text.gsub(/(?<!\$)\$(?!\$)\{?\w+\}?/) do |v| # searches $VAR and ${VAR} and not $$VAR
229
- if filler
230
- filler
225
+ var = v.tr('${}', '')
226
+ val = ENV[var]
227
+ if val
228
+ val
231
229
  elsif @replace_missing
232
230
  @replace_missing
233
231
  else
234
- var = v.tr('${}', '')
235
- val = ENV[var]
236
- if val
237
- val
238
- else
239
- puts "Value for #{var} is not set. Substituting with an empty string." unless skip_validation?
240
- ''
241
- end
232
+ puts "Value for #{var} is not set. Substituting with an empty string." unless skip_validation?
233
+ ''
242
234
  end
243
235
  end
244
236
  end
@@ -34,12 +34,15 @@ module Kontena::Cli::Stacks
34
34
  # @param [Array] to
35
35
  # @return [Array]
36
36
  def extend_env_vars(from, to)
37
- to ||= []
38
- from ||= []
39
- to_hash = Hash[*to.flat_map {|t| t.split('=') }]
40
- from_hash = Hash[*from.flat_map {|f| f.split('=') }]
41
-
42
- from_hash.merge(to_hash).map {|k,v| "#{k}=#{v}"}
37
+ env_vars = to || []
38
+ if from
39
+ from.each do |env|
40
+ env_vars << env unless to && to.find do |key|
41
+ key.split('=').first == env.split('=').first
42
+ end
43
+ end
44
+ end
45
+ env_vars
43
46
  end
44
47
 
45
48
  # Takes two arrays of hashes containing { 'secret' => 'str', 'type' => 'str', 'name' => 'str' }
@@ -151,7 +151,7 @@ class Kontena::Command < Clamp::Command
151
151
  Kontena::Cli::Config.instance.require_current_master_token
152
152
  rescue Kontena::Cli::Config::TokenExpiredError
153
153
  success = Kontena::Client.new(
154
- Kontena::Cli::Config.instance.current_master,
154
+ Kontena::Cli::Config.instance.current_master.url,
155
155
  Kontena::Cli::Config.instance.current_master.token
156
156
  ).refresh_token
157
157
  if success && !retried
@@ -6,6 +6,10 @@ describe Kontena::Cli::Stacks::DeployCommand do
6
6
  include ClientHelpers
7
7
 
8
8
  describe '#execute' do
9
+ before(:each) do
10
+ allow(subject).to receive(:wait_for_deploy_to_finish).and_return(spy)
11
+ end
12
+
9
13
  it 'requires api url' do
10
14
  expect(described_class.requires_current_master?).to be_truthy
11
15
  subject.run(['test-stack'])
@@ -63,62 +63,6 @@ describe Kontena::Cli::Stacks::YAML::Reader do
63
63
  .and_return(fixture('kontena_v3.yml'))
64
64
  subject
65
65
  end
66
-
67
- context 'variable interpolation' do
68
- before(:each) do
69
- allow(ENV).to receive(:key?).and_return(true)
70
- allow(ENV).to receive(:[]).with('TAG').and_return('4.1')
71
- allow(ENV).to receive(:[]).with('STACK').and_return('test')
72
- allow(ENV).to receive(:[]).with('GRID').and_return('test-grid')
73
- allow(ENV).to receive(:[]).with('MYSQL_IMAGE').and_return('mariadb:latest')
74
- end
75
-
76
- it 'interpolates $VAR variables' do
77
- allow(File).to receive(:read)
78
- .with(absolute_yaml_path)
79
- .and_return(fixture('stack-with-variables.yml'))
80
- services = subject.yaml['services']
81
- expect(services['wordpress']['image']).to eq('wordpress:4.1')
82
- end
83
-
84
- it 'interpolates ${VAR} variables' do
85
- allow(File).to receive(:read)
86
- .with(absolute_yaml_path)
87
- .and_return(fixture('stack-with-variables.yml'))
88
- services = subject.yaml['services']
89
- expect(services['mysql']['image']).to eq('mariadb:latest')
90
- end
91
-
92
- it 'warns about empty variables' do
93
- allow(File).to receive(:read)
94
- .with(absolute_yaml_path)
95
- .and_return(fixture('stack-with-variables.yml'))
96
- allow(ENV).to receive(:[])
97
- .with('MYSQL_IMAGE')
98
- .and_return(nil)
99
-
100
- expect {
101
- subject
102
- }.to output("Value for MYSQL_IMAGE is not set. Substituting with an empty string.\n").to_stdout
103
- end
104
- end
105
-
106
- it 'replaces $$VAR variables to $VAR format' do
107
- allow(ENV).to receive(:key?).and_return(true)
108
- allow(ENV).to receive(:[]).with('TEST_ENV_VAR').and_return('foo')
109
- allow(ENV).to receive(:[]).with('TAG').and_return('4.1')
110
- allow(ENV).to receive(:[]).with('MYSQL_IMAGE').and_return('mariadb:latest')
111
- allow(ENV).to receive(:[]).with('STACK').and_return('test')
112
- allow(ENV).to receive(:[]).with('GRID').and_return('test-grid')
113
- allow(File).to receive(:read)
114
- .with(absolute_yaml_path)
115
- .and_return(fixture('stack-with-variables.yml'))
116
- allow(File).to receive(:read)
117
- .with(absolute_yaml_path('docker-compose_v2.yml'))
118
- .and_return(fixture('docker-compose_v2.yml'))
119
- services = subject.execute[:services]
120
- expect(services['mysql']['environment'].first).to eq('INTERNAL_VAR=$INTERNAL_VAR')
121
- end
122
66
  end
123
67
 
124
68
  context 'when yaml file is malformed' do
@@ -199,6 +143,65 @@ describe Kontena::Cli::Stacks::YAML::Reader do
199
143
  end
200
144
  end
201
145
 
146
+ context 'variable interpolation' do
147
+ before(:each) do
148
+ allow(ENV).to receive(:key?).and_return(true)
149
+ allow(ENV).to receive(:[]).with('TAG').and_return('4.1')
150
+ allow(ENV).to receive(:[]).with('STACK').and_return('test')
151
+ allow(ENV).to receive(:[]).with('GRID').and_return('test-grid')
152
+ allow(ENV).to receive(:[]).with('MYSQL_IMAGE').and_return('mariadb:latest')
153
+ allow(ENV).to receive(:[]).with('TEST_ENV_VAR').and_return('foo')
154
+ end
155
+
156
+ it 'interpolates $VAR variables' do
157
+ allow(File).to receive(:read)
158
+ .with(absolute_yaml_path)
159
+ .and_return(fixture('stack-with-variables.yml'))
160
+ subject.execute
161
+ services = subject.yaml['services']
162
+ expect(services['wordpress']['image']).to eq('wordpress:4.1')
163
+ end
164
+
165
+ it 'interpolates ${VAR} variables' do
166
+ allow(File).to receive(:read)
167
+ .with(absolute_yaml_path)
168
+ .and_return(fixture('stack-with-variables.yml'))
169
+ subject.execute
170
+ services = subject.yaml['services']
171
+ expect(services['mysql']['image']).to eq('mariadb:latest')
172
+ end
173
+
174
+ it 'warns about empty variables' do
175
+ allow(File).to receive(:read)
176
+ .with(absolute_yaml_path)
177
+ .and_return(fixture('stack-with-variables.yml'))
178
+ allow(ENV).to receive(:[])
179
+ .with('MYSQL_IMAGE')
180
+ .and_return(nil)
181
+
182
+ expect {
183
+ subject.execute
184
+ }.to output("Value for MYSQL_IMAGE is not set. Substituting with an empty string.\n").to_stdout
185
+ end
186
+ end
187
+
188
+ it 'replaces $$VAR variables to $VAR format' do
189
+ allow(ENV).to receive(:key?).and_return(true)
190
+ allow(ENV).to receive(:[]).with('TEST_ENV_VAR').and_return('foo')
191
+ allow(ENV).to receive(:[]).with('TAG').and_return('4.1')
192
+ allow(ENV).to receive(:[]).with('MYSQL_IMAGE').and_return('mariadb:latest')
193
+ allow(ENV).to receive(:[]).with('STACK').and_return('test')
194
+ allow(ENV).to receive(:[]).with('GRID').and_return('test-grid')
195
+ allow(File).to receive(:read)
196
+ .with(absolute_yaml_path)
197
+ .and_return(fixture('stack-with-variables.yml'))
198
+ allow(File).to receive(:read)
199
+ .with(absolute_yaml_path('docker-compose_v2.yml'))
200
+ .and_return(fixture('docker-compose_v2.yml'))
201
+ services = subject.execute[:services]
202
+ expect(services['mysql']['environment'].first).to eq('INTERNAL_VAR=$INTERNAL_VAR')
203
+ end
204
+
202
205
  context 'environment variables' do
203
206
  it 'converts env hash to array' do
204
207
  result = subject.execute[:services]
@@ -282,7 +285,6 @@ describe Kontena::Cli::Stacks::YAML::Reader do
282
285
  .with(absolute_yaml_path)
283
286
  .and_return(fixture('kontena_build_v3.yml'))
284
287
  outcome = subject.execute
285
- puts outcome
286
288
  expect(outcome[:services]['webapp']['build']['context']).to eq(File.expand_path('.'))
287
289
  end
288
290
  end
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.0.0
4
+ version: 1.0.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: 2016-11-29 00:00:00.000000000 Z
11
+ date: 2016-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -543,9 +543,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
543
543
  version: 2.0.0
544
544
  required_rubygems_version: !ruby/object:Gem::Requirement
545
545
  requirements:
546
- - - ">="
546
+ - - ">"
547
547
  - !ruby/object:Gem::Version
548
- version: '0'
548
+ version: 1.3.1
549
549
  requirements: []
550
550
  rubyforge_project:
551
551
  rubygems_version: 2.5.1