bosh_cli 0.16
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/README +4 -0
- data/Rakefile +55 -0
- data/bin/bosh +17 -0
- data/lib/cli.rb +76 -0
- data/lib/cli/cache.rb +44 -0
- data/lib/cli/changeset_helper.rb +142 -0
- data/lib/cli/command_definition.rb +52 -0
- data/lib/cli/commands/base.rb +245 -0
- data/lib/cli/commands/biff.rb +300 -0
- data/lib/cli/commands/blob.rb +125 -0
- data/lib/cli/commands/cloudcheck.rb +169 -0
- data/lib/cli/commands/deployment.rb +147 -0
- data/lib/cli/commands/job.rb +42 -0
- data/lib/cli/commands/job_management.rb +117 -0
- data/lib/cli/commands/log_management.rb +81 -0
- data/lib/cli/commands/maintenance.rb +131 -0
- data/lib/cli/commands/misc.rb +240 -0
- data/lib/cli/commands/package.rb +112 -0
- data/lib/cli/commands/property_management.rb +125 -0
- data/lib/cli/commands/release.rb +469 -0
- data/lib/cli/commands/ssh.rb +271 -0
- data/lib/cli/commands/stemcell.rb +184 -0
- data/lib/cli/commands/task.rb +213 -0
- data/lib/cli/commands/user.rb +28 -0
- data/lib/cli/commands/vms.rb +53 -0
- data/lib/cli/config.rb +154 -0
- data/lib/cli/core_ext.rb +145 -0
- data/lib/cli/dependency_helper.rb +62 -0
- data/lib/cli/deployment_helper.rb +263 -0
- data/lib/cli/deployment_manifest_compiler.rb +28 -0
- data/lib/cli/director.rb +633 -0
- data/lib/cli/director_task.rb +64 -0
- data/lib/cli/errors.rb +48 -0
- data/lib/cli/event_log_renderer.rb +351 -0
- data/lib/cli/job_builder.rb +226 -0
- data/lib/cli/package_builder.rb +254 -0
- data/lib/cli/packaging_helper.rb +248 -0
- data/lib/cli/release.rb +176 -0
- data/lib/cli/release_builder.rb +215 -0
- data/lib/cli/release_compiler.rb +178 -0
- data/lib/cli/release_tarball.rb +272 -0
- data/lib/cli/runner.rb +771 -0
- data/lib/cli/stemcell.rb +83 -0
- data/lib/cli/task_log_renderer.rb +40 -0
- data/lib/cli/templates/help_message.erb +75 -0
- data/lib/cli/validation.rb +42 -0
- data/lib/cli/version.rb +7 -0
- data/lib/cli/version_calc.rb +48 -0
- data/lib/cli/versions_index.rb +126 -0
- data/lib/cli/yaml_helper.rb +62 -0
- data/spec/assets/biff/bad_gateway_config.yml +28 -0
- data/spec/assets/biff/good_simple_config.yml +63 -0
- data/spec/assets/biff/good_simple_golden_config.yml +63 -0
- data/spec/assets/biff/good_simple_template.erb +69 -0
- data/spec/assets/biff/multiple_subnets_config.yml +40 -0
- data/spec/assets/biff/network_only_template.erb +34 -0
- data/spec/assets/biff/no_cc_config.yml +27 -0
- data/spec/assets/biff/no_range_config.yml +27 -0
- data/spec/assets/biff/no_subnet_config.yml +16 -0
- data/spec/assets/biff/ok_network_config.yml +30 -0
- data/spec/assets/biff/properties_template.erb +6 -0
- data/spec/assets/deployment.MF +0 -0
- data/spec/assets/plugins/bosh/cli/commands/echo.rb +43 -0
- data/spec/assets/plugins/bosh/cli/commands/ruby.rb +24 -0
- 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 +6 -0
- data/spec/assets/release/jobs/cacher/monit +1 -0
- data/spec/assets/release/jobs/cleaner.tgz +0 -0
- data/spec/assets/release/jobs/cleaner/job.MF +4 -0
- data/spec/assets/release/jobs/cleaner/monit +1 -0
- data/spec/assets/release/jobs/sweeper.tgz +0 -0
- data/spec/assets/release/jobs/sweeper/config/test.conf +1 -0
- data/spec/assets/release/jobs/sweeper/job.MF +5 -0
- data/spec/assets/release/jobs/sweeper/monit +1 -0
- 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 +17 -0
- 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 +1 -0
- data/spec/assets/stemcell/stemcell.MF +6 -0
- 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 +25 -0
- data/spec/unit/base_command_spec.rb +66 -0
- data/spec/unit/biff_spec.rb +135 -0
- data/spec/unit/cache_spec.rb +36 -0
- data/spec/unit/cli_commands_spec.rb +481 -0
- data/spec/unit/config_spec.rb +139 -0
- data/spec/unit/core_ext_spec.rb +77 -0
- data/spec/unit/dependency_helper_spec.rb +52 -0
- data/spec/unit/deployment_manifest_compiler_spec.rb +63 -0
- data/spec/unit/director_spec.rb +511 -0
- data/spec/unit/director_task_spec.rb +48 -0
- data/spec/unit/event_log_renderer_spec.rb +171 -0
- data/spec/unit/hash_changeset_spec.rb +73 -0
- data/spec/unit/job_builder_spec.rb +454 -0
- data/spec/unit/package_builder_spec.rb +567 -0
- data/spec/unit/release_builder_spec.rb +65 -0
- data/spec/unit/release_spec.rb +66 -0
- data/spec/unit/release_tarball_spec.rb +33 -0
- data/spec/unit/runner_spec.rb +140 -0
- data/spec/unit/ssh_spec.rb +78 -0
- data/spec/unit/stemcell_spec.rb +17 -0
- data/spec/unit/version_calc_spec.rb +27 -0
- data/spec/unit/versions_index_spec.rb +132 -0
- metadata +338 -0
data/lib/cli/stemcell.rb
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Cli
|
|
4
|
+
class Stemcell
|
|
5
|
+
include Validation
|
|
6
|
+
|
|
7
|
+
attr_reader :stemcell_file, :manifest
|
|
8
|
+
|
|
9
|
+
def initialize(tarball_path, cache)
|
|
10
|
+
@stemcell_file = File.expand_path(tarball_path, Dir.pwd)
|
|
11
|
+
@cache = cache
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def perform_validation(options = {})
|
|
15
|
+
tmp_dir = Dir.mktmpdir
|
|
16
|
+
|
|
17
|
+
step("File exists and readable",
|
|
18
|
+
"Cannot find stemcell file #{@stemcell_file}", :fatal) do
|
|
19
|
+
File.exists?(@stemcell_file) && File.readable?(@stemcell_file)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
cache_key = "%s_%s" % [@stemcell_file, File.mtime(@stemcell_file)]
|
|
23
|
+
|
|
24
|
+
manifest_yaml = @cache.read(cache_key)
|
|
25
|
+
|
|
26
|
+
if manifest_yaml
|
|
27
|
+
say("Using cached manifest...")
|
|
28
|
+
else
|
|
29
|
+
say("Manifest not found in cache, verifying tarball...")
|
|
30
|
+
|
|
31
|
+
step("Extract tarball",
|
|
32
|
+
"Cannot extract tarball #{@stemcell_file}", :fatal) do
|
|
33
|
+
`tar -C #{tmp_dir} -xzf #{@stemcell_file} 2>&1`
|
|
34
|
+
$?.exitstatus == 0
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
manifest_file = File.expand_path("stemcell.MF", tmp_dir)
|
|
38
|
+
|
|
39
|
+
step("Manifest exists", "Cannot find stemcell manifest", :fatal) do
|
|
40
|
+
File.exists?(manifest_file)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
step("Stemcell image file",
|
|
44
|
+
"Stemcell image file is missing", :fatal) do
|
|
45
|
+
File.exists?(File.expand_path("image", tmp_dir))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
say("Writing manifest to cache...")
|
|
49
|
+
manifest_yaml = File.read(manifest_file)
|
|
50
|
+
@cache.write(cache_key, manifest_yaml)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
manifest = YAML.load(manifest_yaml)
|
|
54
|
+
|
|
55
|
+
step("Stemcell properties",
|
|
56
|
+
"Manifest should contain valid name, " +
|
|
57
|
+
"version and cloud properties") do
|
|
58
|
+
manifest.is_a?(Hash) && manifest.has_key?("name") &&
|
|
59
|
+
manifest.has_key?("version") &&
|
|
60
|
+
manifest.has_key?("cloud_properties") &&
|
|
61
|
+
manifest["name"].is_a?(String) &&
|
|
62
|
+
(manifest["version"].is_a?(String) ||
|
|
63
|
+
manifest["version"].kind_of?(Numeric)) &&
|
|
64
|
+
(manifest["cloud_properties"].nil? ||
|
|
65
|
+
manifest["cloud_properties"].is_a?(Hash))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
print_info(manifest)
|
|
69
|
+
@manifest = manifest
|
|
70
|
+
ensure
|
|
71
|
+
FileUtils.rm_rf(tmp_dir)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def print_info(manifest)
|
|
75
|
+
say("\nStemcell info")
|
|
76
|
+
say("-------------")
|
|
77
|
+
|
|
78
|
+
say("Name: %s" % [manifest["name"] || "missing".red])
|
|
79
|
+
say("Version: %s" % [manifest["version"] || "missing".red])
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Cli
|
|
4
|
+
class TaskLogRenderer
|
|
5
|
+
|
|
6
|
+
def self.create_for_log_type(log_type)
|
|
7
|
+
if log_type == "event"
|
|
8
|
+
EventLogRenderer.new
|
|
9
|
+
else
|
|
10
|
+
TaskLogRenderer.new
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_accessor :time_adjustment
|
|
15
|
+
attr_accessor :duration
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@out = Bosh::Cli::Config.output || $stdout
|
|
19
|
+
@out.sync = true
|
|
20
|
+
@lock = Mutex.new
|
|
21
|
+
@output = ""
|
|
22
|
+
@time_adjustment = 0
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_output(output)
|
|
26
|
+
@output = output
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def refresh
|
|
30
|
+
@out.print(@output)
|
|
31
|
+
@output = ""
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def finish(state)
|
|
35
|
+
refresh
|
|
36
|
+
@done = true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<%= basic_usage %>
|
|
2
|
+
Currently available bosh commands are:
|
|
3
|
+
|
|
4
|
+
Deployment
|
|
5
|
+
<%= command_usage(:deployment) %>
|
|
6
|
+
<%= command_usage(:delete_deployment) %>
|
|
7
|
+
<%= command_usage(:list_deployments) %>
|
|
8
|
+
<%= command_usage(:deploy) %>
|
|
9
|
+
<%= command_usage(:diff) %>
|
|
10
|
+
|
|
11
|
+
Release management
|
|
12
|
+
<%= command_usage(:create_release) %>
|
|
13
|
+
<%= command_usage(:delete_release) %>
|
|
14
|
+
<%= command_usage(:verify_release) %>
|
|
15
|
+
<%= command_usage(:upload_release) %>
|
|
16
|
+
<%= command_usage(:list_releases) %>
|
|
17
|
+
<%= command_usage(:reset_release) %>
|
|
18
|
+
|
|
19
|
+
<%= command_usage(:init_release) %>
|
|
20
|
+
<%= command_usage(:generate_package) %>
|
|
21
|
+
<%= command_usage(:generate_job) %>
|
|
22
|
+
|
|
23
|
+
Stemcells
|
|
24
|
+
<%= command_usage(:upload_stemcell) %>
|
|
25
|
+
<%= command_usage(:verify_stemcell) %>
|
|
26
|
+
<%= command_usage(:list_stemcells) %>
|
|
27
|
+
<%= command_usage(:delete_stemcell) %>
|
|
28
|
+
<%= command_usage(:list_public_stemcells) %>
|
|
29
|
+
<%= command_usage(:download_public_stemcell) %>
|
|
30
|
+
|
|
31
|
+
User management
|
|
32
|
+
<%= command_usage(:create_user) %>
|
|
33
|
+
|
|
34
|
+
Job management
|
|
35
|
+
<%= command_usage(:start_job) %>
|
|
36
|
+
<%= command_usage(:stop_job) %>
|
|
37
|
+
<%= command_usage(:restart_job) %>
|
|
38
|
+
<%= command_usage(:recreate_job) %>
|
|
39
|
+
|
|
40
|
+
Log management
|
|
41
|
+
<%= command_usage(:fetch_logs) %>
|
|
42
|
+
|
|
43
|
+
Task management
|
|
44
|
+
<%= command_usage(:list_running_tasks) %>
|
|
45
|
+
<%= command_usage(:list_recent_tasks) %>
|
|
46
|
+
<%= command_usage(:track_task) %>
|
|
47
|
+
<%= command_usage(:cancel_task) %>
|
|
48
|
+
|
|
49
|
+
Property management
|
|
50
|
+
<%= command_usage(:set_property) %>
|
|
51
|
+
<%= command_usage(:get_property) %>
|
|
52
|
+
<%= command_usage(:unset_property) %>
|
|
53
|
+
<%= command_usage(:list_properties) %>
|
|
54
|
+
|
|
55
|
+
Maintenance
|
|
56
|
+
<%= command_usage(:cleanup) %>
|
|
57
|
+
<%= command_usage(:cloudcheck) %>
|
|
58
|
+
|
|
59
|
+
Misc
|
|
60
|
+
<%= command_usage(:status) %>
|
|
61
|
+
<%= command_usage(:list_vms) %>
|
|
62
|
+
<%= command_usage(:target) %>
|
|
63
|
+
<%= command_usage(:login) %>
|
|
64
|
+
<%= command_usage(:logout) %>
|
|
65
|
+
<%= command_usage(:purge) %>
|
|
66
|
+
|
|
67
|
+
Remote access
|
|
68
|
+
<%= command_usage(:ssh) %>
|
|
69
|
+
<%= command_usage(:scp) %>
|
|
70
|
+
<%= command_usage(:ssh_cleanup) %>
|
|
71
|
+
|
|
72
|
+
Blob
|
|
73
|
+
<%= command_usage(:upload_blob) %>
|
|
74
|
+
<%= command_usage(:sync_blobs) %>
|
|
75
|
+
<%= command_usage(:blobs) %>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Cli
|
|
4
|
+
class ValidationHalted < StandardError; end
|
|
5
|
+
|
|
6
|
+
module Validation
|
|
7
|
+
|
|
8
|
+
def errors
|
|
9
|
+
@errors ||= []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def valid?(options = {})
|
|
13
|
+
validate(options) unless @validated
|
|
14
|
+
errors.empty?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def validate(options = {})
|
|
18
|
+
perform_validation(options)
|
|
19
|
+
rescue ValidationHalted
|
|
20
|
+
ensure
|
|
21
|
+
@validated = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def reset_validation
|
|
25
|
+
@validated = nil
|
|
26
|
+
@errors = []
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def step(name, error_message, kind = :non_fatal, &block)
|
|
32
|
+
passed = yield
|
|
33
|
+
|
|
34
|
+
say("%-60s %s" % [name, passed ? "OK".green : "FAILED".red])
|
|
35
|
+
|
|
36
|
+
unless passed
|
|
37
|
+
errors << error_message
|
|
38
|
+
raise ValidationHalted if kind == :fatal
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/cli/version.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Cli
|
|
4
|
+
module VersionCalc
|
|
5
|
+
|
|
6
|
+
# Returns 0 if two versions are the same,
|
|
7
|
+
# 1 if v1 > v2
|
|
8
|
+
# -1 if v1 < v2
|
|
9
|
+
def version_cmp(v1 = "0", v2 = "0")
|
|
10
|
+
vp1 = components(v1)
|
|
11
|
+
vp2 = components(v2)
|
|
12
|
+
|
|
13
|
+
[vp1.size, vp2.size].max.times do |i|
|
|
14
|
+
result = vp1[i].to_i <=> vp2[i].to_i
|
|
15
|
+
return result unless result == 0
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
0
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def version_greater(v1, v2)
|
|
22
|
+
version_cmp(v1, v2) > 0
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def version_less(v1, v2)
|
|
26
|
+
version_cmp(v1, v2) < 0
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def version_same(v1, v2)
|
|
30
|
+
version_cmp(v1, v2) == 0
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def major_version(v)
|
|
34
|
+
components(v)[0].to_i
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def minor_version(v)
|
|
38
|
+
components(v)[1].to_i
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def components(v)
|
|
44
|
+
v.to_s.split(".")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Cli
|
|
4
|
+
class VersionsIndex
|
|
5
|
+
include VersionCalc
|
|
6
|
+
|
|
7
|
+
def initialize(storage_dir, name_prefix = nil)
|
|
8
|
+
@storage_dir = File.expand_path(storage_dir)
|
|
9
|
+
@index_file = File.join(@storage_dir, "index.yml")
|
|
10
|
+
@name_prefix = name_prefix
|
|
11
|
+
|
|
12
|
+
if File.file?(@index_file)
|
|
13
|
+
init_index(load_yaml_file(@index_file, nil))
|
|
14
|
+
else
|
|
15
|
+
init_index({})
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def find_by_checksum(checksum)
|
|
20
|
+
@data["builds"].each_pair do |fingerprint, build_data|
|
|
21
|
+
return build_data if build_data["sha1"] == checksum
|
|
22
|
+
end
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def [](fingerprint)
|
|
27
|
+
@data["builds"][fingerprint]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def latest_version(major = nil)
|
|
31
|
+
builds = @data["builds"].values
|
|
32
|
+
|
|
33
|
+
if major
|
|
34
|
+
builds = builds.select do |build|
|
|
35
|
+
major_version(build["version"]) == major
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
return nil if builds.empty?
|
|
40
|
+
|
|
41
|
+
sorted = builds.sort { |build1, build2|
|
|
42
|
+
cmp = version_cmp(build2["version"], build1["version"])
|
|
43
|
+
if cmp == 0
|
|
44
|
+
raise "There is a duplicate version `#{build1["version"]}' " +
|
|
45
|
+
"in index `#{@index_file}'"
|
|
46
|
+
end
|
|
47
|
+
cmp
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
sorted[0]["version"]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def version_exists?(version)
|
|
54
|
+
File.exists?(filename(version))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def add_version(fingerprint, item, payload = nil)
|
|
58
|
+
version = item["version"]
|
|
59
|
+
|
|
60
|
+
if version.blank?
|
|
61
|
+
raise InvalidIndex,
|
|
62
|
+
"Cannot save index entry without knowing its version"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
create_directories
|
|
66
|
+
|
|
67
|
+
if payload
|
|
68
|
+
File.open(filename(version), "w") do |f|
|
|
69
|
+
f.write(payload)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
@data["builds"].each_pair do |fp, build|
|
|
74
|
+
if version_cmp(build["version"], version) == 0 && fp != fingerprint
|
|
75
|
+
raise "Trying to add duplicate version `#{version}' " +
|
|
76
|
+
"into index `#{@index_file}'"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
@data["builds"][fingerprint] = item
|
|
81
|
+
if payload
|
|
82
|
+
@data["builds"][fingerprint]["sha1"] = Digest::SHA1.hexdigest(payload)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
File.open(@index_file, "w") do |f|
|
|
86
|
+
f.write(YAML.dump(@data))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
File.expand_path(filename(version))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def filename(version)
|
|
93
|
+
name = @name_prefix.blank? ?
|
|
94
|
+
"#{version}.tgz" : "#{@name_prefix}-#{version}.tgz"
|
|
95
|
+
File.join(@storage_dir, name)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def create_directories
|
|
101
|
+
begin
|
|
102
|
+
FileUtils.mkdir_p(@storage_dir)
|
|
103
|
+
rescue SystemCallError => e
|
|
104
|
+
raise InvalidIndex, "Cannot create index storage directory: #{e}"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
begin
|
|
108
|
+
FileUtils.touch(@index_file)
|
|
109
|
+
rescue SystemCallError => e
|
|
110
|
+
raise InvalidIndex, "Cannot create index file: #{e}"
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def init_index(data)
|
|
115
|
+
data ||= {}
|
|
116
|
+
|
|
117
|
+
unless data.kind_of?(Hash)
|
|
118
|
+
raise InvalidIndex, "Invalid versions index data type, " +
|
|
119
|
+
"#{data.class} given, Hash expected"
|
|
120
|
+
end
|
|
121
|
+
@data = data
|
|
122
|
+
@data.delete("latest_version") # Indices used to track latest versions
|
|
123
|
+
@data["builds"] ||= {}
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
module Bosh::Cli
|
|
4
|
+
class YamlHelper
|
|
5
|
+
class << self
|
|
6
|
+
private
|
|
7
|
+
def process_object(o)
|
|
8
|
+
case o
|
|
9
|
+
when @syck_class::Map
|
|
10
|
+
process_map(o)
|
|
11
|
+
when @syck_class::Seq
|
|
12
|
+
process_seq(o)
|
|
13
|
+
when @syck_class::Scalar
|
|
14
|
+
else
|
|
15
|
+
err("Unhandled class #{o.class}, fix yaml duplicate check")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def process_seq(s)
|
|
20
|
+
s.value.each do |v|
|
|
21
|
+
process_object(v)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def process_map(m)
|
|
26
|
+
return if m.class != @syck_class::Map
|
|
27
|
+
s = Set.new
|
|
28
|
+
m.value.each_key do |k|
|
|
29
|
+
raise "Found dup key #{k.value}" if s.include?(k.value)
|
|
30
|
+
s.add(k.value)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
m.value.each_value do |v|
|
|
34
|
+
process_object(v)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
public
|
|
39
|
+
def check_duplicate_keys(path)
|
|
40
|
+
# Some Ruby builds on Ubuntu seem to expose a bug
|
|
41
|
+
# with the opposite order of Syck check, so we first
|
|
42
|
+
# check for Syck and then for YAML::Syck
|
|
43
|
+
if defined?(Syck)
|
|
44
|
+
@syck_class = Syck
|
|
45
|
+
elsif defined?(YAML::Syck)
|
|
46
|
+
@syck_class = YAML::Syck
|
|
47
|
+
else
|
|
48
|
+
raise "Cannot find Syck parser for YAML, " +
|
|
49
|
+
"please check your Ruby installation"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
File.open(path) do |f|
|
|
53
|
+
begin
|
|
54
|
+
process_map(YAML.parse(f))
|
|
55
|
+
rescue => e
|
|
56
|
+
raise "Bad yaml file #{path}, " + e.message
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|