kontena-cli 1.4.0.pre6 → 1.4.0.pre7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|