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
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Bosh::Cli::ReleaseBuilder do
|
|
6
|
+
|
|
7
|
+
before(:each) do
|
|
8
|
+
@release_dir = Dir.mktmpdir
|
|
9
|
+
FileUtils.mkdir_p(File.join(@release_dir, "config"))
|
|
10
|
+
@release = Bosh::Cli::Release.new(@release_dir)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def new_builder
|
|
14
|
+
Bosh::Cli::ReleaseBuilder.new(@release, [], [])
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "uses version 1 if no previous releases have been created" do
|
|
18
|
+
new_builder.version.should == 1
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "builds a release" do
|
|
22
|
+
builder = new_builder
|
|
23
|
+
builder.build
|
|
24
|
+
|
|
25
|
+
expected_tarball_path = File.join(@release_dir,
|
|
26
|
+
"dev_releases", "bosh_release-1.tgz")
|
|
27
|
+
|
|
28
|
+
builder.tarball_path.should == expected_tarball_path
|
|
29
|
+
File.file?(expected_tarball_path).should be_true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "doesn't build a new release if nothing has changed" do
|
|
33
|
+
builder = new_builder
|
|
34
|
+
builder.build
|
|
35
|
+
builder.build
|
|
36
|
+
|
|
37
|
+
File.file?(File.join(@release_dir, "dev_releases", "bosh_release-1.tgz")).
|
|
38
|
+
should be_true
|
|
39
|
+
File.file?(File.join(@release_dir, "dev_releases", "bosh_release-2.tgz")).
|
|
40
|
+
should be_false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "has a list of jobs affected by building this release" do
|
|
44
|
+
job1 = mock(:job, :new_version? => true,
|
|
45
|
+
:packages => ["bar", "baz"], :name => "job1")
|
|
46
|
+
job2 = mock(:job, :new_version? => false,
|
|
47
|
+
:packages => ["foo", "baz"], :name => "job2")
|
|
48
|
+
job3 = mock(:job, :new_version? => false,
|
|
49
|
+
:packages => ["baz", "zb"], :name => "job3")
|
|
50
|
+
job4 = mock(:job, :new_version? => false,
|
|
51
|
+
:packages => ["bar", "baz"], :name => "job4")
|
|
52
|
+
|
|
53
|
+
package1 = mock(:package, :name => "foo", :new_version? => true)
|
|
54
|
+
package2 = mock(:package, :name => "bar", :new_version? => false)
|
|
55
|
+
package3 = mock(:package, :name => "baz", :new_version? => false)
|
|
56
|
+
package4 = mock(:package, :name => "zb", :new_version? => true)
|
|
57
|
+
|
|
58
|
+
builder = Bosh::Cli::ReleaseBuilder.new(@release,
|
|
59
|
+
[package1, package2,
|
|
60
|
+
package3, package4],
|
|
61
|
+
[job1, job2, job3, job4])
|
|
62
|
+
builder.affected_jobs.should =~ [job1, job2, job3]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Bosh::Cli::Release do
|
|
6
|
+
|
|
7
|
+
before :each do
|
|
8
|
+
@release_dir = Dir.mktmpdir
|
|
9
|
+
FileUtils.mkdir_p(File.join(@release_dir, "config"))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def new_release(dir)
|
|
13
|
+
Bosh::Cli::Release.new(@release_dir)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "persists release attributes" do
|
|
17
|
+
r = new_release(@dir)
|
|
18
|
+
|
|
19
|
+
r.dev_name.should be_nil
|
|
20
|
+
r.final_name.should be_nil
|
|
21
|
+
r.min_cli_version.should be_nil
|
|
22
|
+
r.latest_release_filename.should be_nil
|
|
23
|
+
|
|
24
|
+
r.dev_name = "dev-release"
|
|
25
|
+
r.final_name = "prod-release"
|
|
26
|
+
r.min_cli_version = "0.5.2"
|
|
27
|
+
r.latest_release_filename = "foobar"
|
|
28
|
+
r.save_config
|
|
29
|
+
|
|
30
|
+
r2 = new_release(@release_dir)
|
|
31
|
+
r.dev_name.should == "dev-release"
|
|
32
|
+
r.final_name.should == "prod-release"
|
|
33
|
+
r.min_cli_version.should == "0.5.2"
|
|
34
|
+
r.latest_release_filename.should == "foobar"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "has attributes persisted in bosh user config" do
|
|
38
|
+
r = new_release(@release_dir)
|
|
39
|
+
r.dev_name = "dev-release"
|
|
40
|
+
r.final_name = "prod-release"
|
|
41
|
+
r.min_cli_version = "0.5.2"
|
|
42
|
+
r.save_config
|
|
43
|
+
|
|
44
|
+
FileUtils.rm_rf(File.join(@release_dir, "config", "dev.yml"))
|
|
45
|
+
|
|
46
|
+
r = new_release(@release_dir)
|
|
47
|
+
r.dev_name.should be_nil
|
|
48
|
+
r.final_name.should == "prod-release"
|
|
49
|
+
r.min_cli_version.should == "0.5.2"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "has attributes persisted in public release config" do
|
|
53
|
+
r = new_release(@release_dir)
|
|
54
|
+
r.dev_name = "dev-release"
|
|
55
|
+
r.final_name = "prod-release"
|
|
56
|
+
r.min_cli_version = "0.5.2"
|
|
57
|
+
r.save_config
|
|
58
|
+
|
|
59
|
+
FileUtils.rm_rf(File.join(@release_dir, "config", "final.yml"))
|
|
60
|
+
|
|
61
|
+
r = new_release(@release_dir)
|
|
62
|
+
r.dev_name.should == "dev-release"
|
|
63
|
+
r.final_name.should be_nil
|
|
64
|
+
r.min_cli_version.should be_nil
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Bosh::Cli::ReleaseTarball do
|
|
6
|
+
|
|
7
|
+
describe "verifying a release" do
|
|
8
|
+
it "verifies and reports a valid release" do
|
|
9
|
+
tarball = Bosh::Cli::ReleaseTarball.new(spec_asset("valid_release.tgz"))
|
|
10
|
+
tarball.should be_valid
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "verifies repacked release if appropriate option is set" do
|
|
14
|
+
tarball = Bosh::Cli::ReleaseTarball.new(spec_asset("valid_release.tgz"))
|
|
15
|
+
remote_release = {
|
|
16
|
+
"packages" => [{ "name" => "mutator", "version" => "2.99.7" }],
|
|
17
|
+
"jobs" => [{ "name" => "cacher", "version" => "1" },
|
|
18
|
+
{ "name" => "sweeper", "version" => "1" }]
|
|
19
|
+
}
|
|
20
|
+
repacked_tarball_path = tarball.repack(remote_release)
|
|
21
|
+
|
|
22
|
+
tarball.skipped.should == 2
|
|
23
|
+
|
|
24
|
+
repacked_tarball = Bosh::Cli::ReleaseTarball.new(repacked_tarball_path)
|
|
25
|
+
repacked_tarball.valid?.should be_false
|
|
26
|
+
repacked_tarball.reset_validation
|
|
27
|
+
repacked_tarball.valid?(:allow_sparse => true).should be_true
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# TODO: add whining on potential errors
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Bosh::Cli::Runner do
|
|
6
|
+
|
|
7
|
+
before(:all) do
|
|
8
|
+
@out = StringIO.new
|
|
9
|
+
Bosh::Cli::Config.output = @out
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_cmd(args, namespace, action, cmd_args = [])
|
|
13
|
+
runner = Bosh::Cli::Runner.new(args)
|
|
14
|
+
runner.prepare
|
|
15
|
+
runner.dispatch
|
|
16
|
+
|
|
17
|
+
runner.namespace.should == namespace
|
|
18
|
+
runner.action.should == action
|
|
19
|
+
runner.args.should == cmd_args
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "has a set of default global options" do
|
|
23
|
+
runner = Bosh::Cli::Runner.new(["do", "some", "stuff"])
|
|
24
|
+
runner.parse_options!
|
|
25
|
+
runner.options[:verbose].should == nil
|
|
26
|
+
runner.options[:colorize].should == true
|
|
27
|
+
runner.options[:director_checks].should == true
|
|
28
|
+
runner.options[:quiet].should == nil
|
|
29
|
+
runner.options[:non_interactive].should == nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "allows overriding global options" do
|
|
33
|
+
runner = Bosh::Cli::Runner.new(["--verbose", "--no-color",
|
|
34
|
+
"--skip-director-checks", "--quiet",
|
|
35
|
+
"--non-interactive", "release",
|
|
36
|
+
"upload", "/path"])
|
|
37
|
+
runner.parse_options!
|
|
38
|
+
runner.options[:verbose].should == true
|
|
39
|
+
runner.options[:colorize].should == false
|
|
40
|
+
runner.options[:director_checks].should == false
|
|
41
|
+
runner.options[:quiet].should == true
|
|
42
|
+
runner.options[:non_interactive].should == true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "dispatches commands to appropriate methods (nu school)" do
|
|
46
|
+
test_cmd(["version"], :misc, :version)
|
|
47
|
+
test_cmd(["status"], :misc, :status)
|
|
48
|
+
test_cmd(["target"], :misc, :show_target)
|
|
49
|
+
test_cmd(["target", "test"], :misc, :set_target, ["test"])
|
|
50
|
+
test_cmd(["target", "test", "alias"], :misc, :set_target, ["test", "alias"])
|
|
51
|
+
test_cmd(["deploy"], :deployment, :perform)
|
|
52
|
+
test_cmd(["deployment"], :deployment, :show_current)
|
|
53
|
+
test_cmd(["deployment", "test"], :deployment, :set_current, ["test"])
|
|
54
|
+
|
|
55
|
+
test_cmd(["delete", "deployment", "foo"], :deployment, :delete, ["foo"])
|
|
56
|
+
test_cmd(["delete", "stemcell", "a", "1"], :stemcell, :delete, ["a", "1"])
|
|
57
|
+
test_cmd(["delete", "release", "a"], :release, :delete, ["a"])
|
|
58
|
+
test_cmd(["delete", "release", "a", "--force"],
|
|
59
|
+
:release, :delete, ["a", "--force"])
|
|
60
|
+
test_cmd(["delete", "release", "a", "2.2.1", "--force"],
|
|
61
|
+
:release, :delete, ["a", "2.2.1", "--force"])
|
|
62
|
+
|
|
63
|
+
test_cmd(["create", "user", "admin"], :user, :create, ["admin"])
|
|
64
|
+
test_cmd(["create", "user", "admin", "12321"],
|
|
65
|
+
:user, :create, ["admin", "12321"])
|
|
66
|
+
test_cmd(["create", "release"], :release, :create)
|
|
67
|
+
test_cmd(["reset", "release"], :release, :reset)
|
|
68
|
+
test_cmd(["create", "package", "bla"], :package, :create, ["bla"])
|
|
69
|
+
|
|
70
|
+
test_cmd(["login", "admin", "12321"], :misc, :login, ["admin", "12321"])
|
|
71
|
+
test_cmd(["logout"], :misc, :logout)
|
|
72
|
+
test_cmd(["purge"], :misc, :purge_cache)
|
|
73
|
+
|
|
74
|
+
test_cmd(["init", "release"], :release, :init)
|
|
75
|
+
test_cmd(["init", "release", "/path"], :release, :init, ["/path"])
|
|
76
|
+
|
|
77
|
+
test_cmd(["upload", "release", "/path"], :release, :upload, ["/path"])
|
|
78
|
+
test_cmd(["upload", "release"], :release, :upload)
|
|
79
|
+
test_cmd(["upload", "stemcell", "/path"], :stemcell, :upload, ["/path"])
|
|
80
|
+
|
|
81
|
+
test_cmd(["generate", "package", "foo"], :package, :generate, ["foo"])
|
|
82
|
+
test_cmd(["generate", "job", "baz"], :job, :generate, ["baz"])
|
|
83
|
+
|
|
84
|
+
test_cmd(["verify", "release", "/path"], :release, :verify, ["/path"])
|
|
85
|
+
test_cmd(["verify", "stemcell", "/path"], :stemcell, :verify, ["/path"])
|
|
86
|
+
|
|
87
|
+
test_cmd(["stemcells"], :stemcell, :list)
|
|
88
|
+
test_cmd(["releases"], :release, :list)
|
|
89
|
+
test_cmd(["deployments"], :deployment, :list)
|
|
90
|
+
|
|
91
|
+
test_cmd(["tasks"], :task, :list_running)
|
|
92
|
+
test_cmd(["task", "500"], :task, :track, ["500"])
|
|
93
|
+
test_cmd(["tasks"], :task, :list_running)
|
|
94
|
+
test_cmd(["tasks", "recent"], :task, :list_recent)
|
|
95
|
+
test_cmd(["tasks", "recent", "42"], :task, :list_recent, ["42"])
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "cancels running task and quits when ctrl-c is issued " +
|
|
99
|
+
"and user agrees to quit" do
|
|
100
|
+
runner = Bosh::Cli::Runner.new(["any", "command"])
|
|
101
|
+
runner.runner = {}
|
|
102
|
+
runner.runner.stub(:task_running?).and_return(true)
|
|
103
|
+
runner.stub(:kill_current_task?).and_return(true)
|
|
104
|
+
runner.runner.should_receive(:cancel_current_task).once
|
|
105
|
+
lambda { runner.handle_ctrl_c }.should raise_error SystemExit
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "quits when ctrl-c is issued and there is no task running" do
|
|
109
|
+
runner = Bosh::Cli::Runner.new(["any", "command"])
|
|
110
|
+
runner.runner = {}
|
|
111
|
+
runner.runner.stub(:task_running?).and_return(false)
|
|
112
|
+
lambda { runner.handle_ctrl_c }.should raise_error SystemExit
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "doesn't quit when user issues ctrl-c but does not want to quit" do
|
|
116
|
+
runner = Bosh::Cli::Runner.new(["any", "command"])
|
|
117
|
+
runner.runner = {}
|
|
118
|
+
runner.runner.stub(:task_running?).and_return(true)
|
|
119
|
+
runner.stub(:kill_current_task?).and_return(false)
|
|
120
|
+
lambda { runner.handle_ctrl_c }.should_not raise_error SystemExit
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "loads custom plugins" do
|
|
124
|
+
plugin_path = spec_asset("plugins")
|
|
125
|
+
$:.unshift(plugin_path)
|
|
126
|
+
|
|
127
|
+
begin
|
|
128
|
+
test_cmd(["banner", "foo"], :echo, :banner, ["foo"])
|
|
129
|
+
test_cmd(["say", "bar"], :echo, :say_color, ["bar"])
|
|
130
|
+
test_cmd(["say", "baz", "--color", "red"],
|
|
131
|
+
:echo, :say_color, ["baz", "--color", "red"])
|
|
132
|
+
|
|
133
|
+
test_cmd(["ruby", "version"], :ruby, :ruby_version)
|
|
134
|
+
test_cmd(["ruby", "config", "arch"], :ruby, :ruby_config, ["arch"])
|
|
135
|
+
ensure
|
|
136
|
+
$:.shift.should == plugin_path
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Bosh::Cli::Command::Base do
|
|
6
|
+
|
|
7
|
+
before :all do
|
|
8
|
+
@public_key = File.join(Dir.mktmpdir, "public_key")
|
|
9
|
+
File.open(@public_key, "w+") do |f|
|
|
10
|
+
f.write("PUBLIC_KEY")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe Bosh::Cli::Command::Ssh do
|
|
15
|
+
it "should get the public key" do
|
|
16
|
+
ssh = Bosh::Cli::Command::Ssh.new
|
|
17
|
+
public_key = ssh.get_public_key("public_key" => @public_key)
|
|
18
|
+
public_key.should == "PUBLIC_KEY"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should get the public key from users home directory " +
|
|
22
|
+
"or raise exception" do
|
|
23
|
+
ssh = Bosh::Cli::Command::Ssh.new
|
|
24
|
+
public_key = nil
|
|
25
|
+
begin
|
|
26
|
+
public_key = ssh.get_public_key({})
|
|
27
|
+
rescue Bosh::Cli::CliExit
|
|
28
|
+
public_key = "SOMETHING"
|
|
29
|
+
end
|
|
30
|
+
public_key.should_not be_nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should contact director to setup ssh on the job" do
|
|
34
|
+
mock_director = mock(Object)
|
|
35
|
+
mock_director.stub(:setup_ssh).and_return([{ "status" => "success",
|
|
36
|
+
"ip" => "127.0.0.1" }])
|
|
37
|
+
mock_director.stub(:cleanup_ssh)
|
|
38
|
+
Bosh::Cli::Director.should_receive(:new).and_return(mock_director)
|
|
39
|
+
ssh = Bosh::Cli::Command::Ssh.new
|
|
40
|
+
ssh.stub(:prepare_deployment_manifest).and_return("test")
|
|
41
|
+
ssh.stub(:cleanup_ssh)
|
|
42
|
+
ssh.setup_ssh("dea", 0, "temp_pass",
|
|
43
|
+
{ "public_key" => @public_key }) do |results, user|
|
|
44
|
+
results.each do |result|
|
|
45
|
+
result["status"].should == "success"
|
|
46
|
+
result["ip"].should == "127.0.0.1"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should try to setup interactive shell when a job index is given" do
|
|
52
|
+
ssh = Bosh::Cli::Command::Ssh.new
|
|
53
|
+
@interactive_shell = false
|
|
54
|
+
@execute_command = false
|
|
55
|
+
ssh.stub(:setup_interactive_shell) { @interactive_shell = true }
|
|
56
|
+
ssh.stub(:execute_command) { @execute_command = true }
|
|
57
|
+
ssh.shell("dea", "0")
|
|
58
|
+
@interactive_shell.should == true && @execute_command.should == false
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should fail to setup interactive shell when a job index is not given" do
|
|
62
|
+
ssh = Bosh::Cli::Command::Ssh.new
|
|
63
|
+
lambda {
|
|
64
|
+
ssh.shell("dea")
|
|
65
|
+
}.should raise_error(Bosh::Cli::CliExit, "Please specify a job index")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should try to execute given command remotely" do
|
|
69
|
+
ssh = Bosh::Cli::Command::Ssh.new
|
|
70
|
+
@interactive_shell = false
|
|
71
|
+
@execute_command = false
|
|
72
|
+
ssh.stub(:setup_interactive_shell) { @interactive_shell = true }
|
|
73
|
+
ssh.stub(:execute_command) { @execute_command = true }
|
|
74
|
+
ssh.shell("dea", "ls -l")
|
|
75
|
+
@interactive_shell.should == false && @execute_command.should == true
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Bosh::Cli::Stemcell do
|
|
6
|
+
|
|
7
|
+
describe "verifying a stemcell" do
|
|
8
|
+
it "verifies and reports a valid stemcell" do
|
|
9
|
+
sc = Bosh::Cli::Stemcell.new(spec_asset("valid_stemcell.tgz"),
|
|
10
|
+
Bosh::Cli::Cache.new(Dir.mktmpdir))
|
|
11
|
+
sc.should be_valid
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# TODO: add whining on potential errors
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Bosh::Cli::VersionCalc do
|
|
6
|
+
|
|
7
|
+
before :each do
|
|
8
|
+
@obj = Object.new.extend(Bosh::Cli::VersionCalc)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "can compare versions" do
|
|
12
|
+
@obj.version_cmp("1.2", "1.2").should == 0
|
|
13
|
+
@obj.version_cmp("1.3", "1.2").should == 1
|
|
14
|
+
@obj.version_cmp("0.1.7", "0.9.2").should == -1
|
|
15
|
+
@obj.version_cmp("0.1.7.5", "0.1.7").should == 1
|
|
16
|
+
@obj.version_cmp("0.1.7.4.9.9", "0.1.7.5").should == -1
|
|
17
|
+
|
|
18
|
+
@obj.version_cmp(10, 11).should == -1
|
|
19
|
+
@obj.version_cmp(43, 42).should == 1
|
|
20
|
+
@obj.version_cmp(7, 7).should == 0
|
|
21
|
+
|
|
22
|
+
@obj.version_cmp("10.9-dev", "10.10-dev").should == -1
|
|
23
|
+
@obj.version_cmp("0.2.3", "0.2.3.0.8").should == -1
|
|
24
|
+
@obj.version_cmp("0.2.3-dev", "0.2.3.0.3-dev").should == -1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Bosh::Cli::VersionsIndex do
|
|
6
|
+
|
|
7
|
+
before :each do
|
|
8
|
+
@dir = Dir.mktmpdir
|
|
9
|
+
@index_file = File.join(@dir, "index.yml")
|
|
10
|
+
@index = Bosh::Cli::VersionsIndex.new(@dir)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after :each do
|
|
14
|
+
FileUtils.rm_rf(@dir)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "only creates directory structure on writes to index" do
|
|
18
|
+
File.exists?(@index_file).should be_false
|
|
19
|
+
@index.version_exists?(1).should be_false
|
|
20
|
+
@index["deadbeef"].should be_nil
|
|
21
|
+
@index.latest_version.should be_nil
|
|
22
|
+
File.exists?(@index_file).should be_false
|
|
23
|
+
|
|
24
|
+
@index.add_version("deadcafe", { "version" => 2 }, "payload2")
|
|
25
|
+
File.exists?(@index_file).should be_true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "chokes on malformed index file" do
|
|
29
|
+
File.open(@index_file, "w") { |f| f.write("deadbeef") }
|
|
30
|
+
|
|
31
|
+
lambda {
|
|
32
|
+
@index = Bosh::Cli::VersionsIndex.new(@dir)
|
|
33
|
+
}.should raise_error(Bosh::Cli::InvalidIndex,
|
|
34
|
+
"Invalid versions index data type, " +
|
|
35
|
+
"String given, Hash expected")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "doesn't choke on empty index file" do
|
|
39
|
+
File.open(@index_file, "w") { |f| f.write("") }
|
|
40
|
+
@index = Bosh::Cli::VersionsIndex.new(@dir)
|
|
41
|
+
@index.latest_version.should be_nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "can be used to add versioned payloads to index" do
|
|
45
|
+
item1 = { "a" => 1, "b" => 2, "version" => 1 }
|
|
46
|
+
item2 = { "a" => 3, "b" => 4, "version" => 2 }
|
|
47
|
+
@index.add_version("deadbeef", item1, "payload1")
|
|
48
|
+
@index.add_version("deadcafe", item2, "payload2")
|
|
49
|
+
|
|
50
|
+
@index.latest_version.should == 2
|
|
51
|
+
@index["deadbeef"].should ==
|
|
52
|
+
item1.merge("sha1" => Digest::SHA1.hexdigest("payload1"))
|
|
53
|
+
@index["deadcafe"].should ==
|
|
54
|
+
item2.merge("sha1" => Digest::SHA1.hexdigest("payload2"))
|
|
55
|
+
@index.version_exists?(1).should be_true
|
|
56
|
+
@index.version_exists?(2).should be_true
|
|
57
|
+
@index.version_exists?(3).should be_false
|
|
58
|
+
|
|
59
|
+
@index.filename(1).should == File.join(@dir, "1.tgz")
|
|
60
|
+
@index.filename(2).should == File.join(@dir, "2.tgz")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "you shall not pass without version" do
|
|
64
|
+
item_noversion = { "a" => 1, "b" => 2 }
|
|
65
|
+
lambda {
|
|
66
|
+
@index.add_version("deadbeef", item_noversion, "payload1")
|
|
67
|
+
}.should raise_error(Bosh::Cli::InvalidIndex,
|
|
68
|
+
"Cannot save index entry without knowing its version")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "latest version only gets updated if it's greater than current latest" do
|
|
72
|
+
item1 = { "a" => 1, "b" => 2, "version" => 1 }
|
|
73
|
+
item2 = { "a" => 3, "b" => 4, "version" => 2 }
|
|
74
|
+
item3 = { "a" => 3, "b" => 4, "version" => 3 }
|
|
75
|
+
|
|
76
|
+
@index.add_version("deadbeef", item1, "payload1")
|
|
77
|
+
@index.add_version("deadcafe", item2, "payload2")
|
|
78
|
+
@index.latest_version.should == 2
|
|
79
|
+
@index.add_version("addedface", item3, "payload2")
|
|
80
|
+
@index.latest_version.should == 3
|
|
81
|
+
@index.add_version("facedbeef", item1.merge("version" => "1.5"), "payload3")
|
|
82
|
+
@index.latest_version.should == 3
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "supports dev versions and proper version comparison when updating latest version" do
|
|
86
|
+
item1 = { "a" => 1, "b" => 2, "version" => "1.9-dev" }
|
|
87
|
+
item2 = { "a" => 3, "b" => 4, "version" => "1.8-dev" }
|
|
88
|
+
item3 = { "a" => 3, "b" => 4, "version" => "1.10-dev" }
|
|
89
|
+
|
|
90
|
+
@index.add_version("deadbeef", item1, "payload1")
|
|
91
|
+
@index.add_version("deadcafe", item2, "payload2")
|
|
92
|
+
@index.latest_version.should == "1.9-dev"
|
|
93
|
+
@index.add_version("facedead", item3, "payload2")
|
|
94
|
+
@index.latest_version.should == "1.10-dev"
|
|
95
|
+
@index.add_version("badbed", item1.merge("version" => "2.15-dev"), "payload3")
|
|
96
|
+
@index.latest_version.should == "2.15-dev"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "doesn't allow duplicate fingerprints or versions" do
|
|
100
|
+
item1 = { "a" => 1, "b" => 2, "version" => "1.9-dev" }
|
|
101
|
+
item2 = { "a" => 3, "b" => 4, "version" => "1.8-dev" }
|
|
102
|
+
|
|
103
|
+
@index.add_version("deadbeef", item1, "payload1")
|
|
104
|
+
|
|
105
|
+
lambda {
|
|
106
|
+
@index.add_version("deadcafe", item1, "payload3")
|
|
107
|
+
}.should raise_error("Trying to add duplicate version `1.9-dev' " +
|
|
108
|
+
"into index `#{File.join(@dir, "index.yml")}'")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "supports finding entries by checksum" do
|
|
112
|
+
item1 = { "a" => 1, "b" => 2, "version" => 1 }
|
|
113
|
+
item2 = { "a" => 3, "b" => 4, "version" => 2 }
|
|
114
|
+
|
|
115
|
+
@index.add_version("deadbeef", item1, "payload1")
|
|
116
|
+
@index.add_version("deadcafe", item2, "payload2")
|
|
117
|
+
|
|
118
|
+
checksum1 = Digest::SHA1.hexdigest("payload1")
|
|
119
|
+
checksum2 = Digest::SHA1.hexdigest("payload2")
|
|
120
|
+
|
|
121
|
+
@index.find_by_checksum(checksum1).should == item1.merge("sha1" => checksum1)
|
|
122
|
+
@index.find_by_checksum(checksum2).should == item2.merge("sha1" => checksum2)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "supports name prefix" do
|
|
126
|
+
item = { "a" => 1, "b" => 2, "version" => 1 }
|
|
127
|
+
@index = Bosh::Cli::VersionsIndex.new(@dir, "foobar")
|
|
128
|
+
@index.add_version("deadbeef", item, "payload1")
|
|
129
|
+
@index.filename(1).should == File.join(@dir, "foobar-1.tgz")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|