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
|
@@ -10,6 +10,8 @@ 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
|
|
14
|
+
|
|
13
15
|
requires_current_master
|
|
14
16
|
requires_current_master_token
|
|
15
17
|
|
|
@@ -18,10 +20,12 @@ module Kontena::Cli::Stacks
|
|
|
18
20
|
spinner "Triggering deployment of stack #{pastel.cyan(name)}" do
|
|
19
21
|
deployment = deploy_stack(name)
|
|
20
22
|
end
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
if wait?
|
|
24
|
+
spinner "Waiting for deployment to start" do
|
|
25
|
+
wait_for_deployment_to_start(deployment)
|
|
26
|
+
end
|
|
27
|
+
wait_for_deploy_to_finish(deployment)
|
|
23
28
|
end
|
|
24
|
-
wait_for_deploy_to_finish(deployment)
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
def deploy_stack(name)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require_relative 'common'
|
|
2
|
+
require_relative 'yaml/stack_file_loader'
|
|
2
3
|
|
|
3
4
|
module Kontena::Cli::Stacks
|
|
4
5
|
class InstallCommand < Kontena::Command
|
|
@@ -16,21 +17,53 @@ module Kontena::Cli::Stacks
|
|
|
16
17
|
include Common::StackValuesToOption
|
|
17
18
|
include Common::StackValuesFromOption
|
|
18
19
|
|
|
20
|
+
option '--parent-name', '[PARENT_NAME]', "Set parent stack name", hidden: true
|
|
21
|
+
option '--skip-dependencies', :flag, "Do not install any stack dependencies"
|
|
22
|
+
|
|
19
23
|
requires_current_master
|
|
20
24
|
requires_current_master_token
|
|
21
25
|
|
|
22
26
|
def execute
|
|
23
|
-
|
|
27
|
+
set_env_variables(stack_name, current_grid)
|
|
28
|
+
|
|
29
|
+
install_dependencies unless skip_dependencies?
|
|
30
|
+
|
|
31
|
+
hint_on_validation_notifications(reader.notifications)
|
|
32
|
+
abort_on_validation_errors(reader.errors)
|
|
33
|
+
|
|
34
|
+
dump_variables if values_to
|
|
35
|
+
|
|
36
|
+
create_stack
|
|
37
|
+
deploy_stack if deploy?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def install_dependencies
|
|
41
|
+
dependencies = loader.dependencies
|
|
42
|
+
return if dependencies.nil?
|
|
43
|
+
dependencies.each do |dependency|
|
|
44
|
+
target_name = "#{stack_name}-#{dependency['name']}"
|
|
45
|
+
caret "Installing dependency #{pastel.cyan(dependency[:stack])} as #{pastel.cyan(target_name)}"
|
|
46
|
+
cmd = ['stack', 'install', '-n', target_name, '--parent-name', stack_name]
|
|
47
|
+
|
|
48
|
+
dependency['variables'].merge(dependency_values_from_options(dependency['name'])).each do |key, value|
|
|
49
|
+
cmd.concat ['-v', "#{key}=#{value}"]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
cmd << '--no-deploy' unless deploy?
|
|
53
|
+
|
|
54
|
+
cmd << dependency['stack']
|
|
55
|
+
Kontena.run!(cmd)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
24
58
|
|
|
25
|
-
|
|
59
|
+
def create_stack
|
|
26
60
|
spinner "Creating stack #{pastel.cyan(stack['name'])} " do
|
|
27
|
-
|
|
61
|
+
client.post("grids/#{current_grid}/stacks", stack)
|
|
28
62
|
end
|
|
29
|
-
Kontena.run!(['stack', 'deploy', stack['name']]) if deploy?
|
|
30
63
|
end
|
|
31
64
|
|
|
32
|
-
def
|
|
33
|
-
|
|
65
|
+
def deploy_stack
|
|
66
|
+
Kontena.run!(['stack', 'deploy', stack['name']])
|
|
34
67
|
end
|
|
35
68
|
end
|
|
36
69
|
end
|
|
@@ -19,8 +19,22 @@ module Kontena::Cli::Stacks
|
|
|
19
19
|
default: Kontena.pastel.dim('⊝').freeze
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
def stacks
|
|
23
|
-
|
|
22
|
+
def stacks_by_names(stacks, name_list)
|
|
23
|
+
name_list.map { |name| stacks.find { |stack| stack['name'] == name } }.compact
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def build_depths(stacks)
|
|
27
|
+
stacks.sort_by { |s| s['name'] }.each do |stack|
|
|
28
|
+
stack['depth'] += 1
|
|
29
|
+
stacks_by_names(stacks, stack['children'].map { |n| n['name'] }).each do |child_stack|
|
|
30
|
+
child_stack['depth'] += stack['depth']
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
stacks
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get_stacks
|
|
37
|
+
client.get("grids/#{current_grid}/stacks")['stacks'].tap { |stacks| stacks.map { |stack| stack['depth'] = 0 } }
|
|
24
38
|
end
|
|
25
39
|
|
|
26
40
|
def fields
|
|
@@ -35,9 +49,11 @@ module Kontena::Cli::Stacks
|
|
|
35
49
|
end
|
|
36
50
|
|
|
37
51
|
def execute
|
|
38
|
-
|
|
52
|
+
stacks = build_depths(get_stacks)
|
|
53
|
+
|
|
54
|
+
print_table(stacks) do |row|
|
|
39
55
|
next if quiet?
|
|
40
|
-
row['name'] = health_icon(stack_health(row)) + " " + row['name']
|
|
56
|
+
row['name'] = health_icon(stack_health(row)) + " " + tree_icon(row) + row['name']
|
|
41
57
|
row['stack'] = "#{row['stack']}:#{row['version']}"
|
|
42
58
|
row['services_count'] = row['services'].size
|
|
43
59
|
row['ports'] = stack_ports(row).join(',')
|
|
@@ -59,6 +75,22 @@ module Kontena::Cli::Stacks
|
|
|
59
75
|
HEALTH_ICONS.fetch(health) { HEALTH_ICONS[:default] }
|
|
60
76
|
end
|
|
61
77
|
|
|
78
|
+
def tree_icon(row)
|
|
79
|
+
parent = row['parent']
|
|
80
|
+
children = row['children'] || []
|
|
81
|
+
if parent.nil? && children.empty?
|
|
82
|
+
# solo
|
|
83
|
+
char = ''
|
|
84
|
+
elsif parent.nil? && !children.empty?
|
|
85
|
+
char = ''
|
|
86
|
+
elsif !parent.nil?
|
|
87
|
+
char = '┗━'
|
|
88
|
+
end
|
|
89
|
+
left_pad = ' ' * (2 * (row['depth'] - 1))
|
|
90
|
+
right_pad = row['depth'] > 1 ? '━' : ''
|
|
91
|
+
left_pad + char + right_pad
|
|
92
|
+
end
|
|
93
|
+
|
|
62
94
|
# @param [Hash] stack
|
|
63
95
|
# @return [Array<String>]
|
|
64
96
|
def stack_ports(stack)
|
|
@@ -9,13 +9,20 @@ module Kontena::Cli::Stacks
|
|
|
9
9
|
banner "Shows logs from services in a stack"
|
|
10
10
|
|
|
11
11
|
parameter "NAME", "Stack name"
|
|
12
|
+
parameter "[SERVICE] ...", "Service names"
|
|
12
13
|
|
|
13
14
|
requires_current_master
|
|
14
15
|
requires_current_master_token
|
|
15
16
|
|
|
16
17
|
def execute
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
if service_list.empty?
|
|
19
|
+
show_logs("stacks/#{current_grid}/#{name}/container_logs") do |log|
|
|
20
|
+
show_log(log)
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
show_logs("grids/#{current_grid}/container_logs", services: service_list.map {|s| [name, s].join('/')}.join(',')) do |log|
|
|
24
|
+
show_log(log)
|
|
25
|
+
end
|
|
19
26
|
end
|
|
20
27
|
end
|
|
21
28
|
|
|
@@ -4,7 +4,7 @@ module Kontena::Cli::Stacks::Registry
|
|
|
4
4
|
class PullCommand < Kontena::Command
|
|
5
5
|
include Kontena::Cli::Common
|
|
6
6
|
include Kontena::Cli::Stacks::Common
|
|
7
|
-
include Kontena::Cli::Stacks::Common::
|
|
7
|
+
include Kontena::Cli::Stacks::Common::RegistryNameParam
|
|
8
8
|
|
|
9
9
|
banner "Pulls / downloads a stack from the stack registry"
|
|
10
10
|
|
|
@@ -14,7 +14,7 @@ module Kontena::Cli::Stacks::Registry
|
|
|
14
14
|
|
|
15
15
|
def execute
|
|
16
16
|
target = no_cache? ? stacks_client : Kontena::StacksCache
|
|
17
|
-
content = target.pull(stack_name,
|
|
17
|
+
content = target.pull(stack_name.stack_name, stack_name.version)
|
|
18
18
|
if return?
|
|
19
19
|
return content
|
|
20
20
|
elsif file
|
|
@@ -7,19 +7,30 @@ module Kontena::Cli::Stacks::Registry
|
|
|
7
7
|
|
|
8
8
|
banner "Pushes (uploads) a stack to the stack registry"
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
include Kontena::Cli::Stacks::Common::StackFileOrNameParam
|
|
11
|
+
include Kontena::Cli::Stacks::Common::StackValuesFromOption
|
|
11
12
|
|
|
12
13
|
requires_current_account_token
|
|
13
14
|
|
|
15
|
+
option '--dry-run', :flag, "Do not perform any uploading", hidden: true
|
|
16
|
+
|
|
17
|
+
def includes_local_dependencies?(dependencies = loader.dependencies)
|
|
18
|
+
return false if dependencies.nil?
|
|
19
|
+
dependencies.any? { |dep| Kontena::Cli::Stacks::YAML::StackFileLoader.for(dep['stack']).origin == 'file' || includes_local_dependencies(dep['depends']) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def includes_local_extends?
|
|
23
|
+
stack.fetch(:services) { {} }.any? { |svc| svc['extends'] && svc[:extends]['file'] }
|
|
24
|
+
end
|
|
25
|
+
|
|
14
26
|
def execute
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
stacks_client.push(file.stack_name, file.stack_version, file.raw_content)
|
|
27
|
+
set_env_variables(stack_name, 'validate', 'validate-platform')
|
|
28
|
+
|
|
29
|
+
exit_with_error "Stack file contains dependencies to local files" if includes_local_dependencies?
|
|
30
|
+
exit_with_error "Stack file has services that extend from local files" if includes_local_extends?
|
|
31
|
+
|
|
32
|
+
spinner("Pushing #{pastel.cyan(source)} to stacks registry as #{loader.stack_name}") do
|
|
33
|
+
stacks_client.push(stack_name, loader.stack_name.version, loader.content) unless dry_run?
|
|
23
34
|
end
|
|
24
35
|
end
|
|
25
36
|
end
|
|
@@ -4,7 +4,7 @@ module Kontena::Cli::Stacks::Registry
|
|
|
4
4
|
class RemoveCommand < Kontena::Command
|
|
5
5
|
include Kontena::Cli::Common
|
|
6
6
|
include Kontena::Cli::Stacks::Common
|
|
7
|
-
include Kontena::Cli::Stacks::Common::
|
|
7
|
+
include Kontena::Cli::Stacks::Common::RegistryNameParam
|
|
8
8
|
|
|
9
9
|
banner "Removes a stack (or version) from the stack registry. Use user/stack_name or user/stack_name:version."
|
|
10
10
|
|
|
@@ -14,8 +14,8 @@ module Kontena::Cli::Stacks::Registry
|
|
|
14
14
|
|
|
15
15
|
def execute
|
|
16
16
|
unless force?
|
|
17
|
-
if
|
|
18
|
-
puts "About to delete #{pastel.cyan("#{stack_name}
|
|
17
|
+
if stack_name.version
|
|
18
|
+
puts "About to delete #{pastel.cyan("#{stack_name}")} from the stacks registry"
|
|
19
19
|
confirm
|
|
20
20
|
else
|
|
21
21
|
puts "About to delete an entire stack and all of its versions from the stacks registry"
|
|
@@ -23,7 +23,7 @@ module Kontena::Cli::Stacks::Registry
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
spinner "Removing #{pastel.cyan(stack_name)} from the registry" do
|
|
26
|
-
stacks_client.destroy(stack_name,
|
|
26
|
+
stacks_client.destroy(stack_name.stack_name, stack_name.version)
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
end
|
|
@@ -4,7 +4,7 @@ module Kontena::Cli::Stacks::Registry
|
|
|
4
4
|
class ShowCommand < Kontena::Command
|
|
5
5
|
include Kontena::Cli::Common
|
|
6
6
|
include Kontena::Cli::Stacks::Common
|
|
7
|
-
include Kontena::Cli::Stacks::Common::
|
|
7
|
+
include Kontena::Cli::Stacks::Common::RegistryNameParam
|
|
8
8
|
|
|
9
9
|
banner "Shows information about a stack on the stacks registry"
|
|
10
10
|
|
|
@@ -15,16 +15,16 @@ module Kontena::Cli::Stacks::Registry
|
|
|
15
15
|
def execute
|
|
16
16
|
require 'semantic'
|
|
17
17
|
unless versions?
|
|
18
|
-
stack = ::YAML.safe_load(stacks_client.show(stack_name,
|
|
18
|
+
stack = ::YAML.safe_load(stacks_client.show(stack_name.stack_name, stack_name.version))
|
|
19
19
|
puts "#{stack['stack']}:"
|
|
20
|
-
puts " #{"latest_" unless
|
|
20
|
+
puts " #{"latest_" unless stack_name.version}version: #{stack['version']}"
|
|
21
21
|
puts " expose: #{stack['expose'] || '-'}"
|
|
22
22
|
puts " description: #{stack['description'] || '-'}"
|
|
23
23
|
|
|
24
24
|
puts " available_versions:"
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
stacks_client.versions(stack_name).reject {|s| s['version'].nil? || s['version'].empty?}.map { |s| Semantic::Version.new(s['version'])}.sort.reverse_each do |version|
|
|
27
|
+
stacks_client.versions(stack_name.stack_name).reject {|s| s['version'].nil? || s['version'].empty?}.map { |s| Semantic::Version.new(s['version'])}.sort.reverse_each do |version|
|
|
28
28
|
puts versions? ? version : " - #{version}"
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -10,12 +10,38 @@ module Kontena::Cli::Stacks
|
|
|
10
10
|
|
|
11
11
|
parameter "NAME", "Stack name"
|
|
12
12
|
option "--force", :flag, "Force remove", default: false, attribute_name: :forced
|
|
13
|
+
option "--keep-dependencies", :flag, "Do not remove dependencies"
|
|
13
14
|
|
|
14
15
|
requires_current_master
|
|
15
16
|
requires_current_master_token
|
|
16
17
|
|
|
18
|
+
def fetch_stack
|
|
19
|
+
client.get("stacks/#{current_grid}/#{name}")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def confirm_remove(stack)
|
|
23
|
+
if stack['parent']
|
|
24
|
+
puts "#{pastel.yellow('Warning:')} The stack #{pastel.cyan(stack['parent']['name'])} depends on stack #{name}"
|
|
25
|
+
end
|
|
26
|
+
if stack['children'] && !stack['children'].empty?
|
|
27
|
+
puts "#{pastel.yellow('Warning:')} The stack #{pastel.cyan(name)} has dependencies that will be removed:"
|
|
28
|
+
stack['children'].each do |child|
|
|
29
|
+
puts "- #{pastel.yellow(child['name'])}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
confirm_command(name)
|
|
33
|
+
end
|
|
34
|
+
|
|
17
35
|
def execute
|
|
18
|
-
|
|
36
|
+
stack = fetch_stack
|
|
37
|
+
confirm_remove(stack) unless forced?
|
|
38
|
+
unless keep_dependencies?
|
|
39
|
+
stack.fetch('children', Hash.new).each do |child_stack|
|
|
40
|
+
caret"Removing dependency #{pastel.cyan(child_stack['name'])}"
|
|
41
|
+
Kontena.run!(['stack', 'remove', '--force', child_stack['name']])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
19
45
|
spinner "Removing stack #{pastel.cyan(name)} " do
|
|
20
46
|
remove_stack(name)
|
|
21
47
|
wait_stack_removal(name)
|
|
@@ -27,12 +27,14 @@ module Kontena::Cli::Stacks
|
|
|
27
27
|
data = {}
|
|
28
28
|
data['instances'] = options['instances']
|
|
29
29
|
data['image'] = parse_image(options['image'])
|
|
30
|
-
data['env'] = options['environment']
|
|
30
|
+
data['env'] = options['environment'] || options['env']
|
|
31
31
|
data['links'] = parse_links(options['links'] || [])
|
|
32
32
|
data['external_links'] = parse_links(options['external_links'] || [])
|
|
33
33
|
data['ports'] = parse_stringified_ports(options['ports'] || [])
|
|
34
34
|
data['memory'] = parse_memory(options['mem_limit'].to_s) if options['mem_limit']
|
|
35
35
|
data['memory_swap'] = parse_memory(options['memswap_limit'].to_s) if options['memswap_limit']
|
|
36
|
+
data['shm_size'] = parse_memory(options['shm_size'].to_s) if options['shm_size']
|
|
37
|
+
data['cpus'] = options['cpus'] if options['cpus']
|
|
36
38
|
data['cpu_shares'] = options['cpu_shares'] if options['cpu_shares']
|
|
37
39
|
data['volumes'] = options['volumes'] || []
|
|
38
40
|
data['volumes_from'] = options['volumes_from'] || []
|
|
@@ -61,6 +63,7 @@ module Kontena::Cli::Stacks
|
|
|
61
63
|
data['deploy_opts'] = deploy
|
|
62
64
|
data['hooks'] = options['hooks'] || {}
|
|
63
65
|
data['secrets'] = options['secrets'] if options['secrets']
|
|
66
|
+
data['certificates'] = options['certificates'] if options['certificates']
|
|
64
67
|
data['build'] = parse_build_options(options) if options['build']
|
|
65
68
|
data['health_check'] = parse_health_check(options)
|
|
66
69
|
data['stop_grace_period'] = options['stop_grace_period'] if options['stop_grace_period']
|
|
@@ -85,7 +88,14 @@ module Kontena::Cli::Stacks
|
|
|
85
88
|
# @return [Array<Hash>]
|
|
86
89
|
def parse_links(link_options)
|
|
87
90
|
link_options.map{|l|
|
|
88
|
-
|
|
91
|
+
if l.kind_of?(String)
|
|
92
|
+
service_name, alias_name = l.split(':')
|
|
93
|
+
elsif l.kind_of?(Hash)
|
|
94
|
+
service_name = l['name']
|
|
95
|
+
alias_name = l['alias']
|
|
96
|
+
else
|
|
97
|
+
raise TypeError, "Invalid link type #{l.class.name}, expecting String or Hash"
|
|
98
|
+
end
|
|
89
99
|
if service_name.nil?
|
|
90
100
|
raise ArgumentError.new("Invalid link value #{l}")
|
|
91
101
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require_relative 'common'
|
|
2
|
+
require 'yaml'
|
|
2
3
|
|
|
3
4
|
module Kontena::Cli::Stacks
|
|
4
5
|
class ShowCommand < Kontena::Command
|
|
@@ -13,17 +14,35 @@ module Kontena::Cli::Stacks
|
|
|
13
14
|
requires_current_master
|
|
14
15
|
requires_current_master_token
|
|
15
16
|
|
|
17
|
+
option '--values', :flag, 'Output the variable-value pairs as YAML'
|
|
18
|
+
include Common::StackValuesToOption
|
|
19
|
+
|
|
16
20
|
def execute
|
|
17
|
-
|
|
21
|
+
write_variables if values_to
|
|
22
|
+
values? ? show_variables : show_stack
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def variables
|
|
26
|
+
@variables ||= stack['variables'] || {}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def stack
|
|
30
|
+
@stack ||= client.get("stacks/#{current_grid}/#{name}")
|
|
18
31
|
end
|
|
19
32
|
|
|
20
|
-
def
|
|
21
|
-
|
|
33
|
+
def show_variables
|
|
34
|
+
puts variable_yaml
|
|
22
35
|
end
|
|
23
36
|
|
|
24
|
-
def
|
|
25
|
-
|
|
37
|
+
def variable_yaml
|
|
38
|
+
::YAML.dump(variables)
|
|
39
|
+
end
|
|
26
40
|
|
|
41
|
+
def write_variables
|
|
42
|
+
File.write(values_to, variable_yaml)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def show_stack
|
|
27
46
|
puts "#{stack['name']}:"
|
|
28
47
|
puts " created: #{stack['created_at']}"
|
|
29
48
|
puts " updated: #{stack['updated_at']}"
|
|
@@ -32,6 +51,17 @@ module Kontena::Cli::Stacks
|
|
|
32
51
|
puts " version: #{stack['version']}"
|
|
33
52
|
puts " revision: #{stack['revision']}"
|
|
34
53
|
puts " expose: #{stack['expose'] || '-'}"
|
|
54
|
+
puts " variables:#{' -' if variables.empty?}"
|
|
55
|
+
variables.each do |var, val|
|
|
56
|
+
puts " #{var}: #{val}"
|
|
57
|
+
end
|
|
58
|
+
puts " parent: #{stack['parent'] ? stack['parent']['name'] : '-'}"
|
|
59
|
+
if stack['children'] && !stack['children'].empty?
|
|
60
|
+
puts " children:"
|
|
61
|
+
stack['children'].each do |child|
|
|
62
|
+
puts " - #{child['name']}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
35
65
|
puts " services:"
|
|
36
66
|
stack['services'].each do |service|
|
|
37
67
|
show_service(service['id'])
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'semantic'
|
|
2
|
+
|
|
3
|
+
module Kontena::Cli::Stacks
|
|
4
|
+
class StackName
|
|
5
|
+
# A class for parsing stack name strings, such as kontena/foo:1.0.0
|
|
6
|
+
|
|
7
|
+
attr_reader :user, :stack, :version
|
|
8
|
+
|
|
9
|
+
# @param definition [String] such as kontena/foo:1.0.0
|
|
10
|
+
# @param version [String] set version separately
|
|
11
|
+
# @return [StackName]
|
|
12
|
+
# @example
|
|
13
|
+
# name = StackName.new('kontena/foo:0.1.0')
|
|
14
|
+
# name.user => 'kontena'
|
|
15
|
+
# name.stack => 'foo'
|
|
16
|
+
# name.version => '0.1.0'
|
|
17
|
+
# name.stack_name => 'kontena/foo'
|
|
18
|
+
# name.to_s => 'kontena/foo:0.1.0
|
|
19
|
+
def initialize(definition = nil, version = nil)
|
|
20
|
+
if definition.kind_of?(Hash)
|
|
21
|
+
@user = definition[:user] || definition['user']
|
|
22
|
+
@stack = definition[:stack] || definition['stack']
|
|
23
|
+
@version = definition[:version] || definition['version'] || version
|
|
24
|
+
elsif definition.kind_of?(String)
|
|
25
|
+
parsed = parse(definition)
|
|
26
|
+
@user = parsed[:user]
|
|
27
|
+
@stack = parsed[:stack]
|
|
28
|
+
@version = parsed[:version] || version
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Stack name without version
|
|
33
|
+
# @return [String] example: kontena/foo
|
|
34
|
+
def stack_name
|
|
35
|
+
[user, stack].compact.join('/')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Full stack name including version if present
|
|
39
|
+
# @return [String] example: kontena/foo:0.1.0
|
|
40
|
+
def to_s
|
|
41
|
+
version ? "#{stack_name}:#{version}" : stack_name
|
|
42
|
+
end
|
|
43
|
+
alias to_str to_s
|
|
44
|
+
|
|
45
|
+
# True when version is a prerelease
|
|
46
|
+
# @return [NilClass,TrueClass,FalseClass] nil when no version, true when prerelease, false when not.
|
|
47
|
+
def pre?
|
|
48
|
+
return nil if version.nil?
|
|
49
|
+
!Semantic::Version.new(version).pre.nil?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def parse(definition)
|
|
55
|
+
return {} if definition.empty?
|
|
56
|
+
name, version = definition.split(':', 2)
|
|
57
|
+
if name.include?('/')
|
|
58
|
+
user, stack = name.split('/', 2)
|
|
59
|
+
else
|
|
60
|
+
user = nil
|
|
61
|
+
stack = name
|
|
62
|
+
end
|
|
63
|
+
{
|
|
64
|
+
user: user,
|
|
65
|
+
stack: stack,
|
|
66
|
+
version: version
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|