bosh_cpi 0.4.2
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 +1 -0
- data/Rakefile +50 -0
- data/lib/cloud/config.rb +14 -0
- data/lib/cloud/errors.rb +21 -0
- data/lib/cloud/provider.rb +14 -0
- data/lib/cloud/version.rb +5 -0
- data/lib/cloud.rb +177 -0
- data/spec/lib/cloud/spec.rb +9 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/unit/config_spec.rb +15 -0
- data/spec/unit/provider_spec.rb +19 -0
- metadata +76 -0
data/README
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
BOSH Cloud Provider Interface
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
$:.unshift(File.expand_path("../../rake", __FILE__))
|
4
|
+
|
5
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __FILE__)
|
6
|
+
|
7
|
+
require "rubygems"
|
8
|
+
require "bundler"
|
9
|
+
Bundler.setup(:default, :test)
|
10
|
+
|
11
|
+
require "rake"
|
12
|
+
begin
|
13
|
+
require "rspec/core/rake_task"
|
14
|
+
rescue LoadError
|
15
|
+
end
|
16
|
+
|
17
|
+
require "bundler_task"
|
18
|
+
require "ci_task"
|
19
|
+
|
20
|
+
gem_helper = Bundler::GemHelper.new(Dir.pwd)
|
21
|
+
|
22
|
+
desc "Build CPI gem into the pkg directory"
|
23
|
+
task "build" do
|
24
|
+
gem_helper.build_gem
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Build and install CPI into system gems"
|
28
|
+
task "install" do
|
29
|
+
Rake::Task["bundler:install"].invoke
|
30
|
+
gem_helper.install_gem
|
31
|
+
end
|
32
|
+
|
33
|
+
BundlerTask.new
|
34
|
+
|
35
|
+
if defined?(RSpec)
|
36
|
+
namespace :spec do
|
37
|
+
desc "Run Unit Tests"
|
38
|
+
rspec_task = RSpec::Core::RakeTask.new(:unit) do |t|
|
39
|
+
t.pattern = "spec/unit/**/*_spec.rb"
|
40
|
+
t.rspec_opts = %w(--format progress --colour)
|
41
|
+
end
|
42
|
+
|
43
|
+
CiTask.new do |task|
|
44
|
+
task.rspec_task = rspec_task
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Run tests"
|
49
|
+
task :spec => %w(spec:unit)
|
50
|
+
end
|
data/lib/cloud/config.rb
ADDED
data/lib/cloud/errors.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bosh::Clouds
|
2
|
+
|
3
|
+
class CpiError < StandardError; end
|
4
|
+
class NotImplemented < CpiError; end
|
5
|
+
|
6
|
+
class CloudError < StandardError; end
|
7
|
+
class VMNotFound < CloudError; end
|
8
|
+
|
9
|
+
class RetriableCloudError < CloudError
|
10
|
+
attr_accessor :ok_to_retry
|
11
|
+
|
12
|
+
def initialize(ok_to_retry)
|
13
|
+
@ok_to_retry = ok_to_retry
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class NoDiskSpace < RetriableCloudError; end
|
18
|
+
class DiskNotAttached < RetriableCloudError; end
|
19
|
+
class DiskNotFound < RetriableCloudError; end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Bosh::Clouds
|
2
|
+
class Provider
|
3
|
+
|
4
|
+
def self.create(plugin, options)
|
5
|
+
begin
|
6
|
+
require "cloud/#{plugin}"
|
7
|
+
rescue LoadError
|
8
|
+
raise CloudError, "Could not find Cloud Provider Plugin: #{plugin}"
|
9
|
+
end
|
10
|
+
Bosh::Clouds.const_get(plugin.capitalize).new(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
data/lib/cloud.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh; module Clouds; end; end
|
4
|
+
|
5
|
+
require "cloud/config"
|
6
|
+
require "cloud/errors"
|
7
|
+
require "cloud/provider"
|
8
|
+
|
9
|
+
module Bosh
|
10
|
+
|
11
|
+
##
|
12
|
+
# CPI - Cloud Provider Interface, used for interfacing with various IaaS APIs.
|
13
|
+
#
|
14
|
+
# Key terms:
|
15
|
+
# Stemcell: template used for creating VMs (shouldn't be powered on)
|
16
|
+
# VM: VM created from a stemcell with custom settings (networking and resources)
|
17
|
+
# Disk: volume that can be attached and detached from the VMs,
|
18
|
+
# never attached to more than a single VM at one time
|
19
|
+
class Cloud
|
20
|
+
|
21
|
+
##
|
22
|
+
# Cloud initialization
|
23
|
+
#
|
24
|
+
# @param [Hash] options cloud options
|
25
|
+
def initialize(options)
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Creates a stemcell
|
30
|
+
#
|
31
|
+
# @param [String] image_path path to an opaque blob containing the stemcell image
|
32
|
+
# @param [Hash] cloud_properties properties required for creating this template
|
33
|
+
# specific to a CPI
|
34
|
+
# @return [String] opaque id later used by {#create_vm} and {#delete_stemcell}
|
35
|
+
def create_stemcell(image_path, cloud_properties)
|
36
|
+
not_implemented(:create_stemcell)
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Deletes a stemcell
|
41
|
+
#
|
42
|
+
# @param [String] stemcell stemcell id that was once returned by {#create_stemcell}
|
43
|
+
# @return nil
|
44
|
+
def delete_stemcell(stemcell_id)
|
45
|
+
not_implemented(:delete_stemcell)
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Creates a VM - creates (and powers on) a VM from a stemcell with the proper resources
|
50
|
+
# and on the specified network. When disk locality is present the VM will be placed near
|
51
|
+
# the provided disk so it won't have to move when the disk is attached later.
|
52
|
+
#
|
53
|
+
# Sample networking config:
|
54
|
+
# {"network_a" =>
|
55
|
+
# {
|
56
|
+
# "netmask" => "255.255.248.0",
|
57
|
+
# "ip" => "172.30.41.40",
|
58
|
+
# "gateway" => "172.30.40.1",
|
59
|
+
# "dns" => ["172.30.22.153", "172.30.22.154"],
|
60
|
+
# "cloud_properties" => {"name" => "VLAN444"}
|
61
|
+
# }
|
62
|
+
# }
|
63
|
+
#
|
64
|
+
# Sample resource pool config (CPI specific):
|
65
|
+
# {
|
66
|
+
# "ram" => 512,
|
67
|
+
# "disk" => 512,
|
68
|
+
# "cpu" => 1
|
69
|
+
# }
|
70
|
+
# or similar for EC2:
|
71
|
+
# {"name" => "m1.small"}
|
72
|
+
#
|
73
|
+
# @param [String] agent_id UUID for the agent that will be used later on by the director
|
74
|
+
# to locate and talk to the agent
|
75
|
+
# @param [String] stemcell stemcell id that was once returned by {#create_stemcell}
|
76
|
+
# @param [Hash] resource_pool cloud specific properties describing the resources needed
|
77
|
+
# for this VM
|
78
|
+
# @param [Hash] networks list of networks and their settings needed for this VM
|
79
|
+
# @param [optional, String, Array] disk_locality disk id(s) if known of the disk(s) that will be
|
80
|
+
# attached to this vm
|
81
|
+
# @param [optional, Hash] env environment that will be passed to this vm
|
82
|
+
# @return [String] opaque id later used by {#configure_networks}, {#attach_disk},
|
83
|
+
# {#detach_disk}, and {#delete_vm}
|
84
|
+
def create_vm(agent_id, stemcell_id, resource_pool,
|
85
|
+
networks, disk_locality = nil, env = nil)
|
86
|
+
not_implemented(:create_vm)
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Deletes a VM
|
91
|
+
#
|
92
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
93
|
+
# @return nil
|
94
|
+
def delete_vm(vm_id)
|
95
|
+
not_implemented(:delete_vm)
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Reboots a VM
|
100
|
+
#
|
101
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
102
|
+
# @param [Optional, Hash] CPI specific options (e.g hard/soft reboot)
|
103
|
+
# @return nil
|
104
|
+
def reboot_vm(vm_id)
|
105
|
+
not_implemented(:reboot_vm)
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Configures networking an existing VM.
|
110
|
+
#
|
111
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
112
|
+
# @param [Hash] networks list of networks and their settings needed for this VM,
|
113
|
+
# same as the networks argument in {#create_vm}
|
114
|
+
# @return nil
|
115
|
+
def configure_networks(vm_id, networks)
|
116
|
+
not_implemented(:configure_networks)
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Creates a disk (possibly lazily) that will be attached later to a VM. When
|
121
|
+
# VM locality is specified the disk will be placed near the VM so it won't have to move
|
122
|
+
# when it's attached later.
|
123
|
+
#
|
124
|
+
# @param [Integer] size disk size in MB
|
125
|
+
# @param [optional, String] vm_locality vm id if known of the VM that this disk will
|
126
|
+
# be attached to
|
127
|
+
# @return [String] opaque id later used by {#attach_disk}, {#detach_disk}, and {#delete_disk}
|
128
|
+
def create_disk(size, vm_locality = nil)
|
129
|
+
not_implemented(:create_disk)
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# Deletes a disk
|
134
|
+
# Will raise an exception if the disk is attached to a VM
|
135
|
+
#
|
136
|
+
# @param [String] disk disk id that was once returned by {#create_disk}
|
137
|
+
# @return nil
|
138
|
+
def delete_disk(disk_id)
|
139
|
+
not_implemented(:delete_disk)
|
140
|
+
end
|
141
|
+
|
142
|
+
##
|
143
|
+
# Attaches a disk
|
144
|
+
#
|
145
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
146
|
+
# @param [String] disk disk id that was once returned by {#create_disk}
|
147
|
+
# @return nil
|
148
|
+
def attach_disk(vm_id, disk_id)
|
149
|
+
not_implemented(:attach_disk)
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# Detaches a disk
|
154
|
+
#
|
155
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
156
|
+
# @param [String] disk disk id that was once returned by {#create_disk}
|
157
|
+
# @return nil
|
158
|
+
def detach_disk(vm_id, disk_id)
|
159
|
+
not_implemented(:detach_disk)
|
160
|
+
end
|
161
|
+
|
162
|
+
##
|
163
|
+
# Validates the deployment
|
164
|
+
# @api not_yet_used
|
165
|
+
def validate_deployment(old_manifest, new_manifest)
|
166
|
+
not_implemented(:validate_deployment)
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
|
171
|
+
def not_implemented(method)
|
172
|
+
raise Bosh::Clouds::NotImplemented,
|
173
|
+
"`#{method}' is not implemented by #{self.class}"
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
|
4
|
+
|
5
|
+
require "rubygems"
|
6
|
+
require "bundler"
|
7
|
+
Bundler.setup(:default, :test)
|
8
|
+
|
9
|
+
require "rspec"
|
10
|
+
require "cloud"
|
11
|
+
require "logger"
|
12
|
+
|
13
|
+
class CloudSpecConfig
|
14
|
+
|
15
|
+
attr_accessor :db, :uuid
|
16
|
+
|
17
|
+
def logger
|
18
|
+
if @logger.nil?
|
19
|
+
@logger = Logger.new(STDOUT)
|
20
|
+
@logger.level = Logger::ERROR
|
21
|
+
end
|
22
|
+
@logger
|
23
|
+
end
|
24
|
+
|
25
|
+
def uuid
|
26
|
+
@uuid ||= self.class.name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Bosh::Clouds::Config.configure(CloudSpecConfig.new)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
describe Bosh::Clouds::Config do
|
4
|
+
it "configure a logger" do
|
5
|
+
Bosh::Clouds::Config.logger.should be_kind_of(Logger)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should configure a uuid" do
|
9
|
+
Bosh::Clouds::Config.uuid.should be_kind_of(String)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should not have a db configured" do
|
13
|
+
Bosh::Clouds::Config.db.should be_nil
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
3
|
+
|
4
|
+
describe Bosh::Clouds::Provider do
|
5
|
+
it "should create a provider instance" do
|
6
|
+
|
7
|
+
provider = Bosh::Clouds::Provider.create("spec", {})
|
8
|
+
provider.should be_kind_of(Bosh::Clouds::Spec)
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should fail to create an invalid provider" do
|
13
|
+
|
14
|
+
lambda {
|
15
|
+
Bosh::Clouds::Provider.create("enoent", {})
|
16
|
+
}.should raise_error(Bosh::Clouds::CloudError)
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bosh_cpi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- VMware
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-02 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bosh_common
|
16
|
+
requirement: &70217789535540 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70217789535540
|
25
|
+
description: BOSH CPI
|
26
|
+
email: support@vmware.com
|
27
|
+
executables: []
|
28
|
+
extensions: []
|
29
|
+
extra_rdoc_files: []
|
30
|
+
files:
|
31
|
+
- lib/cloud.rb
|
32
|
+
- lib/cloud/config.rb
|
33
|
+
- lib/cloud/errors.rb
|
34
|
+
- lib/cloud/provider.rb
|
35
|
+
- lib/cloud/version.rb
|
36
|
+
- README
|
37
|
+
- Rakefile
|
38
|
+
- spec/lib/cloud/spec.rb
|
39
|
+
- spec/spec_helper.rb
|
40
|
+
- spec/unit/config_spec.rb
|
41
|
+
- spec/unit/provider_spec.rb
|
42
|
+
homepage: http://www.vmware.com
|
43
|
+
licenses: []
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
hash: -2486536985115199089
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
hash: -2486536985115199089
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.8.12
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: BOSH CPI
|
72
|
+
test_files:
|
73
|
+
- spec/lib/cloud/spec.rb
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
- spec/unit/config_spec.rb
|
76
|
+
- spec/unit/provider_spec.rb
|