bosh_deployer 0.4.0 → 0.5.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.
- data/config/aws_defaults.yml +3 -0
- data/config/openstack_defaults.yml +50 -0
- data/lib/bosh/cli/commands/micro.rb +12 -1
- data/lib/deployer/config.rb +15 -3
- data/lib/deployer/instance_manager/aws.rb +12 -4
- data/lib/deployer/instance_manager/openstack.rb +256 -0
- data/lib/deployer/instance_manager/vsphere.rb +1 -1
- data/lib/deployer/instance_manager.rb +32 -6
- data/lib/deployer/version.rb +1 -1
- metadata +58 -8
data/config/aws_defaults.yml
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
---
|
2
|
+
name:
|
3
|
+
|
4
|
+
logging:
|
5
|
+
level: INFO
|
6
|
+
|
7
|
+
dir:
|
8
|
+
|
9
|
+
network:
|
10
|
+
type: dynamic
|
11
|
+
cloud_properties: {}
|
12
|
+
|
13
|
+
env:
|
14
|
+
bosh:
|
15
|
+
password:
|
16
|
+
|
17
|
+
resources:
|
18
|
+
persistent_disk: 4096
|
19
|
+
cloud_properties:
|
20
|
+
instance_type: m1.small
|
21
|
+
availability_zone:
|
22
|
+
|
23
|
+
cloud:
|
24
|
+
plugin: openstack
|
25
|
+
properties:
|
26
|
+
openstack:
|
27
|
+
auth_url:
|
28
|
+
username:
|
29
|
+
api_key:
|
30
|
+
tenant:
|
31
|
+
default_key_name:
|
32
|
+
default_security_groups: []
|
33
|
+
ssh_user: vcap
|
34
|
+
registry:
|
35
|
+
endpoint: http://admin:admin@localhost:25889
|
36
|
+
user: admin
|
37
|
+
password: admin
|
38
|
+
stemcell:
|
39
|
+
kernel_id:
|
40
|
+
disk: 4096
|
41
|
+
agent:
|
42
|
+
ntp: []
|
43
|
+
blobstore:
|
44
|
+
plugin: local
|
45
|
+
properties:
|
46
|
+
blobstore_path: /var/vcap/micro_bosh/data/cache
|
47
|
+
mbus:
|
48
|
+
|
49
|
+
apply_spec:
|
50
|
+
properties: {}
|
@@ -80,12 +80,14 @@ module Bosh::Cli::Command
|
|
80
80
|
|
81
81
|
def perform(*options)
|
82
82
|
update = options.delete("--update")
|
83
|
+
force = options.delete("--force")
|
83
84
|
stemcell = options.shift
|
84
85
|
|
85
86
|
err "No deployment set" unless deployment
|
86
87
|
|
88
|
+
manifest = load_yaml_file(deployment)
|
89
|
+
|
87
90
|
if stemcell.nil?
|
88
|
-
manifest = load_yaml_file(deployment)
|
89
91
|
unless manifest.is_a?(Hash)
|
90
92
|
err("Invalid manifest format")
|
91
93
|
end
|
@@ -114,6 +116,15 @@ module Bosh::Cli::Command
|
|
114
116
|
err "Instance exists. Did you mean to --update?"
|
115
117
|
end
|
116
118
|
|
119
|
+
# make sure the user knows a persistent disk is a really good idea
|
120
|
+
unless dig_hash(manifest, "resources", "persistent_disk")
|
121
|
+
unless force
|
122
|
+
msg = "No persistent disk configured, use --force to deploy anyway"
|
123
|
+
quit(msg.red)
|
124
|
+
end
|
125
|
+
say("WARNING! The micro bosh data won't be persisted".red)
|
126
|
+
end
|
127
|
+
|
117
128
|
confirmation = "Deploying new"
|
118
129
|
|
119
130
|
method = :create_deployment
|
data/lib/deployer/config.rb
CHANGED
@@ -10,7 +10,7 @@ module Bosh::Deployer
|
|
10
10
|
include Helpers
|
11
11
|
|
12
12
|
attr_accessor :logger, :db, :uuid, :resources, :cloud_options,
|
13
|
-
:spec_properties, :bosh_ip, :env, :name
|
13
|
+
:spec_properties, :agent_properties, :bosh_ip, :env, :name
|
14
14
|
|
15
15
|
def configure(config)
|
16
16
|
plugin = cloud_plugin(config)
|
@@ -31,7 +31,9 @@ module Bosh::Deployer
|
|
31
31
|
@logger.level = Logger.const_get(config["logging"]["level"].upcase)
|
32
32
|
@logger.formatter = ThreadFormatter.new
|
33
33
|
|
34
|
-
|
34
|
+
apply_spec = config["apply_spec"]
|
35
|
+
@spec_properties = apply_spec["properties"]
|
36
|
+
@agent_properties = apply_spec["agent"]
|
35
37
|
|
36
38
|
@db = Sequel.sqlite
|
37
39
|
|
@@ -87,7 +89,9 @@ module Bosh::Deployer
|
|
87
89
|
end
|
88
90
|
|
89
91
|
def networks
|
90
|
-
@networks
|
92
|
+
return @networks if @networks
|
93
|
+
|
94
|
+
@networks = {
|
91
95
|
"bosh" => {
|
92
96
|
"cloud_properties" => @net_conf["cloud_properties"],
|
93
97
|
"netmask" => @net_conf["netmask"],
|
@@ -98,6 +102,14 @@ module Bosh::Deployer
|
|
98
102
|
"default" => ["dns", "gateway"]
|
99
103
|
}
|
100
104
|
}
|
105
|
+
if @net_conf["vip"]
|
106
|
+
@networks["vip"] = {
|
107
|
+
"ip" => @net_conf["vip"],
|
108
|
+
"type" => "vip"
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
@networks
|
101
113
|
end
|
102
114
|
|
103
115
|
private
|
@@ -128,7 +128,15 @@ module Bosh::Deployer
|
|
128
128
|
|
129
129
|
def discover_bosh_ip
|
130
130
|
if exists?
|
131
|
-
|
131
|
+
# choose elastic IP over public, as any agent connecting to the
|
132
|
+
# deployed micro bosh will be cut off from the public IP when
|
133
|
+
# we re-deploy micro bosh
|
134
|
+
if cloud.ec2.instances[state.vm_cid].has_elastic_ip?
|
135
|
+
ip = cloud.ec2.instances[state.vm_cid].elastic_ip.public_ip
|
136
|
+
else
|
137
|
+
ip = cloud.ec2.instances[state.vm_cid].public_ip_address
|
138
|
+
end
|
139
|
+
|
132
140
|
if ip != Config.bosh_ip
|
133
141
|
Config.bosh_ip = ip
|
134
142
|
logger.info("discovered bosh ip=#{Config.bosh_ip}")
|
@@ -142,14 +150,14 @@ module Bosh::Deployer
|
|
142
150
|
cloud.ec2.instances[state.vm_cid].private_ip_address
|
143
151
|
end
|
144
152
|
|
145
|
-
# @return [Integer] size in
|
153
|
+
# @return [Integer] size in MiB
|
146
154
|
def disk_size(cid)
|
147
|
-
# AWS stores disk size in
|
155
|
+
# AWS stores disk size in GiB but the CPI uses MiB
|
148
156
|
cloud.ec2.volumes[cid].size * 1024
|
149
157
|
end
|
150
158
|
|
151
159
|
def persistent_disk_changed?
|
152
|
-
# since AWS stores disk size in
|
160
|
+
# since AWS stores disk size in GiB and the CPI uses MiB there
|
153
161
|
# is a risk of conversion errors which lead to an unnecessary
|
154
162
|
# disk migration, so we need to do a double conversion
|
155
163
|
# here to avoid that
|
@@ -0,0 +1,256 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
require 'net/ssh'
|
4
|
+
|
5
|
+
module Bosh::Deployer
|
6
|
+
class InstanceManager
|
7
|
+
|
8
|
+
class Openstack < InstanceManager
|
9
|
+
|
10
|
+
def update_spec(spec)
|
11
|
+
spec = super(spec)
|
12
|
+
properties = spec["properties"]
|
13
|
+
|
14
|
+
properties["openstack"] =
|
15
|
+
Config.spec_properties["openstack"] ||
|
16
|
+
Config.cloud_options["properties"]["openstack"].dup
|
17
|
+
|
18
|
+
properties["openstack"]["registry"] = Config.cloud_options["properties"]["registry"]
|
19
|
+
properties["openstack"]["stemcell"] = Config.cloud_options["properties"]["stemcell"]
|
20
|
+
|
21
|
+
spec.delete("networks")
|
22
|
+
|
23
|
+
spec
|
24
|
+
end
|
25
|
+
|
26
|
+
def configure
|
27
|
+
properties = Config.cloud_options["properties"]
|
28
|
+
@ssh_user = properties["openstack"]["ssh_user"]
|
29
|
+
@ssh_port = properties["openstack"]["ssh_port"] || 22
|
30
|
+
@ssh_wait = properties["openstack"]["ssh_wait"] || 60
|
31
|
+
|
32
|
+
key = properties["openstack"]["private_key"]
|
33
|
+
unless key
|
34
|
+
raise ConfigError, "Missing properties.openstack.private_key"
|
35
|
+
end
|
36
|
+
@ssh_key = File.expand_path(key)
|
37
|
+
unless File.exists?(@ssh_key)
|
38
|
+
raise ConfigError, "properties.openstack.private_key '#{key}' does not exist"
|
39
|
+
end
|
40
|
+
|
41
|
+
uri = URI.parse(properties["registry"]["endpoint"])
|
42
|
+
user, password = uri.userinfo.split(":", 2)
|
43
|
+
@registry_port = uri.port
|
44
|
+
|
45
|
+
@registry_db = Tempfile.new("openstack_registry_db")
|
46
|
+
@registry_db_url = "sqlite://#{@registry_db.path}"
|
47
|
+
|
48
|
+
registry_config = {
|
49
|
+
"logfile" => "./openstack_registry.log",
|
50
|
+
"http" => {
|
51
|
+
"port" => uri.port,
|
52
|
+
"user" => user,
|
53
|
+
"password" => password
|
54
|
+
},
|
55
|
+
"db" => {
|
56
|
+
"database" => @registry_db_url
|
57
|
+
},
|
58
|
+
"openstack" => properties["openstack"]
|
59
|
+
}
|
60
|
+
|
61
|
+
@registry_config = Tempfile.new("openstack_registry_yml")
|
62
|
+
@registry_config.write(YAML.dump(registry_config))
|
63
|
+
@registry_config.close
|
64
|
+
end
|
65
|
+
|
66
|
+
def start
|
67
|
+
configure()
|
68
|
+
|
69
|
+
Sequel.connect(@registry_db_url) do |db|
|
70
|
+
migrate(db)
|
71
|
+
servers = @deployments["openstack_servers"]
|
72
|
+
db[:openstack_servers].insert_multiple(servers) if servers
|
73
|
+
end
|
74
|
+
|
75
|
+
unless has_openstack_registry?
|
76
|
+
raise "openstack_registry command not found - " +
|
77
|
+
"run 'gem install bosh_openstack_registry'"
|
78
|
+
end
|
79
|
+
|
80
|
+
cmd = "openstack_registry -c #{@registry_config.path}"
|
81
|
+
|
82
|
+
@registry_pid = spawn(cmd)
|
83
|
+
|
84
|
+
5.times do
|
85
|
+
sleep 0.5
|
86
|
+
if Process.waitpid(@registry_pid, Process::WNOHANG)
|
87
|
+
raise Error, "`#{cmd}` failed, exit status=#{$?.exitstatus}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
timeout_time = Time.now.to_f + (60 * 5)
|
92
|
+
http_client = HTTPClient.new()
|
93
|
+
begin
|
94
|
+
http_client.head("http://127.0.0.1:#{@registry_port}")
|
95
|
+
sleep 0.5
|
96
|
+
rescue URI::Error, SocketError, Errno::ECONNREFUSED => e
|
97
|
+
if timeout_time - Time.now.to_f > 0
|
98
|
+
retry
|
99
|
+
else
|
100
|
+
raise "Cannot access openstack_registry: #{e.message}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
logger.info("openstack_registry is ready on port #{@registry_port}")
|
104
|
+
ensure
|
105
|
+
@registry_config.unlink if @registry_config
|
106
|
+
end
|
107
|
+
|
108
|
+
def stop
|
109
|
+
if @registry_pid && process_exists?(@registry_pid)
|
110
|
+
Process.kill("INT", @registry_pid)
|
111
|
+
Process.waitpid(@registry_pid)
|
112
|
+
end
|
113
|
+
|
114
|
+
return unless @registry_db_url
|
115
|
+
|
116
|
+
Sequel.connect(@registry_db_url) do |db|
|
117
|
+
@deployments["openstack_servers"] = db[:openstack_servers].map {|row| row}
|
118
|
+
end
|
119
|
+
|
120
|
+
save_state
|
121
|
+
@registry_db.unlink if @registry_db
|
122
|
+
end
|
123
|
+
|
124
|
+
def wait_until_agent_ready
|
125
|
+
tunnel(@registry_port)
|
126
|
+
super
|
127
|
+
end
|
128
|
+
|
129
|
+
def discover_bosh_ip
|
130
|
+
if exists?
|
131
|
+
server = cloud.openstack.servers.get(state.vm_cid)
|
132
|
+
ip = server.public_ip_address
|
133
|
+
ip = server.private_ip_address if ip.nil? || ip.empty?
|
134
|
+
if ip.nil? || ip.empty?
|
135
|
+
raise "Unable to discover bosh ip"
|
136
|
+
else
|
137
|
+
if ip["addr"] != Config.bosh_ip
|
138
|
+
Config.bosh_ip = ip["addr"]
|
139
|
+
logger.info("discovered bosh ip=#{Config.bosh_ip}")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
super
|
145
|
+
end
|
146
|
+
|
147
|
+
def service_ip
|
148
|
+
ip = cloud.openstack.servers.get(state.vm_cid).private_ip_address
|
149
|
+
ip["addr"] unless ip.nil? || ip.empty?
|
150
|
+
end
|
151
|
+
|
152
|
+
# @return [Integer] size in MiB
|
153
|
+
def disk_size(cid)
|
154
|
+
# OpenStack stores disk size in GiB but we work with MiB
|
155
|
+
cloud.openstack.volumes.get(cid).size * 1024
|
156
|
+
end
|
157
|
+
|
158
|
+
def persistent_disk_changed?
|
159
|
+
# since OpenStack stores disk size in GiB and we use MiB there
|
160
|
+
# is a risk of conversion errors which lead to an unnecessary
|
161
|
+
# disk migration, so we need to do a double conversion
|
162
|
+
# here to avoid that
|
163
|
+
requested = (Config.resources['persistent_disk'] / 1024.0).ceil * 1024
|
164
|
+
requested != disk_size(state.disk_cid)
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
# TODO this code is similar to has_stemcell_copy?
|
170
|
+
# move the two into bosh_common later
|
171
|
+
def has_openstack_registry?(path=ENV['PATH'])
|
172
|
+
path.split(":").each do |dir|
|
173
|
+
return true if File.exist?(File.join(dir, "openstack_registry"))
|
174
|
+
end
|
175
|
+
false
|
176
|
+
end
|
177
|
+
|
178
|
+
def migrate(db)
|
179
|
+
db.create_table :openstack_servers do
|
180
|
+
primary_key :id
|
181
|
+
column :server_id, :text, :unique => true, :null => false
|
182
|
+
column :settings, :text, :null => false
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def process_exists?(pid)
|
187
|
+
begin
|
188
|
+
Process.kill(0, pid)
|
189
|
+
rescue Errno::ESRCH
|
190
|
+
false
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def socket_readable?(ip, port)
|
195
|
+
socket = TCPSocket.new(ip, port)
|
196
|
+
if IO.select([socket], nil, nil, 5)
|
197
|
+
logger.debug("tcp socket #{ip}:#{port} is readable")
|
198
|
+
yield
|
199
|
+
true
|
200
|
+
else
|
201
|
+
false
|
202
|
+
end
|
203
|
+
rescue SocketError => e
|
204
|
+
logger.debug("tcp socket #{ip}:#{port} SocketError: #{e.inspect}")
|
205
|
+
sleep 1
|
206
|
+
false
|
207
|
+
rescue SystemCallError => e
|
208
|
+
logger.debug("tcp socket #{ip}:#{port} SystemCallError: #{e.inspect}")
|
209
|
+
sleep 1
|
210
|
+
false
|
211
|
+
ensure
|
212
|
+
socket.close if socket
|
213
|
+
end
|
214
|
+
|
215
|
+
def tunnel(port)
|
216
|
+
return if @session
|
217
|
+
|
218
|
+
ip = discover_bosh_ip
|
219
|
+
|
220
|
+
loop until socket_readable?(ip, @ssh_port) do
|
221
|
+
#sshd is up, sleep while host keys are generated
|
222
|
+
sleep @ssh_wait
|
223
|
+
end
|
224
|
+
|
225
|
+
lo = "127.0.0.1"
|
226
|
+
cmd = "ssh -R #{port}:#{lo}:#{port} #{@ssh_user}@#{ip}"
|
227
|
+
|
228
|
+
logger.info("Preparing for ssh tunnel: #{cmd}")
|
229
|
+
loop do
|
230
|
+
begin
|
231
|
+
@session = Net::SSH.start(ip, @ssh_user, :keys => [@ssh_key],
|
232
|
+
:paranoid => false)
|
233
|
+
logger.debug("ssh #{@ssh_user}@#{ip}: ESTABLISHED")
|
234
|
+
break
|
235
|
+
rescue => e
|
236
|
+
logger.debug("ssh start #{@ssh_user}@#{ip} failed: #{e.inspect}")
|
237
|
+
sleep 1
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
@session.forward.remote(port, lo, port)
|
242
|
+
logger.info("`#{cmd}` started: OK")
|
243
|
+
|
244
|
+
Thread.new do
|
245
|
+
begin
|
246
|
+
@session.loop { true }
|
247
|
+
rescue IOError => e
|
248
|
+
logger.debug("`#{cmd}` terminated: #{e.inspect}")
|
249
|
+
@session = nil
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
@@ -350,13 +350,17 @@ module Bosh::Deployer
|
|
350
350
|
properties["director"]["name"] = Config.name
|
351
351
|
end
|
352
352
|
|
353
|
-
|
354
|
-
|
355
|
-
|
353
|
+
# blobstore and nats need to use an elastic IP (if available),
|
354
|
+
# as when the micro bosh instance is re-created during a
|
355
|
+
# deployment, it might get a new private IP
|
356
|
+
%w{blobstore nats}.each do |service|
|
357
|
+
update_agent_service_address(properties, service, bosh_ip)
|
358
|
+
end
|
356
359
|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
+
services = %w{postgres director redis blobstore nats aws_registry
|
361
|
+
openstack_registry}
|
362
|
+
services.each do |service|
|
363
|
+
update_service_address(properties, service, service_ip)
|
360
364
|
end
|
361
365
|
|
362
366
|
spec
|
@@ -382,6 +386,28 @@ module Bosh::Deployer
|
|
382
386
|
|
383
387
|
private
|
384
388
|
|
389
|
+
# update the agent service section from the contents of the apply_spec
|
390
|
+
def update_agent_service_address(properties, service, address)
|
391
|
+
if Config.agent_properties
|
392
|
+
agent = properties["agent"] ||= {}
|
393
|
+
svc = agent[service] ||= {}
|
394
|
+
svc["address"] = address
|
395
|
+
|
396
|
+
if override = Config.agent_properties[service]
|
397
|
+
svc.merge!(override)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
def update_service_address(properties, service, address)
|
403
|
+
return unless properties[service]
|
404
|
+
properties[service]["address"] = address
|
405
|
+
|
406
|
+
if override = Config.spec_properties[service]
|
407
|
+
properties[service].merge!(override)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
385
411
|
def bosh_ip
|
386
412
|
Config.bosh_ip
|
387
413
|
end
|
data/lib/deployer/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bosh_deployer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bosh_common
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.5.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
29
|
+
version: 0.5.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: bosh_cpi
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.6.
|
69
|
+
version: 0.6.2
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,55 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 0.6.
|
77
|
+
version: 0.6.2
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bosh_aws_registry
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.2.2
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.2.2
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: bosh_openstack_cpi
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.0.2
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.0.2
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: bosh_openstack_registry
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.0.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.0.1
|
78
126
|
- !ruby/object:Gem::Dependency
|
79
127
|
name: agent_client
|
80
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,6 +162,7 @@ extensions: []
|
|
114
162
|
extra_rdoc_files: []
|
115
163
|
files:
|
116
164
|
- config/aws_defaults.yml
|
165
|
+
- config/openstack_defaults.yml
|
117
166
|
- config/vsphere_defaults.yml
|
118
167
|
- lib/bosh/cli/commands/micro.rb
|
119
168
|
- lib/deployer.rb
|
@@ -122,6 +171,7 @@ files:
|
|
122
171
|
- lib/deployer/helpers.rb
|
123
172
|
- lib/deployer/instance_manager.rb
|
124
173
|
- lib/deployer/instance_manager/aws.rb
|
174
|
+
- lib/deployer/instance_manager/openstack.rb
|
125
175
|
- lib/deployer/instance_manager/vsphere.rb
|
126
176
|
- lib/deployer/models/instance.rb
|
127
177
|
- lib/deployer/version.rb
|
@@ -142,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
192
|
version: '0'
|
143
193
|
segments:
|
144
194
|
- 0
|
145
|
-
hash: -
|
195
|
+
hash: -2032018102027977195
|
146
196
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
197
|
none: false
|
148
198
|
requirements:
|
@@ -151,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
201
|
version: '0'
|
152
202
|
segments:
|
153
203
|
- 0
|
154
|
-
hash: -
|
204
|
+
hash: -2032018102027977195
|
155
205
|
requirements: []
|
156
206
|
rubyforge_project:
|
157
207
|
rubygems_version: 1.8.24
|