kontena-cli 1.4.0.pre6 → 1.4.0.pre7
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/VERSION +1 -1
- data/bin/kontena +1 -1
- data/kontena-cli.gemspec +3 -3
- data/lib/kontena/cli/certificate/authorize_command.rb +67 -6
- data/lib/kontena/cli/certificate/get_command.rb +7 -0
- data/lib/kontena/cli/certificate/list_command.rb +75 -0
- data/lib/kontena/cli/certificate/register_command.rb +13 -2
- data/lib/kontena/cli/certificate/request_command.rb +20 -0
- data/lib/kontena/cli/certificate/show_command.rb +19 -0
- data/lib/kontena/cli/certificate_command.rb +4 -1
- data/lib/kontena/cli/cloud/master/add_command.rb +1 -1
- data/lib/kontena/cli/common.rb +21 -33
- data/lib/kontena/cli/etcd/health_command.rb +21 -27
- data/lib/kontena/cli/helpers/exec_helper.rb +15 -6
- data/lib/kontena/cli/helpers/health_helper.rb +12 -0
- data/lib/kontena/cli/helpers/log_helper.rb +2 -2
- data/lib/kontena/cli/helpers/time_helper.rb +29 -0
- data/lib/kontena/cli/master/init_cloud_command.rb +19 -0
- data/lib/kontena/cli/master/list_command.rb +1 -1
- data/lib/kontena/cli/master/ssh_command.rb +3 -1
- data/lib/kontena/cli/master/use_command.rb +1 -2
- data/lib/kontena/cli/node_command.rb +1 -0
- data/lib/kontena/cli/nodes/health_command.rb +28 -13
- data/lib/kontena/cli/nodes/list_command.rb +19 -3
- data/lib/kontena/cli/nodes/show_command.rb +4 -2
- data/lib/kontena/cli/nodes/ssh_command.rb +5 -2
- data/lib/kontena/cli/nodes/update_command.rb +2 -0
- data/lib/kontena/cli/plugins/install_command.rb +11 -8
- data/lib/kontena/cli/plugins/list_command.rb +5 -3
- data/lib/kontena/cli/plugins/search_command.rb +4 -2
- data/lib/kontena/cli/plugins/show_command.rb +17 -0
- data/lib/kontena/cli/plugins/uninstall_command.rb +9 -13
- data/lib/kontena/cli/registry/create_command.rb +1 -1
- data/lib/kontena/cli/services/create_command.rb +6 -0
- data/lib/kontena/cli/services/services_helper.rb +33 -6
- data/lib/kontena/cli/services/update_command.rb +6 -0
- data/lib/kontena/cli/stacks/build_command.rb +3 -3
- data/lib/kontena/cli/stacks/common.rb +105 -90
- data/lib/kontena/cli/stacks/deploy_command.rb +7 -3
- data/lib/kontena/cli/stacks/install_command.rb +39 -6
- data/lib/kontena/cli/stacks/list_command.rb +36 -4
- data/lib/kontena/cli/stacks/logs_command.rb +9 -2
- data/lib/kontena/cli/stacks/registry/pull_command.rb +2 -2
- data/lib/kontena/cli/stacks/registry/push_command.rb +20 -9
- data/lib/kontena/cli/stacks/registry/remove_command.rb +4 -4
- data/lib/kontena/cli/stacks/registry/show_command.rb +4 -4
- data/lib/kontena/cli/stacks/remove_command.rb +27 -1
- data/lib/kontena/cli/stacks/service_generator.rb +12 -2
- data/lib/kontena/cli/stacks/show_command.rb +35 -5
- data/lib/kontena/cli/stacks/stack_name.rb +71 -0
- data/lib/kontena/cli/stacks/upgrade_command.rb +127 -14
- data/lib/kontena/cli/stacks/validate_command.rb +38 -10
- data/lib/kontena/cli/stacks/yaml/custom_validators/certificates_validator.rb +22 -0
- data/lib/kontena/cli/stacks/yaml/opto/prompt_resolver.rb +1 -2
- data/lib/kontena/cli/stacks/yaml/reader.rb +211 -185
- data/lib/kontena/cli/stacks/yaml/service_extender.rb +6 -12
- data/lib/kontena/cli/stacks/yaml/stack_file_loader.rb +97 -0
- data/lib/kontena/cli/stacks/yaml/stack_file_loader/file_loader.rb +41 -0
- data/lib/kontena/cli/stacks/yaml/stack_file_loader/registry_loader.rb +24 -0
- data/lib/kontena/cli/stacks/yaml/stack_file_loader/uri_loader.rb +23 -0
- data/lib/kontena/cli/stacks/yaml/validations.rb +16 -0
- data/lib/kontena/cli/stacks/yaml/validator_v3.rb +25 -8
- data/lib/kontena/client.rb +2 -2
- data/lib/kontena/command.rb +11 -0
- data/lib/kontena/main_command.rb +3 -1
- data/lib/kontena/plugin_manager.rb +11 -198
- data/lib/kontena/plugin_manager/cleaner.rb +33 -0
- data/lib/kontena/plugin_manager/common.rb +86 -0
- data/lib/kontena/plugin_manager/installer.rb +54 -0
- data/lib/kontena/plugin_manager/loader.rb +93 -0
- data/lib/kontena/plugin_manager/rubygems_client.rb +42 -23
- data/lib/kontena/plugin_manager/uninstaller.rb +34 -0
- data/lib/kontena/util.rb +24 -0
- data/lib/kontena_cli.rb +1 -0
- data/omnibus/config/projects/kontena.rb +7 -1
- data/omnibus/config/software/{kontena.rb → kontena-cli.rb} +2 -0
- data/spec/fixtures/api/node.json +2 -1
- data/spec/fixtures/stack-internal-extend.yml +6 -1
- data/spec/fixtures/stack-with-dependencies-dep-1-1.yml +8 -0
- data/spec/fixtures/stack-with-dependencies-dep-1.yml +17 -0
- data/spec/fixtures/stack-with-dependencies-dep-2.yml +8 -0
- data/spec/fixtures/stack-with-dependencies-dep-3.yml +5 -0
- data/spec/fixtures/stack-with-dependencies-dep_2-removed.yml +17 -0
- data/spec/fixtures/stack-with-dependencies-dep_3-added.yml +25 -0
- data/spec/fixtures/stack-with-dependencies.yml +22 -0
- data/spec/fixtures/stack-with-variables.yml +3 -0
- data/spec/kontena/cli/etcd/health_command_spec.rb +45 -33
- data/spec/kontena/cli/helpers/exec_helper_spec.rb +2 -1
- data/spec/kontena/cli/master/init_cloud_command_spec.rb +14 -0
- data/spec/kontena/cli/nodes/health_command_spec.rb +74 -10
- data/spec/kontena/cli/nodes/list_command_spec.rb +381 -232
- data/spec/kontena/cli/nodes/show_command_spec.rb +31 -0
- data/spec/kontena/cli/nodes/ssh_command_spec.rb +18 -3
- data/spec/kontena/cli/plugins/install_command_spec.rb +1 -1
- data/spec/kontena/cli/stacks/build_command_spec.rb +6 -12
- data/spec/kontena/cli/stacks/common_spec.rb +42 -69
- data/spec/kontena/cli/stacks/install_command_spec.rb +57 -31
- data/spec/kontena/cli/stacks/list_command_spec.rb +44 -0
- data/spec/kontena/cli/stacks/logs_command_spec.rb +12 -1
- data/spec/kontena/cli/stacks/remove_command_spec.rb +39 -0
- data/spec/kontena/cli/stacks/show_command_spec.rb +16 -0
- data/spec/kontena/cli/stacks/stack_name_spec.rb +21 -0
- data/spec/kontena/cli/stacks/upgrade_command_spec.rb +73 -56
- data/spec/kontena/cli/stacks/validate_command_spec.rb +81 -0
- data/spec/kontena/cli/stacks/yaml/custom_validators/affinities_validator_spec.rb +22 -0
- data/spec/kontena/cli/stacks/yaml/reader_spec.rb +173 -169
- data/spec/kontena/cli/stacks/yaml/service_extender_spec.rb +12 -3
- data/spec/kontena/cli/stacks/yaml/stack_file_loader/file_loader_spec.rb +47 -0
- data/spec/kontena/cli/stacks/yaml/stack_file_loader/registry_loader_spec.rb +53 -0
- data/spec/kontena/cli/stacks/yaml/stack_file_loader/uri_loader_spec.rb +53 -0
- data/spec/kontena/cli/stacks/yaml/stack_file_loader_spec.rb +104 -0
- data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +19 -0
- data/spec/kontena/plugin_manager/cleaner_spec.rb +20 -0
- data/spec/kontena/plugin_manager/common_spec.rb +39 -0
- data/spec/kontena/plugin_manager/installer_spec.rb +50 -0
- data/spec/kontena/plugin_manager/loader_spec.rb +5 -0
- data/spec/kontena/plugin_manager/rubygems_client_spec.rb +11 -25
- data/spec/kontena/plugin_manager/uninstaller_spec.rb +19 -0
- data/spec/kontena/plugin_manager_spec.rb +7 -7
- metadata +64 -97
- data/lib/kontena/cli/app_command.rb +0 -22
- data/lib/kontena/cli/apps/build_command.rb +0 -28
- data/lib/kontena/cli/apps/common.rb +0 -172
- data/lib/kontena/cli/apps/config_command.rb +0 -25
- data/lib/kontena/cli/apps/deploy_command.rb +0 -137
- data/lib/kontena/cli/apps/docker_compose_generator.rb +0 -61
- data/lib/kontena/cli/apps/docker_helper.rb +0 -80
- data/lib/kontena/cli/apps/dockerfile_generator.rb +0 -16
- data/lib/kontena/cli/apps/init_command.rb +0 -89
- data/lib/kontena/cli/apps/kontena_yml_generator.rb +0 -105
- data/lib/kontena/cli/apps/list_command.rb +0 -59
- data/lib/kontena/cli/apps/logs_command.rb +0 -37
- data/lib/kontena/cli/apps/monitor_command.rb +0 -93
- data/lib/kontena/cli/apps/remove_command.rb +0 -74
- data/lib/kontena/cli/apps/restart_command.rb +0 -39
- data/lib/kontena/cli/apps/scale_command.rb +0 -33
- data/lib/kontena/cli/apps/service_generator.rb +0 -114
- data/lib/kontena/cli/apps/service_generator_v2.rb +0 -27
- data/lib/kontena/cli/apps/show_command.rb +0 -23
- data/lib/kontena/cli/apps/start_command.rb +0 -40
- data/lib/kontena/cli/apps/stop_command.rb +0 -40
- data/lib/kontena/cli/apps/yaml/custom_validators/affinities_validator.rb +0 -19
- data/lib/kontena/cli/apps/yaml/custom_validators/build_validator.rb +0 -22
- data/lib/kontena/cli/apps/yaml/custom_validators/extends_validator.rb +0 -20
- data/lib/kontena/cli/apps/yaml/custom_validators/hooks_validator.rb +0 -54
- data/lib/kontena/cli/apps/yaml/custom_validators/secrets_validator.rb +0 -22
- data/lib/kontena/cli/apps/yaml/reader.rb +0 -213
- data/lib/kontena/cli/apps/yaml/service_extender.rb +0 -77
- data/lib/kontena/cli/apps/yaml/validations.rb +0 -71
- data/lib/kontena/cli/apps/yaml/validator.rb +0 -38
- data/lib/kontena/cli/apps/yaml/validator_v2.rb +0 -53
- data/spec/fixtures/app.json +0 -42
- data/spec/fixtures/health.yml +0 -26
- data/spec/fixtures/kontena-build.yml +0 -16
- data/spec/fixtures/kontena-internal-extend.yml +0 -8
- data/spec/fixtures/kontena-invalid.yml +0 -4
- data/spec/fixtures/kontena-with-env-file.yml +0 -18
- data/spec/fixtures/kontena-with-variables.yml +0 -19
- data/spec/fixtures/kontena.yml +0 -17
- data/spec/fixtures/kontena_build_v2.yml +0 -26
- data/spec/fixtures/kontena_numeric_version.yml +0 -9
- data/spec/fixtures/kontena_v2.yml +0 -35
- data/spec/fixtures/mysql.yml +0 -3
- data/spec/fixtures/wordpress-scaled.yml +0 -3
- data/spec/fixtures/wordpress.yml +0 -2
- data/spec/kontena/cli/app/build_command_spec.rb +0 -55
- data/spec/kontena/cli/app/common_spec.rb +0 -110
- data/spec/kontena/cli/app/config_command_spec.rb +0 -78
- data/spec/kontena/cli/app/deploy_command_spec.rb +0 -217
- data/spec/kontena/cli/app/docker_helper_spec.rb +0 -155
- data/spec/kontena/cli/app/init_command_spec.rb +0 -109
- data/spec/kontena/cli/app/logs_command_spec.rb +0 -131
- data/spec/kontena/cli/app/scale_spec.rb +0 -51
- data/spec/kontena/cli/app/service_generator_spec.rb +0 -384
- data/spec/kontena/cli/app/service_generator_v2_spec.rb +0 -73
- data/spec/kontena/cli/app/yaml/reader_spec.rb +0 -457
- data/spec/kontena/cli/app/yaml/service_extender_spec.rb +0 -127
- data/spec/kontena/cli/app/yaml/validator_spec.rb +0 -380
- data/spec/kontena/cli/app/yaml/validator_v2_spec.rb +0 -301
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'kontena/plugin_manager'
|
|
2
|
+
|
|
3
|
+
module Kontena::Cli::Plugins
|
|
4
|
+
class ShowCommand < Kontena::Command
|
|
5
|
+
parameter 'NAME', 'Plugin name' do |name|
|
|
6
|
+
"kontena-plugin-#{name}"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def execute
|
|
10
|
+
require 'yaml'
|
|
11
|
+
plug = Gem::Specification.find { |g| g.name == name }
|
|
12
|
+
out = {}
|
|
13
|
+
out[:path] = plug.gem_dir
|
|
14
|
+
puts out.to_yaml
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -1,26 +1,22 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'kontena/plugin_manager'
|
|
2
2
|
|
|
3
3
|
module Kontena::Cli::Plugins
|
|
4
4
|
class UninstallCommand < Kontena::Command
|
|
5
5
|
include Kontena::Util
|
|
6
6
|
include Kontena::Cli::Common
|
|
7
|
+
include Kontena::PluginManager::Common
|
|
7
8
|
|
|
8
9
|
parameter 'NAME', 'Plugin name'
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
def uninstaller
|
|
12
|
+
Kontena::PluginManager::Uninstaller.new(name)
|
|
13
|
+
end
|
|
11
14
|
|
|
12
15
|
def execute
|
|
13
|
-
exit_with_error "Plugin #{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
begin
|
|
17
|
-
Kontena::PluginManager.instance.uninstall_plugin(name)
|
|
18
|
-
rescue => ex
|
|
19
|
-
$stderr.puts pastel.red("#{ex.class.name} : #{ex.message}")
|
|
20
|
-
logger.error(ex)
|
|
21
|
-
spin.fail
|
|
22
|
-
end
|
|
16
|
+
exit_with_error "Plugin #{name} has not been installed" unless installed?(name)
|
|
17
|
+
spinner "Uninstalling plugin #{pastel.cyan(name)}" do
|
|
18
|
+
uninstaller.uninstall
|
|
23
19
|
end
|
|
24
20
|
end
|
|
25
21
|
end
|
|
26
|
-
end
|
|
22
|
+
end
|
|
@@ -14,7 +14,7 @@ module Kontena::Cli::Registry
|
|
|
14
14
|
option '--s3-region', 'S3_REGION', 'S3 region', default: 'eu-west-1'
|
|
15
15
|
option '--s3-encrypt', :flag, 'Encrypt S3 objects', default: false
|
|
16
16
|
option '--s3-secure', :flag, 'Use secure connection in S3', default: true
|
|
17
|
-
option '--s3-v4auth', :flag, 'Use v4auth on S3', default:
|
|
17
|
+
option '--s3-v4auth', :flag, 'Use v4auth on S3', default: true
|
|
18
18
|
option '--azure-account-name', 'AZURE_ACCOUNT_NAME', 'Azure account name'
|
|
19
19
|
option '--azure-container-name', 'AZURE_CONTAINER_NAME', 'Azure container name'
|
|
20
20
|
|
|
@@ -16,9 +16,13 @@ module Kontena::Cli::Services
|
|
|
16
16
|
option ["-v", "--volume"], "VOLUME", "Add a volume or bind mount it from the host", multivalued: true
|
|
17
17
|
option "--volumes-from", "VOLUMES_FROM", "Mount volumes from another container", multivalued: true
|
|
18
18
|
option ["-a", "--affinity"], "AFFINITY", "Set service affinity", multivalued: true
|
|
19
|
+
option "--cpus", "CPUS", "Number of CPUs" do |cpus|
|
|
20
|
+
Float(cpus)
|
|
21
|
+
end
|
|
19
22
|
option ["-c", "--cpu-shares"], "CPU_SHARES", "CPU shares (relative weight)"
|
|
20
23
|
option ["-m", "--memory"], "MEMORY", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)"
|
|
21
24
|
option ["--memory-swap"], "MEMORY_SWAP", "Total memory usage (memory + swap), set \'-1\' to disable swap (format: <number><optional unit>, where unit = b, k, m or g)"
|
|
25
|
+
option ["--shm-size"], "SHM_SIZE", "Size of /dev/shm (format: <number><optional unit>, where unit = b, k, m or g)"
|
|
22
26
|
option "--cmd", "CMD", "Command to execute"
|
|
23
27
|
option "--instances", "INSTANCES", "How many instances should be deployed"
|
|
24
28
|
option ["-u", "--user"], "USER", "Username who executes first process inside container"
|
|
@@ -69,6 +73,8 @@ module Kontena::Cli::Services
|
|
|
69
73
|
data[:volumes_from] = volumes_from_list unless volumes_from_list.empty?
|
|
70
74
|
data[:memory] = parse_memory(memory) if memory
|
|
71
75
|
data[:memory_swap] = parse_memory(memory_swap) if memory_swap
|
|
76
|
+
data[:shm_size] = parse_memory(shm_size) if shm_size
|
|
77
|
+
data[:cpus] = cpus if cpus
|
|
72
78
|
data[:cpu_shares] = cpu_shares if cpu_shares
|
|
73
79
|
data[:affinity] = affinity_list unless affinity_list.empty?
|
|
74
80
|
data[:env] = env_list unless env_list.empty?
|
|
@@ -100,6 +100,15 @@ module Kontena
|
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
+
if service['certificates'].to_a.size > 0
|
|
104
|
+
puts " certificates: "
|
|
105
|
+
service['certificates'].to_a.each do |c|
|
|
106
|
+
puts " - subject: #{c['subject']}"
|
|
107
|
+
puts " name: #{c['name']}"
|
|
108
|
+
puts " type: #{c['type']}"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
103
112
|
if service['env'].to_a.size > 0
|
|
104
113
|
puts " env: "
|
|
105
114
|
service['env'].to_a.each do |e|
|
|
@@ -161,6 +170,14 @@ module Kontena
|
|
|
161
170
|
end
|
|
162
171
|
end
|
|
163
172
|
|
|
173
|
+
unless service['cpus'].to_s.empty?
|
|
174
|
+
puts " cpus: #{service['cpus']}"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
unless service['cpu_shares'].to_s.empty?
|
|
178
|
+
puts " cpu_shares: #{service['cpu_shares']}"
|
|
179
|
+
end
|
|
180
|
+
|
|
164
181
|
unless service['memory'].to_s.empty?
|
|
165
182
|
puts " memory: #{int_to_filesize(service['memory'])}"
|
|
166
183
|
end
|
|
@@ -169,6 +186,10 @@ module Kontena
|
|
|
169
186
|
puts " memory_swap: #{int_to_filesize(service['memory_swap'])}"
|
|
170
187
|
end
|
|
171
188
|
|
|
189
|
+
unless service['shm_size'].to_s.empty?
|
|
190
|
+
puts " shm_size: #{int_to_filesize(service['shm_size'])}"
|
|
191
|
+
end
|
|
192
|
+
|
|
172
193
|
unless service['pid'].to_s.empty?
|
|
173
194
|
puts " pid: #{service['pid']}"
|
|
174
195
|
end
|
|
@@ -361,13 +382,19 @@ module Kontena
|
|
|
361
382
|
def parse_ports(port_options)
|
|
362
383
|
port_regex = Regexp.new(/\A(?<ip>\d+\.\d+\.\d+\.\d+)?:?(?<node_port>\d+)\:(?<container_port>\d+)\/?(?<protocol>\w+)?\z/)
|
|
363
384
|
port_options.map do |p|
|
|
364
|
-
|
|
365
|
-
|
|
385
|
+
if p.kind_of?(Hash)
|
|
386
|
+
raise ArgumentError, "Missing or invalid node port" unless p['node_port'].to_i > 0
|
|
387
|
+
raise ArgumentError, "Missing or invalid container port" unless p['container_port'].to_i > 0
|
|
388
|
+
{ ip: p['ip'] || '0.0.0.0', protocol: p['protocol'] || 'tcp', node_port: p['node_port'].to_i, container_port: p['container_port'].to_i }
|
|
389
|
+
else
|
|
390
|
+
match_data = port_regex.match(p.to_s)
|
|
391
|
+
raise ArgumentError, "Invalid port value #{p}" unless match_data
|
|
366
392
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
393
|
+
{
|
|
394
|
+
ip: '0.0.0.0',
|
|
395
|
+
protocol: 'tcp'
|
|
396
|
+
}.merge(match_data.names.map { |name| [name.to_sym, match_data[name]] }.to_h.reject { |_,v| v.nil? })
|
|
397
|
+
end
|
|
371
398
|
end
|
|
372
399
|
end
|
|
373
400
|
|
|
@@ -14,9 +14,13 @@ module Kontena::Cli::Services
|
|
|
14
14
|
option ["-e", "--env"], "ENV", "Set environment variables", multivalued: true
|
|
15
15
|
option ["-l", "--link"], "LINK", "Add link to another service in the form of name:alias", multivalued: true
|
|
16
16
|
option ["-a", "--affinity"], "AFFINITY", "Set service affinity", multivalued: true
|
|
17
|
+
option "--cpus", "CPUS", "Number of CPUs" do |cpus|
|
|
18
|
+
Float(cpus)
|
|
19
|
+
end
|
|
17
20
|
option ["-c", "--cpu-shares"], "CPU_SHARES", "CPU shares (relative weight)"
|
|
18
21
|
option ["-m", "--memory"], "MEMORY", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)"
|
|
19
22
|
option ["--memory-swap"], "MEMORY_SWAP", "Total memory usage (memory + swap), set \'-1\' to disable swap (format: <number><optional unit>, where unit = b, k, m or g)"
|
|
23
|
+
option ["--shm-size"], "SHM_SIZE", "Size of /dev/shm (format: <number><optional unit>, where unit = b, k, m or g)"
|
|
20
24
|
option "--cmd", "CMD", "Command to execute"
|
|
21
25
|
option "--instances", "INSTANCES", "How many instances should be deployed"
|
|
22
26
|
option ["-u", "--user"], "USER", "Username who executes first process inside container"
|
|
@@ -60,6 +64,8 @@ module Kontena::Cli::Services
|
|
|
60
64
|
data[:links] = parse_links(link_list) unless link_list.empty?
|
|
61
65
|
data[:memory] = parse_memory(memory) if memory
|
|
62
66
|
data[:memory_swap] = parse_memory(memory_swap) if memory_swap
|
|
67
|
+
data[:shm_size] = parse_memory(shm_size) if shm_size
|
|
68
|
+
data[:cpus] = cpus if cpus
|
|
63
69
|
data[:cpu_shares] = cpu_shares if cpu_shares
|
|
64
70
|
data[:affinity] = affinity_list unless affinity_list.empty?
|
|
65
71
|
data[:env] = env_list unless env_list.empty?
|
|
@@ -8,7 +8,7 @@ module Kontena::Cli::Stacks
|
|
|
8
8
|
|
|
9
9
|
banner "Build images listed in a stack file and push them to your image registry"
|
|
10
10
|
|
|
11
|
-
option ['-f', '--file'], 'FILE', 'Specify an alternate Kontena compose file', attribute_name: :
|
|
11
|
+
option ['-f', '--file'], 'FILE', 'Specify an alternate Kontena compose file', attribute_name: :source, default: 'kontena.yml'
|
|
12
12
|
|
|
13
13
|
option ['--no-cache'], :flag, 'Do not use cache when building the image', default: false
|
|
14
14
|
option ['--no-push'], :flag, 'Do not push images to registry', default: false
|
|
@@ -26,8 +26,8 @@ module Kontena::Cli::Stacks
|
|
|
26
26
|
requires_current_master_token
|
|
27
27
|
|
|
28
28
|
def execute
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
set_env_variables(stack_name, current_grid)
|
|
30
|
+
|
|
31
31
|
services = stack['services']
|
|
32
32
|
|
|
33
33
|
unless service_list.empty?
|
|
@@ -2,32 +2,72 @@ require_relative 'yaml/reader'
|
|
|
2
2
|
require_relative '../services/services_helper'
|
|
3
3
|
require_relative 'service_generator_v2'
|
|
4
4
|
require_relative '../../stacks_client'
|
|
5
|
+
require_relative 'yaml/stack_file_loader'
|
|
5
6
|
require 'yaml'
|
|
6
7
|
|
|
7
8
|
module Kontena::Cli::Stacks
|
|
8
9
|
module Common
|
|
9
10
|
include Kontena::Cli::Services::ServicesHelper
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
# @return [StackFileLoader] a loader for the stack origin defined through command-line options
|
|
13
|
+
def loader
|
|
14
|
+
@loader ||= loader_class.for(source)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @return [YAML::Reader] a YAML reader for the target file
|
|
18
|
+
def reader
|
|
19
|
+
@reader ||= loader.reader
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Stack name read from -n parameter or the stack file
|
|
23
|
+
# @return [String]
|
|
24
|
+
def stack_name
|
|
25
|
+
@stack_name ||= (self.respond_to?(:name) && self.name) ? self.name : loader.stack_name.stack
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# An accessor to the YAML Reader outcome. Passes parent name, values from command line and
|
|
29
|
+
# the stackname to the reader.
|
|
30
|
+
#
|
|
31
|
+
# @return [Hash]
|
|
32
|
+
def stack
|
|
33
|
+
@stack ||= reader.execute(
|
|
34
|
+
name: stack_name,
|
|
35
|
+
parent_name: self.respond_to?(:parent_name) ? self.parent_name : nil,
|
|
36
|
+
values: (self.respond_to?(:values_from_options) ? self.values_from_options : {})
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @return [Class] an accessor to StackFileLoader constant, for testing purposes
|
|
41
|
+
def loader_class
|
|
42
|
+
::Kontena::Cli::Stacks::YAML::StackFileLoader
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module RegistryNameParam
|
|
46
|
+
def stack_name
|
|
47
|
+
@stack_name ||= Kontena::Cli::Stacks::StackName.new(source)
|
|
48
|
+
end
|
|
13
49
|
|
|
14
50
|
def self.included(where)
|
|
15
|
-
where.parameter "STACK_NAME", "Stack name, for example user/stackname or user/stackname:version"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
51
|
+
where.parameter "STACK_NAME", "Stack name, for example user/stackname or user/stackname:version", attribute_name: :source
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
module StackNameParam
|
|
56
|
+
# Include to add a STACK_NAME parameter
|
|
57
|
+
def self.included(where)
|
|
58
|
+
where.parameter "STACK_NAME", "Stack name, for example user/stackname or user/stackname:version", attribute_name: :source
|
|
21
59
|
end
|
|
22
60
|
end
|
|
23
61
|
|
|
24
62
|
module StackFileOrNameParam
|
|
63
|
+
# Include to add a stack file parameter
|
|
25
64
|
def self.included(where)
|
|
26
|
-
where.parameter "[FILE]", "Kontena stack file, registry stack name (user/stack or user/stack:version) or URL", default: "kontena.yml", attribute_name: :
|
|
65
|
+
where.parameter "[FILE]", "Kontena stack file, registry stack name (user/stack or user/stack:version) or URL", default: "kontena.yml", attribute_name: :source
|
|
27
66
|
end
|
|
28
67
|
end
|
|
29
68
|
|
|
30
69
|
module StackNameOption
|
|
70
|
+
# Include to add a stack name parameter
|
|
31
71
|
def self.included(where)
|
|
32
72
|
where.option ['-n', '--name'], 'NAME', 'Define stack name (by default comes from stack file)'
|
|
33
73
|
end
|
|
@@ -35,102 +75,73 @@ module Kontena::Cli::Stacks
|
|
|
35
75
|
|
|
36
76
|
module StackValuesToOption
|
|
37
77
|
attr_accessor :values
|
|
78
|
+
# Include to add --values-to variable value dumping feature
|
|
38
79
|
def self.included(where)
|
|
39
80
|
where.option '--values-to', '[FILE]', 'Output variable values as YAML to file'
|
|
40
81
|
end
|
|
41
82
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
83
|
+
# Writes a YAML file from the values received from YAML::Reader to a file defined through
|
|
84
|
+
# the --values-to option
|
|
85
|
+
def dump_variables
|
|
86
|
+
File.write(values_to, ::YAML.dump(reader.variable_values, without_defaults: true, without_vault: true))
|
|
45
87
|
end
|
|
46
88
|
end
|
|
47
89
|
|
|
48
90
|
module StackValuesFromOption
|
|
49
|
-
|
|
91
|
+
# Include to add --values-from option to read variable values from a YAML file
|
|
92
|
+
# and the -v variable=value option that can be used to pass variable values
|
|
93
|
+
# directly from command line
|
|
50
94
|
def self.included(where)
|
|
95
|
+
where.prepend InstanceMethods
|
|
96
|
+
|
|
51
97
|
where.option '--values-from', '[FILE]', 'Read variable values from YAML' do |filename|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
98
|
+
values_from_file.merge!(::YAML.safe_load(File.read(filename)))
|
|
99
|
+
true
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
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|
|
|
103
|
+
var_name, var_value = var_pair.split('=', 2)
|
|
104
|
+
values_from_value_options.merge!(::YAML.safe_load(::YAML.dump(var_name => var_value)))
|
|
57
105
|
end
|
|
58
106
|
end
|
|
59
|
-
end
|
|
60
107
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
108
|
+
module InstanceMethods
|
|
109
|
+
def values_from_file
|
|
110
|
+
@values_from_file ||= {}
|
|
111
|
+
end
|
|
64
112
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if reader.stack_name.nil?
|
|
68
|
-
exit_with_error "Stack MUST have stack name in YAML top level field 'stack'! Aborting."
|
|
69
|
-
end
|
|
70
|
-
set_env_variables(name || reader.stack_name, current_grid)
|
|
71
|
-
reader
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def stack_from_reader(reader)
|
|
75
|
-
outcome = reader.execute
|
|
76
|
-
|
|
77
|
-
hint_on_validation_notifications(outcome[:notifications]) unless outcome[:notifications].empty?
|
|
78
|
-
abort_on_validation_errors(outcome[:errors]) unless outcome[:errors].empty?
|
|
79
|
-
kontena_services = generate_services(outcome[:services])
|
|
80
|
-
kontena_volumes = generate_volumes(outcome[:volumes])
|
|
81
|
-
stack = {
|
|
82
|
-
'name' => outcome[:name],
|
|
83
|
-
'stack' => outcome[:stack],
|
|
84
|
-
'expose' => outcome[:expose],
|
|
85
|
-
'version' => outcome[:version],
|
|
86
|
-
'source' => reader.raw_content,
|
|
87
|
-
'registry' => outcome[:registry],
|
|
88
|
-
'services' => kontena_services,
|
|
89
|
-
'volumes' => kontena_volumes,
|
|
90
|
-
'variables' => outcome[:variables]
|
|
91
|
-
}
|
|
92
|
-
stack
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def stack_from_yaml(filename, name: nil, values: nil, defaults: nil)
|
|
96
|
-
reader = reader_from_yaml(filename, name: name, values: values, defaults: defaults)
|
|
97
|
-
stack_from_reader(reader)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def stack_read_and_dump(filename, name: nil, values: nil, defaults: nil)
|
|
101
|
-
reader = reader_from_yaml(filename, name: name, values: values, defaults: defaults)
|
|
102
|
-
stack = stack_from_reader(reader)
|
|
103
|
-
dump_variables(reader) if values_to
|
|
104
|
-
stack
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def require_config_file(filename)
|
|
108
|
-
exit_with_error("File #{filename} does not exist") unless File.exists?(filename)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def generate_volumes(yaml_volumes)
|
|
112
|
-
return [] unless yaml_volumes
|
|
113
|
-
yaml_volumes.map do |name, config|
|
|
114
|
-
if config['external'].is_a?(TrueClass)
|
|
115
|
-
config['external'] = name
|
|
116
|
-
elsif config['external']['name']
|
|
117
|
-
config['external'] = config['external']['name']
|
|
113
|
+
def values_from_value_options
|
|
114
|
+
@values_from_value_options ||= {}
|
|
118
115
|
end
|
|
119
|
-
config.merge('name' => name)
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
116
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
117
|
+
def values_from_options
|
|
118
|
+
@values_from_options ||= values_from_file.merge(values_from_value_options)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Transforms a hash
|
|
122
|
+
# dependency_values_from_options('foo.bar' => 1, 'foo')
|
|
123
|
+
# => { 'bar' => 1 }
|
|
124
|
+
# Used for dependency variable injection
|
|
125
|
+
def dependency_values_from_options(name)
|
|
126
|
+
name_with_dot = name.to_s + '.'
|
|
127
|
+
values_from_options.each_with_object({}) do |kv_pair, obj|
|
|
128
|
+
key = kv_pair.first.to_s
|
|
129
|
+
value = kv_pair.last
|
|
130
|
+
next unless key.start_with?(name_with_dot)
|
|
131
|
+
obj[key.sub(name_with_dot, '')] = value
|
|
132
|
+
end
|
|
133
|
+
end
|
|
128
134
|
end
|
|
129
135
|
end
|
|
130
136
|
|
|
131
|
-
|
|
137
|
+
# Sets environment variables from parameters
|
|
138
|
+
# @param stack [String] current stack name
|
|
139
|
+
# @param grid [String] current grid name
|
|
140
|
+
# @param platform [String] current platform name, defaults to param grid value
|
|
141
|
+
def set_env_variables(stack, grid, platform = grid)
|
|
132
142
|
ENV['STACK'] = stack
|
|
133
143
|
ENV['GRID'] = grid
|
|
144
|
+
ENV['PLATFORM'] = platform
|
|
134
145
|
end
|
|
135
146
|
|
|
136
147
|
# @return [String]
|
|
@@ -139,20 +150,24 @@ module Kontena::Cli::Stacks
|
|
|
139
150
|
end
|
|
140
151
|
|
|
141
152
|
def display_notifications(messages, color = :yellow)
|
|
142
|
-
$stderr.puts(
|
|
153
|
+
$stderr.puts(pastel.send(color, messages.to_yaml.gsub(/^---$/, '')))
|
|
143
154
|
end
|
|
144
155
|
|
|
145
|
-
def hint_on_validation_notifications(
|
|
146
|
-
|
|
147
|
-
|
|
156
|
+
def hint_on_validation_notifications(notifications, filename = nil)
|
|
157
|
+
return if notifications.nil? || notifications.empty?
|
|
158
|
+
$stderr.puts pastel.yellow("#{"(#{filename}) " if filename}YAML contains the following unsupported options and they were rejected:")
|
|
159
|
+
display_notifications(notifications)
|
|
148
160
|
end
|
|
149
161
|
|
|
150
|
-
def abort_on_validation_errors(errors)
|
|
151
|
-
|
|
162
|
+
def abort_on_validation_errors(errors, filename = nil)
|
|
163
|
+
return if errors.nil? || errors.empty?
|
|
164
|
+
$stderr.puts pastel.red("#{"(#{filename}) " if filename} YAML validation failed! Aborting.")
|
|
152
165
|
display_notifications(errors, :red)
|
|
153
166
|
abort
|
|
154
167
|
end
|
|
155
168
|
|
|
169
|
+
# An accessor to stack registry client
|
|
170
|
+
# @return [Kontena::StacksClient]
|
|
156
171
|
def stacks_client
|
|
157
172
|
@stacks_client ||= Kontena::StacksClient.new(current_account.stacks_url, current_account.token, read_requires_token: current_account.stacks_read_authentication)
|
|
158
173
|
end
|