bosh_cli 1.3001.0 → 1.3003.0
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/lib/cli.rb +1 -0
- data/lib/cli/base_command.rb +10 -10
- data/lib/cli/client/uaa/client.rb +1 -1
- data/lib/cli/commands/cloudcheck.rb +3 -3
- data/lib/cli/commands/deployment.rb +11 -14
- data/lib/cli/commands/errand.rb +1 -2
- data/lib/cli/commands/job_management.rb +10 -7
- data/lib/cli/commands/job_rename.rb +7 -11
- data/lib/cli/commands/log_management.rb +6 -9
- data/lib/cli/commands/property_management.rb +1 -3
- data/lib/cli/commands/release/export_release.rb +3 -5
- data/lib/cli/commands/snapshot.rb +4 -8
- data/lib/cli/commands/ssh.rb +17 -17
- data/lib/cli/commands/vm.rb +5 -4
- data/lib/cli/deployment_helper.rb +17 -164
- data/lib/cli/manifest.rb +172 -0
- data/lib/cli/version.rb +1 -1
- data/lib/cli/vm_state.rb +4 -5
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce5adb0bf07eb205144b59a5503f2831cd6c4706
|
4
|
+
data.tar.gz: 9d39b975d52d3183e8c636a7c5d72cd4f185c76a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cb26f22b9460558b5382088276075387f8b1d09a5595b06caf258a011b1c1bd87d3ded85ccb937d4865e1e0b2db6369e3541bfd483903edf432f225e0dabb70
|
7
|
+
data.tar.gz: 272037c9bfe1d1ca829d7a1af260604f070b773000417d7bbe3a862a8283dc603dc9083ee78dcc463b880c389dd1fa8605a0536d941bf168aea40010eb01d823
|
data/lib/cli.rb
CHANGED
data/lib/cli/base_command.rb
CHANGED
@@ -122,6 +122,14 @@ module Bosh::Cli
|
|
122
122
|
File.join(Dir.home, '.bosh', 'cache')
|
123
123
|
end
|
124
124
|
|
125
|
+
def show_current_state(deployment_name=nil)
|
126
|
+
user_desc = auth_info.client_auth? ? 'client' : 'user'
|
127
|
+
msg = "Acting as #{user_desc} '#{credentials.username.to_s.make_green}'"
|
128
|
+
msg += " on deployment '#{deployment_name.make_green}'" if deployment_name
|
129
|
+
msg += " on '#{target_name.make_green}'" if target_name
|
130
|
+
say(msg)
|
131
|
+
end
|
132
|
+
|
125
133
|
protected
|
126
134
|
|
127
135
|
def auth_info
|
@@ -187,14 +195,6 @@ module Bosh::Cli
|
|
187
195
|
say("Current deployment is #{deployment.make_green}")
|
188
196
|
end
|
189
197
|
|
190
|
-
def show_current_state(deployment_name=nil)
|
191
|
-
user_desc = auth_info.client_auth? ? 'client' : 'user'
|
192
|
-
msg = "Acting as #{user_desc} '#{credentials.username.to_s.make_green}'"
|
193
|
-
msg += " on deployment '#{deployment_name.make_green}'" if deployment_name
|
194
|
-
msg += " on '#{target_name.make_green}'" if target_name
|
195
|
-
say(msg)
|
196
|
-
end
|
197
|
-
|
198
198
|
def no_track_unsupported
|
199
199
|
if @options.delete(:no_track)
|
200
200
|
say('Ignoring `' + '--no-track'.make_yellow + "' option")
|
@@ -232,8 +232,8 @@ module Bosh::Cli
|
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
235
|
-
def valid_index_for(job, index, options = {})
|
236
|
-
index = '0' if job_unique_in_deployment?(job)
|
235
|
+
def valid_index_for(manifest_hash, job, index, options = {})
|
236
|
+
index = '0' if job_unique_in_deployment?(manifest_hash, job)
|
237
237
|
err('You should specify the job index. There is more than one instance of this job type.') if index.nil?
|
238
238
|
index = index.to_i if options[:integer_index]
|
239
239
|
index
|
@@ -13,12 +13,12 @@ module Bosh::Cli::Command
|
|
13
13
|
"don't attempt to resolve problems"
|
14
14
|
def perform(deployment_name = nil)
|
15
15
|
auth_required
|
16
|
-
show_current_state(deployment_name)
|
17
|
-
|
18
16
|
no_track_unsupported
|
19
17
|
@auto_mode = options[:auto]
|
20
18
|
@report_mode = options[:report]
|
21
19
|
|
20
|
+
deployment_name ||= prepare_deployment_manifest(show_state: true).name
|
21
|
+
|
22
22
|
if non_interactive? && !(@report_mode || @auto_mode)
|
23
23
|
err ("Cloudcheck cannot be run in non-interactive mode\n" +
|
24
24
|
"Please use `--auto' flag if you want automated resolutions " +
|
@@ -29,8 +29,8 @@ module Bosh::Cli::Command
|
|
29
29
|
err("Can't use --auto and --report mode together")
|
30
30
|
end
|
31
31
|
|
32
|
+
|
32
33
|
say("Performing cloud check...")
|
33
|
-
deployment_name ||= prepare_deployment_manifest["name"]
|
34
34
|
|
35
35
|
status, task_id = director.perform_cloud_scan(deployment_name)
|
36
36
|
|
@@ -23,7 +23,7 @@ module Bosh::Cli::Command
|
|
23
23
|
end
|
24
24
|
|
25
25
|
unless manifest["target"].blank?
|
26
|
-
err(
|
26
|
+
err(Bosh::Cli::Manifest::MANIFEST_TARGET_UPGRADE_NOTICE)
|
27
27
|
end
|
28
28
|
|
29
29
|
if manifest["director_uuid"].blank?
|
@@ -86,27 +86,24 @@ module Bosh::Cli::Command
|
|
86
86
|
recreate = !!options[:recreate]
|
87
87
|
redact_diff = !!options[:redact_diff]
|
88
88
|
|
89
|
-
manifest = prepare_deployment_manifest(resolve_properties: true)
|
90
|
-
manifest_yaml = Psych.dump(manifest)
|
89
|
+
manifest = prepare_deployment_manifest(resolve_properties: true, show_state: true)
|
91
90
|
|
92
91
|
inspect_deployment_changes(
|
93
|
-
|
92
|
+
manifest.hash,
|
94
93
|
interactive: interactive?,
|
95
94
|
redact_diff: redact_diff
|
96
95
|
)
|
97
96
|
say('Please review all changes carefully'.make_yellow) if interactive?
|
98
97
|
|
99
98
|
header('Deploying')
|
100
|
-
deployment_name = manifest['name']
|
101
|
-
show_current_state(deployment_name)
|
102
99
|
|
103
100
|
unless confirmed?('Are you sure you want to deploy?')
|
104
101
|
cancel_deployment
|
105
102
|
end
|
106
103
|
|
107
|
-
status, task_id = director.deploy(
|
104
|
+
status, task_id = director.deploy(manifest.yaml, :recreate => recreate)
|
108
105
|
|
109
|
-
task_report(status, task_id, "Deployed `#{
|
106
|
+
task_report(status, task_id, "Deployed `#{manifest.name.make_green}' to `#{target_name.make_green}'")
|
110
107
|
end
|
111
108
|
|
112
109
|
# bosh delete deployment
|
@@ -142,14 +139,14 @@ module Bosh::Cli::Command
|
|
142
139
|
"deployment manifest as the source of properties"
|
143
140
|
def validate_jobs
|
144
141
|
check_if_release_dir
|
145
|
-
manifest = prepare_deployment_manifest(:resolve_properties => true)
|
142
|
+
manifest = prepare_deployment_manifest(:resolve_properties => true, show_state: true)
|
146
143
|
|
147
|
-
if manifest["release"]
|
148
|
-
release_name = manifest["release"]["name"]
|
149
|
-
elsif manifest["releases"].count > 1
|
144
|
+
if manifest.hash["release"]
|
145
|
+
release_name = manifest.hash["release"]["name"]
|
146
|
+
elsif manifest.hash["releases"].count > 1
|
150
147
|
err("Cannot validate a deployment manifest with more than 1 release")
|
151
148
|
else
|
152
|
-
release_name = manifest["releases"].first["name"]
|
149
|
+
release_name = manifest.hash["releases"].first["name"]
|
153
150
|
end
|
154
151
|
if release_name == release.dev_name || release_name == release.final_name
|
155
152
|
nl
|
@@ -169,7 +166,7 @@ module Bosh::Cli::Command
|
|
169
166
|
)
|
170
167
|
|
171
168
|
say(" - validating properties")
|
172
|
-
validator = Bosh::Cli::JobPropertyValidator.new(jobs, manifest)
|
169
|
+
validator = Bosh::Cli::JobPropertyValidator.new(jobs, manifest.hash)
|
173
170
|
validator.validate
|
174
171
|
|
175
172
|
unless validator.jobs_without_properties.empty?
|
data/lib/cli/commands/errand.rb
CHANGED
@@ -38,8 +38,7 @@ module Bosh::Cli::Command
|
|
38
38
|
|
39
39
|
private
|
40
40
|
def perform_run_errand(errand_name)
|
41
|
-
deployment_name = prepare_deployment_manifest
|
42
|
-
show_current_state(deployment_name)
|
41
|
+
deployment_name = prepare_deployment_manifest(show_state: true).name
|
43
42
|
|
44
43
|
errands_client = Bosh::Cli::Client::ErrandsClient.new(director)
|
45
44
|
status, task_id, errand_result = errands_client.run_errand(deployment_name, errand_name, options[:keep_alive] || FALSE)
|
@@ -48,9 +48,11 @@ module Bosh::Cli
|
|
48
48
|
private
|
49
49
|
|
50
50
|
def change_job_state(state, job, index = nil)
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
auth_required
|
52
|
+
manifest = parse_manifest(state, job)
|
53
|
+
|
54
|
+
index = valid_index_for(manifest.hash, job, index)
|
55
|
+
vm_state = VmState.new(self, manifest, force?)
|
54
56
|
job_state = JobState.new(self, vm_state)
|
55
57
|
status, task_id, completion_desc = job_state.change(state, job, index)
|
56
58
|
task_report(status, task_id, completion_desc)
|
@@ -68,10 +70,9 @@ module Bosh::Cli
|
|
68
70
|
options[:force]
|
69
71
|
end
|
70
72
|
|
71
|
-
def
|
72
|
-
|
73
|
-
job_must_exist_in_deployment(job)
|
74
|
-
show_current_state(prepare_deployment_manifest['name'])
|
73
|
+
def parse_manifest(operation, job)
|
74
|
+
manifest = prepare_deployment_manifest(show_state: true)
|
75
|
+
job_must_exist_in_deployment(manifest.hash, job)
|
75
76
|
|
76
77
|
if hard? && soft?
|
77
78
|
err('Cannot handle both --hard and --soft options, please choose one')
|
@@ -80,6 +81,8 @@ module Bosh::Cli
|
|
80
81
|
if !hard_and_soft_options_allowed?(operation) && (hard? || soft?)
|
81
82
|
err("--hard and --soft options only make sense for `stop' operation")
|
82
83
|
end
|
84
|
+
|
85
|
+
manifest
|
83
86
|
end
|
84
87
|
|
85
88
|
def hard_and_soft_options_allowed?(operation)
|
@@ -7,9 +7,7 @@ module Bosh::Cli::Command
|
|
7
7
|
option "--force", "Ignore errors"
|
8
8
|
def rename(old_name, new_name)
|
9
9
|
auth_required
|
10
|
-
|
11
|
-
manifest = Psych.load(manifest_yaml)
|
12
|
-
show_current_state(manifest['name'])
|
10
|
+
manifest = prepare_deployment_manifest(show_state: true)
|
13
11
|
|
14
12
|
force = options[:force]
|
15
13
|
say("You are about to rename `#{old_name.make_green}' to `#{new_name.make_green}'")
|
@@ -20,18 +18,17 @@ module Bosh::Cli::Command
|
|
20
18
|
exit(0)
|
21
19
|
end
|
22
20
|
|
23
|
-
sanity_check_job_rename(
|
21
|
+
sanity_check_job_rename(manifest, old_name, new_name)
|
24
22
|
|
25
23
|
status, task_id = director.rename_job(
|
26
|
-
manifest
|
24
|
+
manifest.name, manifest.yaml, old_name, new_name, force)
|
27
25
|
|
28
26
|
task_report(status, task_id, "Rename successful")
|
29
27
|
end
|
30
28
|
|
31
|
-
def sanity_check_job_rename(
|
29
|
+
def sanity_check_job_rename(manifest, old_name, new_name)
|
32
30
|
# Makes sure the new deployment manifest contains the renamed job
|
33
|
-
|
34
|
-
new_jobs = manifest["jobs"].map { |job| job["name"] }
|
31
|
+
new_jobs = manifest.hash["jobs"].map { |job| job["name"] }
|
35
32
|
unless new_jobs.include?(new_name)
|
36
33
|
err("Please update your deployment manifest to include the " +
|
37
34
|
"new job name `#{new_name}'")
|
@@ -43,7 +40,7 @@ module Bosh::Cli::Command
|
|
43
40
|
end
|
44
41
|
|
45
42
|
# Make sure that the old deployment manifest contains the old job
|
46
|
-
current_deployment = director.get_deployment(manifest
|
43
|
+
current_deployment = director.get_deployment(manifest.name)
|
47
44
|
if current_deployment["manifest"].nil?
|
48
45
|
err("Director could not find manifest for deployment " +
|
49
46
|
"`#{manifest["name"]}'")
|
@@ -96,8 +93,7 @@ module Bosh::Cli::Command
|
|
96
93
|
end
|
97
94
|
|
98
95
|
# Now the manifests should be the same
|
99
|
-
|
100
|
-
if deployment_changed?(current_manifest.dup, manifest.dup)
|
96
|
+
if deployment_changed?(current_manifest.dup, manifest.hash.dup)
|
101
97
|
err("You cannot have any other changes to your manifest during " +
|
102
98
|
"rename. Please revert the above changes and retry.")
|
103
99
|
end
|
@@ -12,17 +12,20 @@ module Bosh::Cli::Command
|
|
12
12
|
option '--all', 'deprecated'
|
13
13
|
|
14
14
|
def fetch_logs(job, index = nil)
|
15
|
-
|
15
|
+
auth_required
|
16
|
+
|
17
|
+
manifest = prepare_deployment_manifest(show_state: true)
|
18
|
+
index = valid_index_for(manifest.hash, job, index)
|
16
19
|
check_arguments(index)
|
17
20
|
|
18
21
|
logs_downloader = Bosh::Cli::LogsDownloader.new(director, self)
|
19
22
|
|
20
|
-
resource_id = fetch_log_resource_id(index, job)
|
23
|
+
resource_id = fetch_log_resource_id(manifest.name, index, job)
|
21
24
|
logs_path = logs_downloader.build_destination_path(job, index, options[:dir] || Dir.pwd)
|
22
25
|
logs_downloader.download(resource_id, logs_path)
|
23
26
|
end
|
24
27
|
|
25
|
-
def fetch_log_resource_id(index, job)
|
28
|
+
def fetch_log_resource_id(deployment_name, index, job)
|
26
29
|
resource_id = director.fetch_logs(deployment_name, job, index, log_type, filters)
|
27
30
|
err('Error retrieving logs') if resource_id.nil?
|
28
31
|
|
@@ -40,8 +43,6 @@ module Bosh::Cli::Command
|
|
40
43
|
end
|
41
44
|
|
42
45
|
def check_arguments(index)
|
43
|
-
auth_required
|
44
|
-
show_current_state(deployment_name)
|
45
46
|
no_track_unsupported
|
46
47
|
|
47
48
|
err('Job index is expected to be a positive integer') if index !~ /^\d+$/
|
@@ -73,10 +74,6 @@ module Bosh::Cli::Command
|
|
73
74
|
end
|
74
75
|
filter
|
75
76
|
end
|
76
|
-
|
77
|
-
def deployment_name
|
78
|
-
@deployment_name ||= prepare_deployment_manifest['name']
|
79
|
-
end
|
80
77
|
end
|
81
78
|
end
|
82
79
|
|
@@ -121,9 +121,7 @@ module Bosh::Cli::Command
|
|
121
121
|
|
122
122
|
def prepare
|
123
123
|
auth_required
|
124
|
-
|
125
|
-
@deployment_name = manifest["name"]
|
126
|
-
show_current_state(@deployment_name)
|
124
|
+
@deployment_name = prepare_deployment_manifest(show_state: true).name
|
127
125
|
end
|
128
126
|
|
129
127
|
def show_header
|
@@ -11,18 +11,16 @@ module Bosh::Cli::Command
|
|
11
11
|
|
12
12
|
def export(release, stemcell)
|
13
13
|
auth_required
|
14
|
-
|
15
|
-
show_current_state
|
14
|
+
manifest = prepare_deployment_manifest(show_state: true)
|
16
15
|
|
17
|
-
deployment_name = prepare_deployment_manifest["name"]
|
18
16
|
release = Bosh::Cli::NameVersionPair.parse(release)
|
19
17
|
stemcell = Bosh::Cli::NameVersionPair.parse(stemcell)
|
20
18
|
stemcell_os = stemcell.name
|
21
19
|
|
22
20
|
client = Bosh::Cli::Client::ExportReleaseClient.new(director)
|
23
|
-
status, task_id = client.export(
|
21
|
+
status, task_id = client.export(manifest.name, release.name, release.version, stemcell_os, stemcell.version)
|
24
22
|
task_report(status, task_id)
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
28
|
-
end
|
26
|
+
end
|
@@ -7,8 +7,7 @@ module Bosh::Cli::Command
|
|
7
7
|
def list(job = nil, index = nil)
|
8
8
|
auth_required
|
9
9
|
|
10
|
-
deployment_name = prepare_deployment_manifest
|
11
|
-
show_current_state(deployment_name)
|
10
|
+
deployment_name = prepare_deployment_manifest(show_state: true).name
|
12
11
|
|
13
12
|
snapshots = director.list_snapshots(deployment_name, job, index)
|
14
13
|
|
@@ -39,8 +38,7 @@ module Bosh::Cli::Command
|
|
39
38
|
def take(job = nil, index = nil)
|
40
39
|
auth_required
|
41
40
|
|
42
|
-
deployment_name = prepare_deployment_manifest
|
43
|
-
show_current_state(deployment_name)
|
41
|
+
deployment_name = prepare_deployment_manifest(show_state: true).name
|
44
42
|
|
45
43
|
unless job && index
|
46
44
|
unless confirmed?("Are you sure you want to take a snapshot of all deployment `#{deployment_name}'?")
|
@@ -59,8 +57,7 @@ module Bosh::Cli::Command
|
|
59
57
|
def delete(snapshot_cid)
|
60
58
|
auth_required
|
61
59
|
|
62
|
-
deployment_name = prepare_deployment_manifest
|
63
|
-
show_current_state(deployment_name)
|
60
|
+
deployment_name = prepare_deployment_manifest(show_state: true).name
|
64
61
|
|
65
62
|
unless confirmed?("Are you sure you want to delete snapshot `#{snapshot_cid}'?")
|
66
63
|
say('Canceled deleting snapshot'.make_green)
|
@@ -77,8 +74,7 @@ module Bosh::Cli::Command
|
|
77
74
|
def delete_all
|
78
75
|
auth_required
|
79
76
|
|
80
|
-
deployment_name = prepare_deployment_manifest
|
81
|
-
show_current_state(deployment_name)
|
77
|
+
deployment_name = prepare_deployment_manifest(show_state: true).name
|
82
78
|
|
83
79
|
unless confirmed?("Are you sure you want to delete all snapshots of deployment `#{deployment_name}'?")
|
84
80
|
say('Canceled deleting snapshots'.make_green)
|
data/lib/cli/commands/ssh.rb
CHANGED
@@ -25,14 +25,16 @@ module Bosh::Cli
|
|
25
25
|
job, index = prompt_for_job_and_index
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
manifest = prepare_deployment_manifest(show_state: true)
|
29
|
+
job_must_exist_in_deployment(manifest.hash, job)
|
30
|
+
|
31
|
+
index = valid_index_for(manifest.hash, job, index, integer_index: true)
|
30
32
|
|
31
33
|
if command.empty?
|
32
|
-
setup_interactive_shell(job, index)
|
34
|
+
setup_interactive_shell(manifest.name, job, index)
|
33
35
|
else
|
34
36
|
say("Executing `#{command.join(' ')}' on #{job}/#{index}")
|
35
|
-
perform_operation(:exec, job, index, command)
|
37
|
+
perform_operation(:exec, manifest.name, job, index, command)
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
@@ -55,13 +57,14 @@ module Bosh::Cli
|
|
55
57
|
err('Please specify either --upload or --download')
|
56
58
|
end
|
57
59
|
|
58
|
-
|
60
|
+
manifest = prepare_deployment_manifest(show_state: true)
|
61
|
+
job_must_exist_in_deployment(manifest.hash, job)
|
59
62
|
|
60
63
|
if args.size != 2
|
61
64
|
err('Please enter valid source and destination paths')
|
62
65
|
end
|
63
66
|
say("Executing file operations on job #{job}")
|
64
|
-
perform_operation(upload ? :upload : :download, job, index, args)
|
67
|
+
perform_operation(upload ? :upload : :download, manifest.name, job, index, args)
|
65
68
|
end
|
66
69
|
|
67
70
|
usage 'cleanup ssh'
|
@@ -73,12 +76,11 @@ module Bosh::Cli
|
|
73
76
|
err("SSH cleanup doesn't accept any extra args")
|
74
77
|
end
|
75
78
|
|
76
|
-
|
77
|
-
|
78
|
-
manifest_name = prepare_deployment_manifest['name']
|
79
|
+
manifest = prepare_deployment_manifest(show_state: true)
|
80
|
+
job_must_exist_in_deployment(manifest.hash, job)
|
79
81
|
|
80
82
|
say("Cleaning up ssh artifacts from #{job}/#{index}")
|
81
|
-
director.cleanup_ssh(
|
83
|
+
director.cleanup_ssh(manifest.name, job, "^#{SSH_USER_PREFIX}", [index])
|
82
84
|
end
|
83
85
|
|
84
86
|
private
|
@@ -106,9 +108,8 @@ module Bosh::Cli
|
|
106
108
|
# @param [String] job
|
107
109
|
# @param [Integer] index
|
108
110
|
# @param [optional,String] password
|
109
|
-
def setup_ssh(job, index, password
|
111
|
+
def setup_ssh(deployment_name, job, index, password)
|
110
112
|
user = random_ssh_username
|
111
|
-
deployment_name = prepare_deployment_manifest['name']
|
112
113
|
|
113
114
|
say("Target deployment is `#{deployment_name}'")
|
114
115
|
nl
|
@@ -166,8 +167,7 @@ module Bosh::Cli
|
|
166
167
|
|
167
168
|
# @param [String] job Job name
|
168
169
|
# @param [Integer] index Job index
|
169
|
-
def setup_interactive_shell(job, index)
|
170
|
-
deployment_required
|
170
|
+
def setup_interactive_shell(deployment_name, job, index)
|
171
171
|
password = options[:default_password]
|
172
172
|
|
173
173
|
if password.nil?
|
@@ -178,7 +178,7 @@ module Bosh::Cli
|
|
178
178
|
err('Please provide ssh password') if password.blank?
|
179
179
|
end
|
180
180
|
|
181
|
-
setup_ssh(job, index, password) do |sessions, user, gateway|
|
181
|
+
setup_ssh(deployment_name, job, index, password) do |sessions, user, gateway|
|
182
182
|
session = sessions.first
|
183
183
|
|
184
184
|
unless session['status'] == 'success' && session['ip']
|
@@ -199,8 +199,8 @@ module Bosh::Cli
|
|
199
199
|
end
|
200
200
|
end
|
201
201
|
|
202
|
-
def perform_operation(operation, job, index, args)
|
203
|
-
setup_ssh(job, index, nil) do |sessions, user, gateway|
|
202
|
+
def perform_operation(operation, deployment_name, job, index, args)
|
203
|
+
setup_ssh(deployment_name, job, index, nil) do |sessions, user, gateway|
|
204
204
|
sessions.each do |session|
|
205
205
|
unless session['status'] == 'success' && session['ip']
|
206
206
|
err("Failed to set up SSH on #{job}/#{index}: #{session.inspect}")
|
data/lib/cli/commands/vm.rb
CHANGED
@@ -9,6 +9,7 @@ module Bosh::Cli
|
|
9
9
|
def resurrection_state(job=nil, index=nil, new_state)
|
10
10
|
if job.nil? && index.nil?
|
11
11
|
resurrection = Resurrection.new(new_state)
|
12
|
+
show_current_state
|
12
13
|
|
13
14
|
director.change_vm_resurrection_for_all(resurrection.paused?)
|
14
15
|
else
|
@@ -16,11 +17,11 @@ module Bosh::Cli
|
|
16
17
|
job, index, _ = job_args.to_a
|
17
18
|
resurrection = Resurrection.new(new_state)
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
manifest = prepare_deployment_manifest(show_state: true)
|
21
|
+
job_must_exist_in_deployment(manifest.hash, job)
|
22
|
+
index = valid_index_for(manifest.hash, job, index, integer_index: true)
|
21
23
|
|
22
|
-
manifest
|
23
|
-
director.change_vm_resurrection(manifest['name'], job, index, resurrection.paused?)
|
24
|
+
director.change_vm_resurrection(manifest.name, job, index, resurrection.paused?)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
@@ -2,68 +2,17 @@ module Bosh::Cli
|
|
2
2
|
module DeploymentHelper
|
3
3
|
def prepare_deployment_manifest(options = {})
|
4
4
|
deployment_required
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
header('Processing deployment manifest')
|
12
|
-
|
13
|
-
manifest = load_yaml_file(manifest_filename)
|
14
|
-
manifest_yaml = File.read(manifest_filename)
|
15
|
-
|
16
|
-
if manifest['name'].blank?
|
17
|
-
err('Deployment name not found in the deployment manifest')
|
18
|
-
end
|
19
|
-
|
20
|
-
if manifest['target']
|
21
|
-
err(manifest_target_upgrade_notice)
|
22
|
-
end
|
23
|
-
|
24
|
-
if options[:resolve_properties]
|
25
|
-
compiler = DeploymentManifestCompiler.new(manifest_yaml)
|
26
|
-
properties = {}
|
27
|
-
|
28
|
-
begin
|
29
|
-
say('Getting deployment properties from director...')
|
30
|
-
properties = director.list_properties(manifest['name'])
|
31
|
-
rescue Bosh::Cli::DirectorError
|
32
|
-
say('Unable to get properties list from director, ' +
|
33
|
-
'trying without it...')
|
34
|
-
end
|
35
|
-
|
36
|
-
say('Compiling deployment manifest...')
|
37
|
-
compiler.properties = properties.inject({}) do |hash, property|
|
38
|
-
hash[property['name']] = property['value']
|
39
|
-
hash
|
40
|
-
end
|
41
|
-
|
42
|
-
manifest = Psych.load(compiler.result)
|
5
|
+
manifest = Manifest.new(deployment, director)
|
6
|
+
manifest.load
|
7
|
+
if options.fetch(:show_state, false)
|
8
|
+
show_current_state(manifest.name)
|
43
9
|
end
|
10
|
+
manifest.validate(options)
|
44
11
|
|
45
|
-
|
46
|
-
err("Invalid manifest `#{File.basename(deployment)}': " +
|
47
|
-
'name and director UUID are required')
|
48
|
-
end
|
49
|
-
|
50
|
-
if director.uuid != manifest['director_uuid']
|
51
|
-
err("Target director UUID doesn't match UUID from deployment manifest")
|
52
|
-
end
|
53
|
-
|
54
|
-
if manifest['release'].blank? && manifest['releases'].blank?
|
55
|
-
err("Deployment manifest doesn't have release information: '" +
|
56
|
-
"please add 'release' or 'releases' section")
|
57
|
-
end
|
58
|
-
|
59
|
-
resolve_release_aliases(manifest)
|
60
|
-
resolve_stemcell_aliases(manifest)
|
61
|
-
|
62
|
-
report_manifest_warnings(manifest)
|
63
|
-
|
64
|
-
options[:yaml] ? Psych.dump(manifest) : manifest
|
12
|
+
manifest
|
65
13
|
end
|
66
14
|
|
15
|
+
|
67
16
|
# Check if the 2 deployments are different.
|
68
17
|
# Print out a summary if "show" is true.
|
69
18
|
def deployment_changed?(current_manifest, manifest, show = true)
|
@@ -201,55 +150,17 @@ module Bosh::Cli
|
|
201
150
|
end
|
202
151
|
end
|
203
152
|
|
204
|
-
def
|
205
|
-
|
206
|
-
director.list_releases.inject({}) do |hash, release|
|
207
|
-
name = release['name']
|
208
|
-
versions = release['versions'] || release['release_versions'].map { |release_version| release_version['version'] }
|
209
|
-
parsed_versions = versions.map do |version|
|
210
|
-
{
|
211
|
-
original: version,
|
212
|
-
parsed: Bosh::Common::Version::ReleaseVersion.parse(version)
|
213
|
-
}
|
214
|
-
end
|
215
|
-
latest_version = parsed_versions.sort_by {|v| v[:parsed] }.last[:original]
|
216
|
-
hash[name] = latest_version.to_s
|
217
|
-
hash
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
# @param [Hash] manifest Deployment manifest (will be modified)
|
223
|
-
# @return [void]
|
224
|
-
def resolve_release_aliases(manifest)
|
225
|
-
releases = manifest['releases'] || [manifest['release']]
|
226
|
-
|
227
|
-
releases.each do |release|
|
228
|
-
if release['version'] == 'latest'
|
229
|
-
latest_release_version = latest_release_versions[release['name']]
|
230
|
-
unless latest_release_version
|
231
|
-
err("Release '#{release['name']}' not found on director. Unable to resolve 'latest' alias in manifest.")
|
232
|
-
end
|
233
|
-
release['version'] = latest_release_version
|
234
|
-
end
|
235
|
-
|
236
|
-
if release['version'].to_i.to_s == release['version']
|
237
|
-
release['version'] = release['version'].to_i
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
def job_unique_in_deployment?(job_name)
|
243
|
-
job = find_job(job_name)
|
153
|
+
def job_unique_in_deployment?(manifest_hash, job_name)
|
154
|
+
job = find_job(manifest_hash, job_name)
|
244
155
|
job ? job.fetch('instances') == 1 : false
|
245
156
|
end
|
246
157
|
|
247
|
-
def job_exists_in_deployment?(job_name)
|
248
|
-
!!find_job(job_name)
|
158
|
+
def job_exists_in_deployment?(manifest_hash, job_name)
|
159
|
+
!!find_job(manifest_hash, job_name)
|
249
160
|
end
|
250
161
|
|
251
|
-
def job_must_exist_in_deployment(job)
|
252
|
-
err("Job `#{job}' doesn't exist") unless job_exists_in_deployment?(job)
|
162
|
+
def job_must_exist_in_deployment(manifest_hash, job)
|
163
|
+
err("Job `#{job}' doesn't exist") unless job_exists_in_deployment?(manifest_hash, job)
|
253
164
|
end
|
254
165
|
|
255
166
|
def prompt_for_job_and_index
|
@@ -280,7 +191,7 @@ module Bosh::Cli
|
|
280
191
|
end
|
281
192
|
|
282
193
|
def jobs_and_indexes
|
283
|
-
jobs = prepare_deployment_manifest.fetch('jobs')
|
194
|
+
jobs = prepare_deployment_manifest.hash.fetch('jobs')
|
284
195
|
|
285
196
|
jobs.inject([]) do |jobs_and_indexes, job|
|
286
197
|
job_name = job.fetch('name')
|
@@ -297,13 +208,13 @@ module Bosh::Cli
|
|
297
208
|
|
298
209
|
private
|
299
210
|
|
300
|
-
def find_job(job_name)
|
301
|
-
jobs =
|
211
|
+
def find_job(manifest_hash, job_name)
|
212
|
+
jobs = manifest_hash.fetch('jobs')
|
302
213
|
jobs.find { |job| job.fetch('name') == job_name }
|
303
214
|
end
|
304
215
|
|
305
216
|
def list_errands
|
306
|
-
deployment_name = prepare_deployment_manifest.
|
217
|
+
deployment_name = prepare_deployment_manifest.name
|
307
218
|
director.list_errands(deployment_name)
|
308
219
|
end
|
309
220
|
|
@@ -315,15 +226,6 @@ module Bosh::Cli
|
|
315
226
|
end
|
316
227
|
end
|
317
228
|
|
318
|
-
def manifest_target_upgrade_notice
|
319
|
-
<<-EOS.gsub(/^\s*/, '').gsub(/\n$/, '')
|
320
|
-
Please upgrade your deployment manifest to use director UUID instead
|
321
|
-
of target. Just replace 'target' key with 'director_uuid' key in your
|
322
|
-
manifest. You can get your director UUID by targeting your director
|
323
|
-
with 'bosh target' and running 'bosh status' command afterwards.
|
324
|
-
EOS
|
325
|
-
end
|
326
|
-
|
327
229
|
def print_summary(diff, key, redact, title = nil)
|
328
230
|
title ||= key.to_s.gsub(/[-_]/, ' ').capitalize
|
329
231
|
|
@@ -363,54 +265,5 @@ module Bosh::Cli
|
|
363
265
|
end
|
364
266
|
end
|
365
267
|
end
|
366
|
-
|
367
|
-
# @param [Hash] manifest Deployment manifest (will be modified)
|
368
|
-
# @return [void]
|
369
|
-
def resolve_stemcell_aliases(manifest)
|
370
|
-
return if manifest['resource_pools'].nil?
|
371
|
-
|
372
|
-
manifest['resource_pools'].each do |rp|
|
373
|
-
stemcell = rp['stemcell']
|
374
|
-
unless stemcell.is_a?(Hash)
|
375
|
-
err('Invalid stemcell spec in the deployment manifest')
|
376
|
-
end
|
377
|
-
if stemcell['version'] == 'latest'
|
378
|
-
latest_version = latest_stemcells[stemcell['name']]
|
379
|
-
if latest_version.nil?
|
380
|
-
err("Latest version for stemcell `#{stemcell['name']}' is unknown")
|
381
|
-
end
|
382
|
-
# Avoiding {Float,Fixnum} -> String noise in diff
|
383
|
-
if latest_version.to_s == latest_version.to_f.to_s
|
384
|
-
latest_version = latest_version.to_f
|
385
|
-
elsif latest_version.to_s == latest_version.to_i.to_s
|
386
|
-
latest_version = latest_version.to_i
|
387
|
-
end
|
388
|
-
stemcell['version'] = latest_version
|
389
|
-
end
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
# @return [Array]
|
394
|
-
def latest_stemcells
|
395
|
-
@_latest_stemcells ||= begin
|
396
|
-
stemcells = director.list_stemcells.inject({}) do |hash, stemcell|
|
397
|
-
unless stemcell.is_a?(Hash) && stemcell['name'] && stemcell['version']
|
398
|
-
err('Invalid director stemcell list format')
|
399
|
-
end
|
400
|
-
hash[stemcell['name']] ||= []
|
401
|
-
hash[stemcell['name']] << stemcell['version']
|
402
|
-
hash
|
403
|
-
end
|
404
|
-
|
405
|
-
stemcells.inject({}) do |hash, (name, versions)|
|
406
|
-
hash[name] = Bosh::Common::Version::StemcellVersionList.parse(versions).latest.to_s
|
407
|
-
hash
|
408
|
-
end
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
def report_manifest_warnings(manifest)
|
413
|
-
ManifestWarnings.new(manifest).report
|
414
|
-
end
|
415
268
|
end
|
416
269
|
end
|
data/lib/cli/manifest.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
module Bosh::Cli
|
2
|
+
class Manifest
|
3
|
+
attr_reader :hash
|
4
|
+
|
5
|
+
def initialize(deployment_file, director)
|
6
|
+
@deployment_file = deployment_file
|
7
|
+
@director = director
|
8
|
+
end
|
9
|
+
|
10
|
+
def name
|
11
|
+
@hash['name']
|
12
|
+
end
|
13
|
+
|
14
|
+
def load
|
15
|
+
unless File.exists?(@deployment_file)
|
16
|
+
err("Cannot find deployment manifest in `#{@deployment_file}'")
|
17
|
+
end
|
18
|
+
|
19
|
+
@hash = load_yaml_file(@deployment_file)
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate(options={})
|
23
|
+
if @hash['name'].blank?
|
24
|
+
err('Deployment name not found in the deployment manifest')
|
25
|
+
end
|
26
|
+
|
27
|
+
if @hash['target']
|
28
|
+
err(MANIFEST_TARGET_UPGRADE_NOTICE)
|
29
|
+
end
|
30
|
+
|
31
|
+
if options[:resolve_properties]
|
32
|
+
compiler = DeploymentManifestCompiler.new(File.read(@deployment_file))
|
33
|
+
properties = {}
|
34
|
+
|
35
|
+
begin
|
36
|
+
say('Getting deployment properties from director...')
|
37
|
+
properties = @director.list_properties(name)
|
38
|
+
rescue Bosh::Cli::DirectorError
|
39
|
+
say('Unable to get properties list from director, ' +
|
40
|
+
'trying without it...')
|
41
|
+
end
|
42
|
+
|
43
|
+
compiler.properties = properties.inject({}) do |hash, property|
|
44
|
+
hash[property['name']] = property['value']
|
45
|
+
hash
|
46
|
+
end
|
47
|
+
|
48
|
+
@hash = Psych.load(compiler.result)
|
49
|
+
end
|
50
|
+
|
51
|
+
if name.blank? || @hash['director_uuid'].blank?
|
52
|
+
err("Invalid manifest `#{File.basename(@deployment_file)}': " +
|
53
|
+
'name and director UUID are required')
|
54
|
+
end
|
55
|
+
|
56
|
+
if @director.uuid != @hash['director_uuid']
|
57
|
+
err("Target director UUID doesn't match UUID from deployment manifest")
|
58
|
+
end
|
59
|
+
|
60
|
+
if @hash['release'].blank? && @hash['releases'].blank?
|
61
|
+
err("Deployment manifest doesn't have release information: '" +
|
62
|
+
"please add 'release' or 'releases' section")
|
63
|
+
end
|
64
|
+
|
65
|
+
resolve_release_aliases
|
66
|
+
resolve_stemcell_aliases
|
67
|
+
|
68
|
+
report_manifest_warnings
|
69
|
+
|
70
|
+
@hash
|
71
|
+
end
|
72
|
+
|
73
|
+
def yaml
|
74
|
+
@yaml ||= Psych.dump(@hash)
|
75
|
+
end
|
76
|
+
|
77
|
+
# @param [Hash] manifest Deployment manifest (will be modified)
|
78
|
+
# @return [void]
|
79
|
+
def resolve_stemcell_aliases
|
80
|
+
return if @hash['resource_pools'].nil?
|
81
|
+
|
82
|
+
@hash['resource_pools'].each do |rp|
|
83
|
+
stemcell = rp['stemcell']
|
84
|
+
unless stemcell.is_a?(Hash)
|
85
|
+
err('Invalid stemcell spec in the deployment manifest')
|
86
|
+
end
|
87
|
+
if stemcell['version'] == 'latest'
|
88
|
+
latest_version = latest_stemcells[stemcell['name']]
|
89
|
+
if latest_version.nil?
|
90
|
+
err("Latest version for stemcell `#{stemcell['name']}' is unknown")
|
91
|
+
end
|
92
|
+
# Avoiding {Float,Fixnum} -> String noise in diff
|
93
|
+
if latest_version.to_s == latest_version.to_f.to_s
|
94
|
+
latest_version = latest_version.to_f
|
95
|
+
elsif latest_version.to_s == latest_version.to_i.to_s
|
96
|
+
latest_version = latest_version.to_i
|
97
|
+
end
|
98
|
+
stemcell['version'] = latest_version
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [Array]
|
104
|
+
def latest_stemcells
|
105
|
+
@_latest_stemcells ||= begin
|
106
|
+
stemcells = @director.list_stemcells.inject({}) do |hash, stemcell|
|
107
|
+
unless stemcell.is_a?(Hash) && stemcell['name'] && stemcell['version']
|
108
|
+
err('Invalid director stemcell list format')
|
109
|
+
end
|
110
|
+
hash[stemcell['name']] ||= []
|
111
|
+
hash[stemcell['name']] << stemcell['version']
|
112
|
+
hash
|
113
|
+
end
|
114
|
+
|
115
|
+
stemcells.inject({}) do |hash, (name, versions)|
|
116
|
+
hash[name] = Bosh::Common::Version::StemcellVersionList.parse(versions).latest.to_s
|
117
|
+
hash
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# @param [Hash] manifest Deployment manifest (will be modified)
|
123
|
+
# @return [void]
|
124
|
+
def resolve_release_aliases
|
125
|
+
releases = @hash['releases'] || [@hash['release']]
|
126
|
+
|
127
|
+
releases.each do |release|
|
128
|
+
if release['version'] == 'latest'
|
129
|
+
latest_release_version = latest_release_versions[release['name']]
|
130
|
+
unless latest_release_version
|
131
|
+
err("Release '#{release['name']}' not found on director. Unable to resolve 'latest' alias in manifest.")
|
132
|
+
end
|
133
|
+
release['version'] = latest_release_version
|
134
|
+
end
|
135
|
+
|
136
|
+
if release['version'].to_i.to_s == release['version']
|
137
|
+
release['version'] = release['version'].to_i
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def latest_release_versions
|
143
|
+
@_latest_release_versions ||= begin
|
144
|
+
@director.list_releases.inject({}) do |hash, release|
|
145
|
+
name = release['name']
|
146
|
+
versions = release['versions'] || release['release_versions'].map { |release_version| release_version['version'] }
|
147
|
+
parsed_versions = versions.map do |version|
|
148
|
+
{
|
149
|
+
original: version,
|
150
|
+
parsed: Bosh::Common::Version::ReleaseVersion.parse(version)
|
151
|
+
}
|
152
|
+
end
|
153
|
+
latest_version = parsed_versions.sort_by { |v| v[:parsed] }.last[:original]
|
154
|
+
hash[name] = latest_version.to_s
|
155
|
+
hash
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
MANIFEST_TARGET_UPGRADE_NOTICE =
|
161
|
+
<<-EOS.gsub(/^\s*/, '').gsub(/\n$/, '')
|
162
|
+
Please upgrade your deployment manifest to use director UUID instead
|
163
|
+
of target. Just replace 'target' key with 'director_uuid' key in your
|
164
|
+
manifest. You can get your director UUID by targeting your director
|
165
|
+
with 'bosh target' and running 'bosh status' command afterwards.
|
166
|
+
EOS
|
167
|
+
|
168
|
+
def report_manifest_warnings
|
169
|
+
ManifestWarnings.new(@hash).report
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
data/lib/cli/version.rb
CHANGED
data/lib/cli/vm_state.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
module Bosh::Cli
|
2
2
|
class VmState
|
3
|
-
def initialize(command, force)
|
3
|
+
def initialize(command, manifest, force)
|
4
4
|
@command = command
|
5
|
+
@manifest = manifest
|
5
6
|
@force = force
|
6
7
|
end
|
7
8
|
|
8
9
|
def change(job, index, new_state, operation_desc)
|
9
10
|
command.say("You are about to #{operation_desc.make_green}")
|
10
|
-
manifest = command.prepare_deployment_manifest
|
11
|
-
manifest_yaml = Psych.dump(manifest)
|
12
11
|
|
13
12
|
if command.interactive?
|
14
|
-
check_if_manifest_changed(manifest)
|
13
|
+
check_if_manifest_changed(@manifest.hash)
|
15
14
|
|
16
15
|
unless command.confirmed?("#{operation_desc.capitalize}?")
|
17
16
|
command.cancel_deployment
|
@@ -20,7 +19,7 @@ module Bosh::Cli
|
|
20
19
|
|
21
20
|
command.nl
|
22
21
|
command.say("Performing `#{operation_desc}'...")
|
23
|
-
command.director.change_job_state(manifest
|
22
|
+
command.director.change_job_state(@manifest.name, @manifest.yaml, job, index, new_state)
|
24
23
|
end
|
25
24
|
|
26
25
|
private
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bosh_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3003.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- VMware
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bosh_common
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.3003.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.3003.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bosh-template
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.3003.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.3003.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: cf-uaa-lib
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +128,14 @@ dependencies:
|
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 1.
|
131
|
+
version: 1.3003.0
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 1.
|
138
|
+
version: 1.3003.0
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: net-ssh
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -306,7 +306,7 @@ dependencies:
|
|
306
306
|
version: '0'
|
307
307
|
description: |-
|
308
308
|
BOSH CLI
|
309
|
-
|
309
|
+
44f0b8
|
310
310
|
email: support@cloudfoundry.com
|
311
311
|
executables:
|
312
312
|
- bosh
|
@@ -395,6 +395,7 @@ files:
|
|
395
395
|
- lib/cli/job_state.rb
|
396
396
|
- lib/cli/line_wrap.rb
|
397
397
|
- lib/cli/logs_downloader.rb
|
398
|
+
- lib/cli/manifest.rb
|
398
399
|
- lib/cli/manifest_warnings.rb
|
399
400
|
- lib/cli/name_version_pair.rb
|
400
401
|
- lib/cli/non_interactive_progress_renderer.rb
|