bosh_cli 1.0.3 → 1.5.0.pre.1113
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.
- data/bin/bosh +0 -9
- data/lib/cli.rb +69 -64
- data/lib/cli/backup_destination_path.rb +33 -0
- data/lib/cli/base_command.rb +57 -56
- data/lib/cli/blob_manager.rb +12 -12
- data/lib/cli/changeset_helper.rb +6 -7
- data/lib/cli/client/director.rb +724 -0
- data/lib/cli/command_handler.rb +6 -7
- data/lib/cli/commands/backup.rb +39 -0
- data/lib/cli/commands/biff.rb +42 -21
- data/lib/cli/commands/blob_management.rb +1 -1
- data/lib/cli/commands/cloudcheck.rb +11 -13
- data/lib/cli/commands/deployment.rb +53 -37
- data/lib/cli/commands/help.rb +3 -2
- data/lib/cli/commands/job_management.rb +67 -103
- data/lib/cli/commands/job_rename.rb +6 -8
- data/lib/cli/commands/log_management.rb +78 -55
- data/lib/cli/commands/maintenance.rb +36 -30
- data/lib/cli/commands/misc.rb +72 -51
- data/lib/cli/commands/package.rb +2 -2
- data/lib/cli/commands/property_management.rb +10 -12
- data/lib/cli/commands/release.rb +236 -133
- data/lib/cli/commands/snapshot.rb +93 -0
- data/lib/cli/commands/ssh.rb +216 -213
- data/lib/cli/commands/stemcell.rb +46 -34
- data/lib/cli/commands/task.rb +2 -2
- data/lib/cli/commands/user.rb +27 -3
- data/lib/cli/commands/vm.rb +28 -0
- data/lib/cli/commands/vms.rb +81 -23
- data/lib/cli/config.rb +6 -2
- data/lib/cli/core_ext.rb +31 -30
- data/lib/cli/deployment_helper.rb +134 -159
- data/lib/cli/deployment_manifest.rb +66 -0
- data/lib/cli/deployment_manifest_compiler.rb +0 -3
- data/lib/cli/event_log_renderer.rb +10 -10
- data/lib/cli/file_with_progress_bar.rb +52 -0
- data/lib/cli/job_builder.rb +1 -1
- data/lib/cli/job_command_args.rb +23 -0
- data/lib/cli/job_property_collection.rb +4 -7
- data/lib/cli/job_property_validator.rb +22 -12
- data/lib/cli/job_state.rb +54 -0
- data/lib/cli/line_wrap.rb +54 -0
- data/lib/cli/packaging_helper.rb +10 -10
- data/lib/cli/release.rb +18 -15
- data/lib/cli/release_builder.rb +9 -4
- data/lib/cli/release_compiler.rb +9 -9
- data/lib/cli/release_tarball.rb +3 -6
- data/lib/cli/resurrection.rb +31 -0
- data/lib/cli/runner.rb +56 -30
- data/lib/cli/stemcell.rb +25 -10
- data/lib/cli/task_log_renderer.rb +1 -1
- data/lib/cli/task_tracker.rb +10 -9
- data/lib/cli/validation.rb +3 -1
- data/lib/cli/version.rb +1 -1
- data/lib/cli/version_calc.rb +5 -18
- data/lib/cli/versions_index.rb +1 -1
- data/lib/cli/vm_state.rb +43 -0
- data/lib/cli/yaml_helper.rb +26 -35
- metadata +75 -208
- data/Rakefile +0 -56
- data/lib/cli/director.rb +0 -628
- data/spec/assets/biff/bad_gateway_config.yml +0 -28
- data/spec/assets/biff/good_simple_config.yml +0 -63
- data/spec/assets/biff/good_simple_golden_config.yml +0 -63
- data/spec/assets/biff/good_simple_template.erb +0 -69
- data/spec/assets/biff/ip_out_of_range.yml +0 -63
- data/spec/assets/biff/multiple_subnets_config.yml +0 -40
- data/spec/assets/biff/network_only_template.erb +0 -34
- data/spec/assets/biff/no_cc_config.yml +0 -27
- data/spec/assets/biff/no_range_config.yml +0 -27
- data/spec/assets/biff/no_subnet_config.yml +0 -16
- data/spec/assets/biff/ok_network_config.yml +0 -30
- data/spec/assets/biff/properties_template.erb +0 -6
- data/spec/assets/config/atmos/config/final.yml +0 -6
- data/spec/assets/config/atmos/config/private.yml +0 -4
- data/spec/assets/config/bad-providers/config/final.yml +0 -5
- data/spec/assets/config/bad-providers/config/private.yml +0 -4
- data/spec/assets/config/deprecation/config/final.yml +0 -5
- data/spec/assets/config/deprecation/config/private.yml +0 -2
- data/spec/assets/config/local/config/final.yml +0 -5
- data/spec/assets/config/local/config/private.yml +0 -1
- data/spec/assets/config/s3/config/final.yml +0 -5
- data/spec/assets/config/s3/config/private.yml +0 -5
- data/spec/assets/config/swift-hp/config/final.yml +0 -6
- data/spec/assets/config/swift-hp/config/private.yml +0 -7
- data/spec/assets/config/swift-rackspace/config/final.yml +0 -6
- data/spec/assets/config/swift-rackspace/config/private.yml +0 -6
- data/spec/assets/deployment.MF +0 -0
- data/spec/assets/plugins/bosh/cli/commands/echo.rb +0 -43
- data/spec/assets/plugins/bosh/cli/commands/ruby.rb +0 -24
- data/spec/assets/release/jobs/cacher.tgz +0 -0
- data/spec/assets/release/jobs/cacher/config/file1.conf +0 -0
- data/spec/assets/release/jobs/cacher/config/file2.conf +0 -0
- data/spec/assets/release/jobs/cacher/job.MF +0 -6
- data/spec/assets/release/jobs/cacher/monit +0 -1
- data/spec/assets/release/jobs/cleaner.tgz +0 -0
- data/spec/assets/release/jobs/cleaner/job.MF +0 -4
- data/spec/assets/release/jobs/cleaner/monit +0 -1
- data/spec/assets/release/jobs/sweeper.tgz +0 -0
- data/spec/assets/release/jobs/sweeper/config/test.conf +0 -1
- data/spec/assets/release/jobs/sweeper/job.MF +0 -5
- data/spec/assets/release/jobs/sweeper/monit +0 -1
- data/spec/assets/release/packages/mutator.tar.gz +0 -0
- data/spec/assets/release/packages/stuff.tgz +0 -0
- data/spec/assets/release/release.MF +0 -17
- data/spec/assets/release_invalid_checksum.tgz +0 -0
- data/spec/assets/release_invalid_jobs.tgz +0 -0
- data/spec/assets/release_no_name.tgz +0 -0
- data/spec/assets/release_no_version.tgz +0 -0
- data/spec/assets/stemcell/image +0 -1
- data/spec/assets/stemcell/stemcell.MF +0 -6
- data/spec/assets/stemcell_invalid_mf.tgz +0 -0
- data/spec/assets/stemcell_no_image.tgz +0 -0
- data/spec/assets/valid_release.tgz +0 -0
- data/spec/assets/valid_stemcell.tgz +0 -0
- data/spec/spec_helper.rb +0 -28
- data/spec/unit/base_command_spec.rb +0 -87
- data/spec/unit/biff_spec.rb +0 -172
- data/spec/unit/blob_manager_spec.rb +0 -288
- data/spec/unit/cache_spec.rb +0 -36
- data/spec/unit/cli_commands_spec.rb +0 -356
- data/spec/unit/config_spec.rb +0 -125
- data/spec/unit/core_ext_spec.rb +0 -81
- data/spec/unit/dependency_helper_spec.rb +0 -52
- data/spec/unit/deployment_manifest_compiler_spec.rb +0 -63
- data/spec/unit/deployment_manifest_spec.rb +0 -153
- data/spec/unit/director_spec.rb +0 -471
- data/spec/unit/director_task_spec.rb +0 -48
- data/spec/unit/event_log_renderer_spec.rb +0 -171
- data/spec/unit/hash_changeset_spec.rb +0 -73
- data/spec/unit/job_builder_spec.rb +0 -455
- data/spec/unit/job_property_collection_spec.rb +0 -111
- data/spec/unit/job_property_validator_spec.rb +0 -7
- data/spec/unit/job_rename_spec.rb +0 -200
- data/spec/unit/package_builder_spec.rb +0 -593
- data/spec/unit/release_builder_spec.rb +0 -120
- data/spec/unit/release_spec.rb +0 -173
- data/spec/unit/release_tarball_spec.rb +0 -29
- data/spec/unit/runner_spec.rb +0 -7
- data/spec/unit/ssh_spec.rb +0 -84
- data/spec/unit/stemcell_spec.rb +0 -17
- data/spec/unit/task_tracker_spec.rb +0 -131
- data/spec/unit/version_calc_spec.rb +0 -27
- data/spec/unit/versions_index_spec.rb +0 -144
|
@@ -9,9 +9,7 @@ module Bosh::Cli::Command
|
|
|
9
9
|
|
|
10
10
|
# The URL of the public stemcell index.
|
|
11
11
|
PUBLIC_STEMCELL_INDEX_URL =
|
|
12
|
-
"https://blob.cfblob.com/
|
|
13
|
-
"1e121204e4e86ee151bc04f6a19ce46b22?uid=bb6a0c89ef4048a8a0f814e2538" +
|
|
14
|
-
"5d1c5/user1&expires=1893484800&signature=NJuAr9c8eOid7dKFmOEN7bmzAlI="
|
|
12
|
+
"https://s3.amazonaws.com/blob.cfblob.com/stemcells/public_stemcells_index.yml"
|
|
15
13
|
|
|
16
14
|
DEFAULT_PUB_STEMCELL_TAG = "stable"
|
|
17
15
|
ALL_STEMCELLS_TAG = "all"
|
|
@@ -27,9 +25,9 @@ module Bosh::Cli::Command
|
|
|
27
25
|
nl
|
|
28
26
|
|
|
29
27
|
if stemcell.valid?
|
|
30
|
-
say("`#{tarball_path}' is a valid stemcell".
|
|
28
|
+
say("`#{tarball_path}' is a valid stemcell".make_green)
|
|
31
29
|
else
|
|
32
|
-
say("Validation errors:".
|
|
30
|
+
say("Validation errors:".make_red)
|
|
33
31
|
stemcell.errors.each do |error|
|
|
34
32
|
say("- %s" % [error])
|
|
35
33
|
end
|
|
@@ -39,38 +37,50 @@ module Bosh::Cli::Command
|
|
|
39
37
|
|
|
40
38
|
# bosh upload stemcell
|
|
41
39
|
usage "upload stemcell"
|
|
42
|
-
desc "Upload stemcell"
|
|
43
|
-
def upload(
|
|
40
|
+
desc "Upload stemcell (stemcell_location can be a local file or a remote URI)"
|
|
41
|
+
def upload(stemcell_location)
|
|
44
42
|
auth_required
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
stemcell_type = stemcell_location =~ /^#{URI::regexp}$/ ? "remote" : "local"
|
|
45
|
+
if stemcell_type == "local"
|
|
46
|
+
stemcell = Bosh::Cli::Stemcell.new(stemcell_location, cache)
|
|
47
|
+
|
|
48
|
+
nl
|
|
49
|
+
say("Verifying stemcell...")
|
|
50
|
+
stemcell.validate
|
|
51
|
+
nl
|
|
52
|
+
|
|
53
|
+
unless stemcell.valid?
|
|
54
|
+
err("Stemcell is invalid, please fix, verify and upload again")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
say("Checking if stemcell already exists...")
|
|
58
|
+
name = stemcell.manifest["name"]
|
|
59
|
+
version = stemcell.manifest["version"]
|
|
60
|
+
|
|
61
|
+
if exists?(name, version)
|
|
62
|
+
err("Stemcell `#{name}/#{version}' already exists, " +
|
|
63
|
+
"increment the version if it has changed")
|
|
64
|
+
else
|
|
65
|
+
say("No")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
stemcell_location = stemcell.stemcell_file
|
|
52
69
|
|
|
53
|
-
|
|
54
|
-
|
|
70
|
+
nl
|
|
71
|
+
say("Uploading stemcell...")
|
|
72
|
+
nl
|
|
73
|
+
else
|
|
74
|
+
nl
|
|
75
|
+
say("Using remote stemcell `#{stemcell_location}'")
|
|
55
76
|
end
|
|
56
77
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
version = stemcell.manifest["version"]
|
|
60
|
-
|
|
61
|
-
if exists?(name, version)
|
|
62
|
-
err("Stemcell `#{name}/#{version}' already exists, " +
|
|
63
|
-
"increment the version if it has changed")
|
|
78
|
+
if stemcell_type == "local"
|
|
79
|
+
status, task_id = director.upload_stemcell(stemcell_location)
|
|
64
80
|
else
|
|
65
|
-
|
|
81
|
+
status, task_id = director.upload_remote_stemcell(stemcell_location)
|
|
66
82
|
end
|
|
67
83
|
|
|
68
|
-
nl
|
|
69
|
-
say("Uploading stemcell...")
|
|
70
|
-
nl
|
|
71
|
-
|
|
72
|
-
status, task_id = director.upload_stemcell(stemcell.stemcell_file)
|
|
73
|
-
|
|
74
84
|
task_report(status, task_id, "Stemcell uploaded and created")
|
|
75
85
|
end
|
|
76
86
|
|
|
@@ -170,15 +180,17 @@ module Bosh::Cli::Command
|
|
|
170
180
|
err("The downloaded file sha1 `#{file_sha1}' does not match the " +
|
|
171
181
|
"expected sha1 `#{sha1}'")
|
|
172
182
|
else
|
|
173
|
-
say("Download complete".
|
|
183
|
+
say("Download complete".make_green)
|
|
174
184
|
end
|
|
175
185
|
end
|
|
176
186
|
|
|
177
187
|
# bosh delete stemcell
|
|
178
188
|
usage "delete stemcell"
|
|
179
189
|
desc "Delete stemcell"
|
|
190
|
+
option "--force", "ignore errors while deleting the stemcell"
|
|
180
191
|
def delete(name, version)
|
|
181
192
|
auth_required
|
|
193
|
+
force = !!options[:force]
|
|
182
194
|
|
|
183
195
|
say("Checking if stemcell exists...")
|
|
184
196
|
|
|
@@ -186,14 +198,14 @@ module Bosh::Cli::Command
|
|
|
186
198
|
err("Stemcell `#{name}/#{version}' does not exist")
|
|
187
199
|
end
|
|
188
200
|
|
|
189
|
-
say("You are going to delete stemcell `#{name}/#{version}'".
|
|
201
|
+
say("You are going to delete stemcell `#{name}/#{version}'".make_red)
|
|
190
202
|
|
|
191
203
|
unless confirmed?
|
|
192
|
-
say("Canceled deleting stemcell".
|
|
204
|
+
say("Canceled deleting stemcell".make_green)
|
|
193
205
|
return
|
|
194
206
|
end
|
|
195
207
|
|
|
196
|
-
status, task_id = director.delete_stemcell(name, version)
|
|
208
|
+
status, task_id = director.delete_stemcell(name, version, :force => force)
|
|
197
209
|
|
|
198
210
|
task_report(status, task_id, "Deleted stemcell `#{name}/#{version}'")
|
|
199
211
|
end
|
|
@@ -232,7 +244,7 @@ module Bosh::Cli::Command
|
|
|
232
244
|
if status_code != HTTP::Status::OK
|
|
233
245
|
err("Received HTTP #{status_code} from #{PUBLIC_STEMCELL_INDEX_URL}.")
|
|
234
246
|
end
|
|
235
|
-
|
|
247
|
+
Psych.load(response.body)
|
|
236
248
|
end
|
|
237
249
|
|
|
238
250
|
end
|
data/lib/cli/commands/task.rb
CHANGED
|
@@ -118,9 +118,9 @@ module Bosh::Cli::Command
|
|
|
118
118
|
def show_tasks_table(tasks)
|
|
119
119
|
return if tasks.empty?
|
|
120
120
|
tasks_table = table do |t|
|
|
121
|
-
t.headings = "#", "State", "Timestamp", "Description", "Result"
|
|
121
|
+
t.headings = "#", "State", "Timestamp", "User", "Description", "Result"
|
|
122
122
|
tasks.map do |task|
|
|
123
|
-
t << [task["id"], task["state"], Time.at(task["timestamp"]).utc,
|
|
123
|
+
t << [task["id"], task["state"], Time.at(task["timestamp"]).utc, task["user"],
|
|
124
124
|
task["description"].to_s, task["result"].to_s.truncate(80)]
|
|
125
125
|
end
|
|
126
126
|
end
|
data/lib/cli/commands/user.rb
CHANGED
|
@@ -10,9 +10,12 @@ module Bosh::Cli::Command
|
|
|
10
10
|
auth_required
|
|
11
11
|
|
|
12
12
|
if interactive?
|
|
13
|
-
username = ask("Enter username: ") if username.blank?
|
|
13
|
+
username = ask("Enter new username: ") if username.blank?
|
|
14
14
|
if password.blank?
|
|
15
|
-
password = ask("Enter password: ") { |q| q.echo = "*" }
|
|
15
|
+
password = ask("Enter new password: ") { |q| q.echo = "*" }
|
|
16
|
+
password_confirmation = ask("Verify new password: ") { |q| q.echo = "*" }
|
|
17
|
+
|
|
18
|
+
err("Passwords do not match") if password != password_confirmation
|
|
16
19
|
end
|
|
17
20
|
end
|
|
18
21
|
|
|
@@ -21,11 +24,32 @@ module Bosh::Cli::Command
|
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
if director.create_user(username, password)
|
|
24
|
-
say("User `#{username}' has been created".
|
|
27
|
+
say("User `#{username}' has been created".make_green)
|
|
25
28
|
else
|
|
26
29
|
err("Error creating user")
|
|
27
30
|
end
|
|
28
31
|
end
|
|
29
32
|
|
|
33
|
+
usage "delete user"
|
|
34
|
+
desc "Deletes the user from the director"
|
|
35
|
+
def delete(username = nil)
|
|
36
|
+
auth_required
|
|
37
|
+
|
|
38
|
+
if interactive?
|
|
39
|
+
username ||= ask("Username to delete: ")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if username.blank?
|
|
43
|
+
err("Please provide a username to delete")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if confirmed?("Are you sure you would like to delete the user `#{username}'?")
|
|
47
|
+
if director.delete_user(username)
|
|
48
|
+
say("User `#{username}' has been deleted".make_green)
|
|
49
|
+
else
|
|
50
|
+
err("Unable to delete user")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
30
54
|
end
|
|
31
55
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'cli/job_command_args'
|
|
2
|
+
require 'cli/resurrection'
|
|
3
|
+
|
|
4
|
+
module Bosh::Cli
|
|
5
|
+
module Command
|
|
6
|
+
class Vm < Base
|
|
7
|
+
usage 'vm resurrection'
|
|
8
|
+
desc 'Enable/Disable resurrection for a given vm'
|
|
9
|
+
def resurrection_state(job=nil, index=nil, new_state)
|
|
10
|
+
if job.nil? && index.nil?
|
|
11
|
+
resurrection = Resurrection.new(new_state)
|
|
12
|
+
|
|
13
|
+
director.change_vm_resurrection_for_all(resurrection.paused?)
|
|
14
|
+
else
|
|
15
|
+
job_args = JobCommandArgs.new([job, index])
|
|
16
|
+
job, index, _ = job_args.to_a
|
|
17
|
+
resurrection = Resurrection.new(new_state)
|
|
18
|
+
|
|
19
|
+
job_must_exist_in_deployment(job)
|
|
20
|
+
index = valid_index_for(job, index, integer_index: true)
|
|
21
|
+
|
|
22
|
+
manifest = prepare_deployment_manifest
|
|
23
|
+
director.change_vm_resurrection(manifest['name'], job, index, resurrection.paused?)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/cli/commands/vms.rb
CHANGED
|
@@ -2,45 +2,103 @@
|
|
|
2
2
|
|
|
3
3
|
module Bosh::Cli::Command
|
|
4
4
|
class Vms < Base
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
option
|
|
5
|
+
usage 'vms'
|
|
6
|
+
desc 'List all VMs in a deployment'
|
|
7
|
+
option '--details', 'Return detailed VM information'
|
|
8
|
+
option '--dns', 'Return VM DNS A records'
|
|
9
|
+
option '--vitals', 'Return VM vitals information'
|
|
10
10
|
def list(deployment_name = nil)
|
|
11
11
|
auth_required
|
|
12
12
|
no_track_unsupported
|
|
13
|
-
show_full_stats = options[:full]
|
|
14
13
|
|
|
15
14
|
if deployment_name.nil?
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
deps = director.list_deployments
|
|
16
|
+
err('No deployments') if deps.empty?
|
|
17
|
+
deps.each { |dep| show_deployment(dep['name'], options) }
|
|
18
|
+
else
|
|
19
|
+
show_deployment deployment_name, options
|
|
19
20
|
end
|
|
21
|
+
end
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
def show_deployment(name, options={})
|
|
24
|
+
say("Deployment `#{name.make_green}'")
|
|
25
|
+
|
|
26
|
+
vms = director.fetch_vm_state(name)
|
|
27
|
+
|
|
28
|
+
if vms.empty?
|
|
29
|
+
nl
|
|
30
|
+
say('No VMs')
|
|
31
|
+
nl
|
|
32
|
+
return
|
|
33
|
+
end
|
|
24
34
|
|
|
25
35
|
sorted = vms.sort do |a, b|
|
|
26
|
-
s = a[
|
|
27
|
-
s = a[
|
|
28
|
-
s = a[
|
|
36
|
+
s = a['job_name'].to_s <=> b['job_name'].to_s
|
|
37
|
+
s = a['index'].to_i <=> b['index'].to_i if s == 0
|
|
38
|
+
s = a['resource_pool'].to_s <=> b['resource_pool'].to_s if s == 0
|
|
29
39
|
s
|
|
30
40
|
end
|
|
31
41
|
|
|
32
42
|
vms_table = table do |t|
|
|
33
|
-
headings = [
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
headings = ['Job/index', 'State', 'Resource Pool', 'IPs']
|
|
44
|
+
if options[:details]
|
|
45
|
+
headings += ['CID', 'Agent ID', 'Resurrection']
|
|
46
|
+
end
|
|
47
|
+
if options[:dns]
|
|
48
|
+
headings += ['DNS A records']
|
|
49
|
+
end
|
|
50
|
+
if options[:vitals]
|
|
51
|
+
headings += [{:value => "Load\n(avg01, avg05, avg15)", :alignment => :center}]
|
|
52
|
+
headings += ["CPU\nUser", "CPU\nSys", "CPU\nWait"]
|
|
53
|
+
headings += ['Memory Usage', 'Swap Usage']
|
|
54
|
+
headings += ["System\nDisk Usage", "Ephemeral\nDisk Usage", "Persistent\nDisk Usage"]
|
|
55
|
+
end
|
|
36
56
|
t.headings = headings
|
|
37
57
|
|
|
38
58
|
sorted.each do |vm|
|
|
39
|
-
job = "#{vm[
|
|
40
|
-
ips = Array(vm[
|
|
59
|
+
job = "#{vm['job_name'] || 'unknown'}/#{vm['index'] || 'unknown'}"
|
|
60
|
+
ips = Array(vm['ips']).join(', ')
|
|
61
|
+
dns_records = Array(vm['dns']).join("\n")
|
|
62
|
+
vitals = vm['vitals']
|
|
63
|
+
|
|
64
|
+
row = [job, vm['job_state'], vm['resource_pool'], ips]
|
|
65
|
+
|
|
66
|
+
if options[:details]
|
|
67
|
+
row += [vm['vm_cid'], vm['agent_id'], vm['resurrection_paused'] ? 'paused' : 'active']
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if options[:dns]
|
|
71
|
+
row += [dns_records.empty? ? 'n/a' : dns_records]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
if options[:vitals]
|
|
75
|
+
if vitals
|
|
76
|
+
cpu = vitals['cpu']
|
|
77
|
+
mem = vitals['mem']
|
|
78
|
+
swap = vitals['swap']
|
|
79
|
+
disk = vitals['disk']
|
|
41
80
|
|
|
42
|
-
|
|
43
|
-
|
|
81
|
+
row << vitals['load'].map { |l| "#{l}%" }.join(', ')
|
|
82
|
+
row << "#{cpu['user']}%"
|
|
83
|
+
row << "#{cpu['sys']}%"
|
|
84
|
+
row << "#{cpu['wait']}%"
|
|
85
|
+
row << "#{mem['percent']}% (#{pretty_size(mem['kb'].to_i * 1024)})"
|
|
86
|
+
row << "#{swap['percent']}% (#{pretty_size(swap['kb'].to_i * 1024)})"
|
|
87
|
+
row << "#{disk['system']['percent']}%"
|
|
88
|
+
if disk['ephemeral'].nil?
|
|
89
|
+
row << 'n/a'
|
|
90
|
+
else
|
|
91
|
+
row << "#{disk['ephemeral']['percent']}%"
|
|
92
|
+
end
|
|
93
|
+
if disk['persistent'].nil?
|
|
94
|
+
row << 'n/a'
|
|
95
|
+
else
|
|
96
|
+
row << "#{disk['persistent']['percent']}%"
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
9.times { row << 'n/a' }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
44
102
|
|
|
45
103
|
t << row
|
|
46
104
|
end
|
|
@@ -49,7 +107,7 @@ module Bosh::Cli::Command
|
|
|
49
107
|
nl
|
|
50
108
|
say(vms_table)
|
|
51
109
|
nl
|
|
52
|
-
say(
|
|
110
|
+
say('VMs total: %d' % vms.size)
|
|
53
111
|
end
|
|
54
112
|
|
|
55
113
|
end
|
data/lib/cli/config.rb
CHANGED
|
@@ -19,6 +19,9 @@ module Bosh::Cli
|
|
|
19
19
|
|
|
20
20
|
# @return [Bosh::Cli::Cache] CLI cache (to save task logs etc.)
|
|
21
21
|
attr_accessor :cache
|
|
22
|
+
|
|
23
|
+
# @return [Integer] CLI polling interval
|
|
24
|
+
attr_accessor :poll_interval
|
|
22
25
|
end
|
|
23
26
|
|
|
24
27
|
@commands = {}
|
|
@@ -42,7 +45,7 @@ module Bosh::Cli
|
|
|
42
45
|
@work_dir = work_dir
|
|
43
46
|
|
|
44
47
|
unless File.exists?(@filename)
|
|
45
|
-
File.open(@filename, "w") { |f|
|
|
48
|
+
File.open(@filename, "w") { |f| Psych.dump({}, f) }
|
|
46
49
|
File.chmod(0600, @filename)
|
|
47
50
|
end
|
|
48
51
|
|
|
@@ -188,12 +191,13 @@ module Bosh::Cli
|
|
|
188
191
|
|
|
189
192
|
def save
|
|
190
193
|
File.open(@filename, "w") do |f|
|
|
191
|
-
|
|
194
|
+
Psych.dump(@config_file, f)
|
|
192
195
|
end
|
|
193
196
|
|
|
194
197
|
rescue SystemCallError => e
|
|
195
198
|
raise ConfigError, e.message
|
|
196
199
|
end
|
|
197
200
|
|
|
201
|
+
attr_reader :filename
|
|
198
202
|
end
|
|
199
203
|
end
|
data/lib/cli/core_ext.rb
CHANGED
|
@@ -66,30 +66,42 @@ module BoshExtensions
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def load_yaml_file(path, expected_type = Hash)
|
|
69
|
-
err("Cannot find file `#{path}'") unless File.
|
|
70
|
-
yaml = YAML.load_file(path)
|
|
69
|
+
err("Cannot find file `#{path}'".make_red) unless File.exist?(path)
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
begin
|
|
72
|
+
yaml_str = ERB.new(File.read(path)).result
|
|
73
|
+
rescue SystemCallError => e
|
|
74
|
+
err("Cannot load YAML file at `#{path}': #{e}".make_red)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
begin
|
|
78
|
+
Bosh::Cli::YamlHelper.check_duplicate_keys(yaml_str)
|
|
79
|
+
rescue => e
|
|
80
|
+
err("Incorrect YAML structure in `#{path}': #{e}".make_red)
|
|
74
81
|
end
|
|
75
82
|
|
|
76
|
-
|
|
83
|
+
yaml = Psych::load(yaml_str)
|
|
84
|
+
if expected_type && !yaml.is_a?(expected_type)
|
|
85
|
+
err("Incorrect YAML structure in `#{path}': expected #{expected_type} at the root".make_red)
|
|
86
|
+
end
|
|
77
87
|
|
|
78
88
|
yaml
|
|
79
|
-
rescue SystemCallError => e
|
|
80
|
-
err("Cannot load YAML file at `#{path}': #{e}")
|
|
81
89
|
end
|
|
82
90
|
|
|
83
|
-
def
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
def write_yaml(manifest, path)
|
|
92
|
+
File.open(path, "w+") do |f|
|
|
93
|
+
f.write(manifest.to_yaml)
|
|
94
|
+
end
|
|
87
95
|
end
|
|
88
96
|
|
|
89
97
|
# @return [Fixnum]
|
|
90
98
|
def terminal_width
|
|
91
99
|
STDIN.tty? ? [HighLine::SystemExtensions.terminal_size[0], 120].min : 80
|
|
92
100
|
end
|
|
101
|
+
|
|
102
|
+
def warning(message)
|
|
103
|
+
warn("[WARNING] #{message}".make_yellow)
|
|
104
|
+
end
|
|
93
105
|
end
|
|
94
106
|
|
|
95
107
|
module BoshStringExtensions
|
|
@@ -100,19 +112,19 @@ module BoshStringExtensions
|
|
|
100
112
|
:yellow => "\e[0m\e[33m"
|
|
101
113
|
}
|
|
102
114
|
|
|
103
|
-
def
|
|
104
|
-
|
|
115
|
+
def make_red
|
|
116
|
+
make_color(:red)
|
|
105
117
|
end
|
|
106
118
|
|
|
107
|
-
def
|
|
108
|
-
|
|
119
|
+
def make_green
|
|
120
|
+
make_color(:green)
|
|
109
121
|
end
|
|
110
122
|
|
|
111
|
-
def
|
|
112
|
-
|
|
123
|
+
def make_yellow
|
|
124
|
+
make_color(:yellow)
|
|
113
125
|
end
|
|
114
126
|
|
|
115
|
-
def
|
|
127
|
+
def make_color(color_code)
|
|
116
128
|
if Bosh::Cli::Config.output &&
|
|
117
129
|
Bosh::Cli::Config.output.tty? &&
|
|
118
130
|
Bosh::Cli::Config.colorize &&
|
|
@@ -144,18 +156,7 @@ module BoshStringExtensions
|
|
|
144
156
|
end
|
|
145
157
|
|
|
146
158
|
def columnize(width = 80, left_margin = 0)
|
|
147
|
-
|
|
148
|
-
buf = ""
|
|
149
|
-
self.split(/\s+/).each do |word|
|
|
150
|
-
if buf.size + word.size > width
|
|
151
|
-
result << buf << "\n" << " " * left_margin
|
|
152
|
-
buf = word + " "
|
|
153
|
-
else
|
|
154
|
-
buf << word << " "
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
end
|
|
158
|
-
result + buf
|
|
159
|
+
Bosh::Cli::LineWrap.new(width, left_margin).wrap(self)
|
|
159
160
|
end
|
|
160
161
|
|
|
161
162
|
def indent(margin = 2)
|