stemcell_builder 1.0.8
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/.gitignore +20 -0
- data/.rvmrc +1 -0
- data/.travis.yml +1 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +123 -0
- data/Rakefile +10 -0
- data/assets/box.ovf.erb +81 -0
- data/assets/stemcell_mf_schema.yaml +30 -0
- data/bin/stemcell_builder +138 -0
- data/lib/stemcell.rb +3 -0
- data/lib/stemcell/builder.rb +445 -0
- data/lib/stemcell/builders/centos.rb +33 -0
- data/lib/stemcell/builders/redhat.rb +34 -0
- data/lib/stemcell/builders/ubuntu.rb +36 -0
- data/lib/stemcell/const.rb +12 -0
- data/lib/stemcell/version.rb +10 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/stemcell_builder/builder_spec.rb +186 -0
- data/spec/stemcell_builder/centos_spec.rb +39 -0
- data/spec/stemcell_builder/redhat_spec.rb +53 -0
- data/spec/stemcell_builder/ubuntu_spec.rb +38 -0
- data/stemcell_builder.gemspec +42 -0
- data/templates/centos/_60-bosh-sysctl.conf +5 -0
- data/templates/centos/_empty_state.yml +9 -0
- data/templates/centos/_monitrc +8 -0
- data/templates/centos/_ntpdate +10 -0
- data/templates/centos/_runonce +46 -0
- data/templates/centos/_sysstat +18 -0
- data/templates/centos/_variables.sh.erb +31 -0
- data/templates/centos/base.sh +23 -0
- data/templates/centos/bosh_agent.sh +39 -0
- data/templates/centos/cleanup.sh +28 -0
- data/templates/centos/definition.rb.erb +37 -0
- data/templates/centos/harden.sh +8 -0
- data/templates/centos/ks.cfg +43 -0
- data/templates/centos/micro.sh +57 -0
- data/templates/centos/monit.sh +21 -0
- data/templates/centos/postinstall.sh +27 -0
- data/templates/centos/ruby.sh +42 -0
- data/templates/centos/setup-bosh.sh +20 -0
- data/templates/centos/sudo.sh +13 -0
- data/templates/centos/timestamp.sh +15 -0
- data/templates/centos/vmware-tools.sh +17 -0
- data/templates/centos/zerodisk.sh +9 -0
- data/templates/noop/erbtest.txt.erb +1 -0
- data/templates/noop/test.txt +1 -0
- data/templates/redhat/_60-bosh-sysctl.conf +5 -0
- data/templates/redhat/_empty_state.yml +9 -0
- data/templates/redhat/_monitrc +8 -0
- data/templates/redhat/_ntpdate +10 -0
- data/templates/redhat/_runonce +46 -0
- data/templates/redhat/_sysstat +18 -0
- data/templates/redhat/_variables.sh.erb +31 -0
- data/templates/redhat/base.sh +41 -0
- data/templates/redhat/bosh_agent.sh +37 -0
- data/templates/redhat/cleanup.sh +30 -0
- data/templates/redhat/definition.rb.erb +38 -0
- data/templates/redhat/harden.sh +8 -0
- data/templates/redhat/ks.cfg +86 -0
- data/templates/redhat/micro.sh +57 -0
- data/templates/redhat/monit.sh +21 -0
- data/templates/redhat/postinstall.sh +27 -0
- data/templates/redhat/rhnreg.sh.erb +15 -0
- data/templates/redhat/ruby.sh +42 -0
- data/templates/redhat/setup-bosh.sh +20 -0
- data/templates/redhat/sudo.sh +13 -0
- data/templates/redhat/timestamp.sh +15 -0
- data/templates/redhat/vmware-tools.sh +17 -0
- data/templates/redhat/zerodisk.sh +9 -0
- data/templates/ubuntu/_60-bosh-sysctl.conf +5 -0
- data/templates/ubuntu/_empty_state.yml +9 -0
- data/templates/ubuntu/_helpers.sh +40 -0
- data/templates/ubuntu/_monitrc +8 -0
- data/templates/ubuntu/_ntpdate +10 -0
- data/templates/ubuntu/_runonce +46 -0
- data/templates/ubuntu/_sysstat +18 -0
- data/templates/ubuntu/_variables.sh.erb +30 -0
- data/templates/ubuntu/apt-upgrade.sh +19 -0
- data/templates/ubuntu/base-stemcell.sh +95 -0
- data/templates/ubuntu/bosh_agent.sh +39 -0
- data/templates/ubuntu/definition.rb.erb +63 -0
- data/templates/ubuntu/harden.sh +9 -0
- data/templates/ubuntu/micro.sh +57 -0
- data/templates/ubuntu/monit.sh +22 -0
- data/templates/ubuntu/network-cleanup.sh +17 -0
- data/templates/ubuntu/postinstall.sh +45 -0
- data/templates/ubuntu/preseed.cfg +87 -0
- data/templates/ubuntu/ruby.sh +54 -0
- data/templates/ubuntu/setup-bosh.sh +14 -0
- data/templates/ubuntu/sudo.sh +14 -0
- data/templates/ubuntu/timestamp.sh +13 -0
- data/templates/ubuntu/vmware-tools.sh +22 -0
- data/templates/ubuntu/zero-disk.sh +10 -0
- metadata +375 -0
data/lib/stemcell.rb
ADDED
@@ -0,0 +1,445 @@
|
|
1
|
+
require 'logger/colors'
|
2
|
+
require 'deep_merge'
|
3
|
+
require 'erb'
|
4
|
+
require 'securerandom'
|
5
|
+
require 'digest/sha1'
|
6
|
+
require 'net/scp'
|
7
|
+
require 'net/ssh'
|
8
|
+
require 'retryable'
|
9
|
+
require 'tmpdir'
|
10
|
+
|
11
|
+
module Bosh::Agent::StemCell
|
12
|
+
|
13
|
+
# This BaseBuilder abstract class represents the base stemcell builder and should be extended by specific stemcell
|
14
|
+
# builders for different distributions
|
15
|
+
class BaseBuilder
|
16
|
+
|
17
|
+
attr_accessor :name, :infrastructure, :architecture
|
18
|
+
attr_accessor :agent_src_path, :agent_version, :bosh_protocol
|
19
|
+
attr_accessor :prefix, :target
|
20
|
+
attr_accessor :iso, :iso_md5, :iso_filename
|
21
|
+
attr_accessor :logger
|
22
|
+
attr_accessor :vm_name
|
23
|
+
|
24
|
+
# Stemcell builders are initialized with a manifest and a set of options. The options provided are merged with the
|
25
|
+
# defaults to allow the end user/developer to specify only the ones that they wish to change and fallback to the defaults.
|
26
|
+
#
|
27
|
+
# The stemcell builder options are as follows
|
28
|
+
#{
|
29
|
+
# :name => 'bosh-stemcell', # Name of the output stemcell
|
30
|
+
# :logger => Logger.new(STDOUT), # The logger instance to use
|
31
|
+
# :target => "bosh-#@type-#@agent_version.tgz", # Target file to generate, by default it will the ./bosh-#@type-#@agent_version.tgz
|
32
|
+
# :infrastructure => 'vsphere', # The target infrastructure, this can be aws||vsphere||openstack
|
33
|
+
# :agent_src_path => './bosh_agent-0.7.0.gem', # The path to the stemcell gem to be installed
|
34
|
+
# :agent_version => '0.7.0', # Agent version
|
35
|
+
# :bosh_protocol => '1', # Bosh protocol version
|
36
|
+
# :architecture => 'x86_64', # The target system architecture
|
37
|
+
# :prefix => `pwd`, # Directory to use as the staging area and where the stemcell will be generated
|
38
|
+
# :iso => nil, # The url from where the builder can download the stemcell
|
39
|
+
# :iso_md5 => nil, # The MD5 hash of the iso
|
40
|
+
# :iso_filename => nil # Optional iso filename to use/search for in the iso folder
|
41
|
+
#}
|
42
|
+
#
|
43
|
+
# The stemcell manifest is as follows
|
44
|
+
#{
|
45
|
+
# :name => @name, # the bosh stemcell name given as a part of the options[:name]
|
46
|
+
# :version => @agent_version, # The agent version
|
47
|
+
# :bosh_protocol => @bosh_protocol,
|
48
|
+
# :cloud_properties => {
|
49
|
+
# :infrastructure => @infrastructure,
|
50
|
+
# :architecture => @architecture
|
51
|
+
# :root_device_name => '/dev/sda1'
|
52
|
+
# }
|
53
|
+
#}
|
54
|
+
def initialize(opts)
|
55
|
+
initialize_common(opts)
|
56
|
+
initialize_micro(opts) if micro?
|
57
|
+
sanity_check
|
58
|
+
end
|
59
|
+
|
60
|
+
# This method does the setup, this implementation takes care of copying over the
|
61
|
+
# correct definition files, packaging the agent and doing any related setup if needed
|
62
|
+
def setup
|
63
|
+
copy_definitions
|
64
|
+
package_agent
|
65
|
+
end
|
66
|
+
|
67
|
+
def micro?
|
68
|
+
!!@micro
|
69
|
+
end
|
70
|
+
|
71
|
+
# This method creates the vm using the #@name as the virtual machine name
|
72
|
+
# If an existing VM exists with the same name, it will be deleted.
|
73
|
+
def build_vm
|
74
|
+
Dir.chdir(@prefix) do
|
75
|
+
@logger.info "Building vm #@name"
|
76
|
+
nogui_str = gui? ? "" : "--nogui"
|
77
|
+
|
78
|
+
sh "veewee vbox build '#@vm_name' --force --auto #{nogui_str}", {:on_error => "Unable to build vm #@name"}
|
79
|
+
|
80
|
+
# execute pre-shutdown hook
|
81
|
+
pre_shutdown_hook
|
82
|
+
|
83
|
+
@logger.info "Export built VM #@name to #@prefix"
|
84
|
+
sh "vagrant basebox export '#@vm_name' --force", {:on_error => "Unable to export VM #@name: vagrant basebox export '#@vm_name'"}
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
def pre_shutdown_hook
|
90
|
+
if micro?
|
91
|
+
convert_stemcell_to_micro
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def type
|
96
|
+
raise NotImplementedError.new("Type must be initialized")
|
97
|
+
end
|
98
|
+
|
99
|
+
def init_default_iso
|
100
|
+
raise NotImplementedError.new("Default ISO options must be provided")
|
101
|
+
end
|
102
|
+
|
103
|
+
# Packages the stemcell contents (defined as the array of file path argument)
|
104
|
+
def package_stemcell
|
105
|
+
@stemcell_files << generate_image << generate_manifest
|
106
|
+
# package up files
|
107
|
+
package_files
|
108
|
+
end
|
109
|
+
|
110
|
+
def generate_manifest
|
111
|
+
stemcell_mf_path = File.expand_path "stemcell.MF", @prefix
|
112
|
+
File.open(stemcell_mf_path, "w") do |f|
|
113
|
+
f.write(manifest.to_yaml)
|
114
|
+
end
|
115
|
+
stemcell_mf_path
|
116
|
+
end
|
117
|
+
|
118
|
+
def generate_image
|
119
|
+
image_path = File.join @prefix, "image"
|
120
|
+
Dir.chdir(@prefix) do
|
121
|
+
sh("tar -xf #@vm_name.box", {:on_error => "Unable to unpack .box file"})
|
122
|
+
vmdk_filename = Dir.glob("*.vmdk").first
|
123
|
+
Dir.glob("*.ovf") { |ovf_file| fix_virtualbox_ovf(ovf_file, vmdk_filename) } # Fix ovf files
|
124
|
+
sh("tar -czf #{image_path} *.vmdk *.ovf", {:on_error=>"Unable to create image file from ovf and vmdk"})
|
125
|
+
FileUtils.rm [Dir.glob('*.box'), Dir.glob('*.vmdk'), Dir.glob('*.ovf'), "Vagrantfile"]
|
126
|
+
@image_sha1 = Digest::SHA1.file(image_path).hexdigest
|
127
|
+
end
|
128
|
+
image_path
|
129
|
+
end
|
130
|
+
|
131
|
+
# Main execution method that sets up the directory, builds the VM and packages everything into a stemcell
|
132
|
+
def run
|
133
|
+
setup
|
134
|
+
build_vm
|
135
|
+
package_stemcell
|
136
|
+
cleanup
|
137
|
+
@target
|
138
|
+
end
|
139
|
+
|
140
|
+
def cleanup
|
141
|
+
@logger.info "Cleaning up files: #@stemcell_files"
|
142
|
+
FileUtils.rm_rf @stemcell_files
|
143
|
+
end
|
144
|
+
|
145
|
+
def manifest
|
146
|
+
@manifest ||= {
|
147
|
+
"name" => @name,
|
148
|
+
"version" => @agent_version,
|
149
|
+
"bosh_protocol" => @bosh_protocol,
|
150
|
+
"sha1" => @image_sha1,
|
151
|
+
"cloud_properties" => {
|
152
|
+
"root_device_name" => Bosh::Agent::StemCell::DEFAULT_DEVICE_NAME,
|
153
|
+
"infrastructure" => @infrastructure,
|
154
|
+
"architecture" => @architecture
|
155
|
+
}
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
protected
|
160
|
+
|
161
|
+
# Cross-platform way of finding an executable in the $PATH.
|
162
|
+
#
|
163
|
+
# which('ruby') #=> /usr/bin/ruby
|
164
|
+
def which(cmd)
|
165
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
166
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
167
|
+
exts.each do |ext|
|
168
|
+
exe = "#{path}/#{cmd}#{ext}"
|
169
|
+
return exe if File.executable? exe
|
170
|
+
end
|
171
|
+
end
|
172
|
+
return nil
|
173
|
+
end
|
174
|
+
|
175
|
+
# Package all files specified as arguments into a tar. The output file is specified by the :target option
|
176
|
+
def package_files
|
177
|
+
Dir.mktmpdir {|tmpdir|
|
178
|
+
@stemcell_files.flatten.each {|file| FileUtils.cp(file, tmpdir) if file && File.exists?(file) } # only copy files that are not nil
|
179
|
+
Dir.chdir(tmpdir) do
|
180
|
+
@logger.info("Package #@stemcell_files to #@target ...")
|
181
|
+
sh "tar -czf #@target *", {:on_error => "unable to package #@stemcell_files into a stemcell"}
|
182
|
+
end
|
183
|
+
}
|
184
|
+
@target
|
185
|
+
end
|
186
|
+
|
187
|
+
def sanity_check
|
188
|
+
@logger.info "Sanity check"
|
189
|
+
|
190
|
+
@logger.info "Checking ssh_port"
|
191
|
+
raise "Unable to find port for ssh" if @ssh_port.nil?
|
192
|
+
|
193
|
+
@logger.info "Checking target file: #@target..."
|
194
|
+
if File.exists? @target
|
195
|
+
@logger.warn "Target file #@target exists. Moving old file to #@target.bak."
|
196
|
+
FileUtils.mv @target, "#@target.bak"
|
197
|
+
end
|
198
|
+
|
199
|
+
@logger.info "Checking agent source: #@agent_src_path"
|
200
|
+
raise "Agent source #@agent_src_path doens't exist" unless File.exists? @agent_src_path
|
201
|
+
|
202
|
+
@logger.info "Checking definitions dir..."
|
203
|
+
raise "Definition for '#{type}' does not exist at path '#{definition_dir}'" unless Dir.exist? definition_dir
|
204
|
+
|
205
|
+
if micro?
|
206
|
+
@logger.info "Checking micro stemcell conversion files"
|
207
|
+
raise "Micro conversion script does not exist." unless File.exists?(@micro_path)
|
208
|
+
raise "Release manifest path missing" unless File.exists?(@release_manifest)
|
209
|
+
raise "Release tar path missing" unless File.exists?(@release_tar)
|
210
|
+
raise "Package compiler path missing" unless File.exists?(@package_compiler_tar)
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
# @param [Hash] opts Options: :silent => when set to true, it raises :on_error exception
|
216
|
+
# @param [String] cmd Command to execute
|
217
|
+
def sh(cmd, opts={})
|
218
|
+
unless opts[:on_error]
|
219
|
+
opts[:on_error] = "Unable to execute: #{cmd}"
|
220
|
+
end
|
221
|
+
Kernel.system(cmd)
|
222
|
+
exit_status = $?.exitstatus
|
223
|
+
|
224
|
+
# raise error only if silent is not true and exit_status != 0
|
225
|
+
if exit_status != 0
|
226
|
+
raise opts[:on_error] unless opts[:silent]
|
227
|
+
end
|
228
|
+
|
229
|
+
exit_status
|
230
|
+
end
|
231
|
+
|
232
|
+
def ssh_options
|
233
|
+
{
|
234
|
+
:host => '127.0.0.1',
|
235
|
+
:user => 'vcap',
|
236
|
+
:password => 'c1oudc0w',
|
237
|
+
:port => @ssh_port,
|
238
|
+
:paranoid => false,
|
239
|
+
:timeout => 30
|
240
|
+
}
|
241
|
+
end
|
242
|
+
|
243
|
+
def filter_ssh_opts
|
244
|
+
opts = ssh_options.dup
|
245
|
+
opts.delete(:host) if opts.has_key?(:host)
|
246
|
+
opts.delete(:user) if opts.has_key?(:user)
|
247
|
+
opts
|
248
|
+
end
|
249
|
+
|
250
|
+
def ssh_execute(cmd)
|
251
|
+
@logger.info "Executing #{cmd} on VM [ options: #{filter_ssh_opts} ]"
|
252
|
+
Net::SSH.start(ssh_options[:host], ssh_options[:user], filter_ssh_opts) do |ssh|
|
253
|
+
ssh.exec! "echo '#{ssh_options[:password]}' | sudo -S /bin/bash '#{cmd}'" do |ch, stream, line|
|
254
|
+
@logger.info line
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def upload_file(source, destination=nil)
|
260
|
+
destination ||= "/home/#{ssh_options[:user]}"
|
261
|
+
|
262
|
+
retryable(:tries => 5, :sleep => 5) do |retries, exception|
|
263
|
+
@logger.warn "Failed to upload :#{exception}" unless exception.nil?
|
264
|
+
@logger.info "Attempting to upload #{source} to #{destination} [ options: #{filter_ssh_opts} ]"
|
265
|
+
Net::SCP.start(ssh_options[:host], ssh_options[:user], filter_ssh_opts) do |scp|
|
266
|
+
scp.upload!(source, destination) do|ch, name, sent, total|
|
267
|
+
print "\r#{name}: #{(sent.to_f * 100 / total.to_f).to_i}%"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def download_file(source, destination=nil)
|
274
|
+
destination ||= File.join(@prefix, File.basename(source))
|
275
|
+
|
276
|
+
retryable(:tries => 5, :sleep => 5) do |retries, exception|
|
277
|
+
@logger.warn "Failed to download :#{exception}" unless exception.nil?
|
278
|
+
@logger.info "Attempting to download #{source} to #{destination} [ options: #{filter_ssh_opts} ]"
|
279
|
+
Net::SCP.start(ssh_options[:host], ssh_options[:user], filter_ssh_opts) do |scp|
|
280
|
+
scp.download!(source, destination) do|ch, name, sent, total|
|
281
|
+
print "\r#{name}: #{(sent.to_f * 100 / total.to_f).to_i}%"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
@logger.warn "Unable to download #{source}" unless File.exists?(destination)
|
286
|
+
end
|
287
|
+
|
288
|
+
private
|
289
|
+
|
290
|
+
def get_free_port
|
291
|
+
port = nil
|
292
|
+
begin
|
293
|
+
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
294
|
+
socket.bind(Addrinfo.tcp("127.0.0.1", 0))
|
295
|
+
port = socket.local_address.ip_port
|
296
|
+
ensure
|
297
|
+
socket.close
|
298
|
+
end
|
299
|
+
port
|
300
|
+
end
|
301
|
+
|
302
|
+
# HACK: This is a compatibility hack for virtualbox-esx compatibility
|
303
|
+
def fix_virtualbox_ovf(filepath, vmdk_filename="box-disk1.vmdk")
|
304
|
+
@logger.info "Generating ovf file for virtual machine"
|
305
|
+
@vmdk_filename = vmdk_filename
|
306
|
+
vmware_ovf_erb = File.join(File.dirname(__FILE__), "..", "..", "assets", "box.ovf.erb")
|
307
|
+
compile_erb(vmware_ovf_erb, filepath)
|
308
|
+
end
|
309
|
+
|
310
|
+
# Packages the agent into a bosh_agent gem and copies it over to definition_dest_dir
|
311
|
+
# so that it can be used as a part of the VM building process by veewee (using the definition).
|
312
|
+
def package_agent
|
313
|
+
@logger.info "Packaging Bosh Agent to #{definition_dest_dir}/_bosh_agent.tar"
|
314
|
+
dst = File.join(definition_dest_dir, "_bosh_agent.tar")
|
315
|
+
if File.directory? @agent_src_path
|
316
|
+
@logger.info "Tarring up Bosh Agent"
|
317
|
+
Dir.chdir(@agent_src_path) do
|
318
|
+
sh("tar -cf #{dst} *.gem > /dev/null 2>&1", {:on_error => "Unable to package bosh gems"})
|
319
|
+
end
|
320
|
+
else
|
321
|
+
FileUtils.cp @agent_src_path, dst
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# Copies the veewee definition directory from ../templates/#@type to #@prefix/definitions/#@name
|
326
|
+
def copy_definitions
|
327
|
+
@logger.info "Creating definition dest dir"
|
328
|
+
if Dir.exists? definition_dest_dir
|
329
|
+
@logger.warn "#{definition_dest_dir} already exists, contents will be deleted"
|
330
|
+
FileUtils.rm_rf definition_dest_dir
|
331
|
+
end
|
332
|
+
FileUtils.mkdir_p definition_dest_dir
|
333
|
+
|
334
|
+
@logger.info "Copying definition from #{definition_dir} to #{definition_dest_dir}"
|
335
|
+
FileUtils.cp_r Dir.glob("#{definition_dir}/*"), definition_dest_dir
|
336
|
+
|
337
|
+
# Compile erb files
|
338
|
+
Dir.glob(File.join(definition_dest_dir, '*.erb')) { |erb_file|
|
339
|
+
compile_erb(erb_file) # compile erb
|
340
|
+
FileUtils.rm erb_file # remove original
|
341
|
+
}
|
342
|
+
end
|
343
|
+
|
344
|
+
def definition_dir
|
345
|
+
File.expand_path(@definition_dir ||= File.join(File.dirname(__FILE__), "..", "..", "templates", type))
|
346
|
+
end
|
347
|
+
|
348
|
+
def definition_dest_dir
|
349
|
+
File.expand_path(@definition_dest_dir ||= File.join(@prefix, "definitions", @vm_name))
|
350
|
+
end
|
351
|
+
|
352
|
+
def compile_erb(erb_file, dst_file=nil)
|
353
|
+
new_file_path = dst_file || erb_file.gsub(/\.erb$/,'')
|
354
|
+
@logger.debug "Compiling erb #{erb_file} to #{new_file_path}"
|
355
|
+
|
356
|
+
File.open(new_file_path, "w"){|f|
|
357
|
+
f.write(ERB.new(File.read(File.expand_path(erb_file))).result(binding))
|
358
|
+
}
|
359
|
+
end
|
360
|
+
|
361
|
+
def gui?
|
362
|
+
!!@gui
|
363
|
+
end
|
364
|
+
|
365
|
+
def initialize_common(opts)
|
366
|
+
@logger = opts[:logger] || Logger.new(STDOUT)
|
367
|
+
@logger.level = Logger.const_get(opts[:log_level] || "INFO")
|
368
|
+
@name = opts[:name] || Bosh::Agent::StemCell::DEFAULT_STEMCELL_NAME
|
369
|
+
@vm_name = opts[:name] || SecureRandom.uuid.gsub(/-/,'')
|
370
|
+
@prefix = File.expand_path(opts[:prefix] || Dir.pwd)
|
371
|
+
@infrastructure = opts[:infrastructure] || Bosh::Agent::StemCell::DEFAULT_INFRASTRUCTURE
|
372
|
+
@architecture = opts[:architecture] || Bosh::Agent::StemCell::DEFAULT_ARCHITECTURE
|
373
|
+
@agent_version = opts[:agent_version] || Bosh::Agent::VERSION
|
374
|
+
@bosh_protocol = opts[:agent_protocol] || Bosh::Agent::BOSH_PROTOCOL
|
375
|
+
@agent_src_path = File.expand_path(opts[:agent_src_path] || "./bosh_agent-#{@agent_version}.gem")
|
376
|
+
@target ||= File.join(@prefix, "#@name-#{type}-#@infrastructure-#{@agent_version}.tgz")
|
377
|
+
@iso = opts[:iso]
|
378
|
+
@iso_md5 = opts[:iso_md5]
|
379
|
+
@gui = opts[:gui]
|
380
|
+
@definitions_dir = opts[:definitions_dir]
|
381
|
+
@stemcell_files = [] # List of files to be packaged into the stemcell
|
382
|
+
@micro = opts[:micro]
|
383
|
+
@ssh_port = opts[:ssh_port] || get_free_port()
|
384
|
+
|
385
|
+
if @iso
|
386
|
+
raise "MD5 must be specified is ISO is specified" unless @iso_md5
|
387
|
+
@iso_filename ||= File.basename @iso
|
388
|
+
else
|
389
|
+
init_default_iso
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
def initialize_micro(opts)
|
394
|
+
@logger.info "Initializing micro stemcell artifacts"
|
395
|
+
#@bosh_src_root = opts[:bosh_src_root] || File.expand_path("bosh", @prefix)
|
396
|
+
@release_manifest = opts[:release_manifest] # || default_release_manifest
|
397
|
+
@release_tar = opts[:release_tar]
|
398
|
+
@package_compiler_tar = opts[:package_compiler]
|
399
|
+
@micro_path = opts[:micro_path] || File.join(definition_dir, "micro.sh")
|
400
|
+
|
401
|
+
# This is kind of a hack :(
|
402
|
+
if File.exists?(@package_compiler_tar) && File.directory?(@package_compiler_tar)
|
403
|
+
# Tar up the package
|
404
|
+
tmpdir = Dir.mktmpdir
|
405
|
+
tmp_package_compiler_tar = File.join(tmpdir, "_package_compiler.tar")
|
406
|
+
Dir.chdir(opts[:package_compiler]) do
|
407
|
+
sh "tar -cf #{tmp_package_compiler_tar} *"
|
408
|
+
@package_compiler_tar = tmp_package_compiler_tar
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
end
|
413
|
+
|
414
|
+
def build_all_deps
|
415
|
+
@logger.info "Build all bosh packages with dependencies from source"
|
416
|
+
@logger.info "Execute 'rake all:build_with_deps' in bosh/ directory"
|
417
|
+
end
|
418
|
+
|
419
|
+
def create_release_tarball
|
420
|
+
@logger.info("Copy bosh/release/config/microbosh-dev-template.yml to bosh/release/config/dev.yml")
|
421
|
+
@logger.info("Then execute 'bosh create release --force --with-tarball'")
|
422
|
+
@logger.info("The release tar will be in bosh/release/dev_releases/micro-bosh*.tgz")
|
423
|
+
@logger.info("The release manifest is at bosh/release/micro/vsphere.yml")
|
424
|
+
end
|
425
|
+
|
426
|
+
def convert_stemcell_to_micro
|
427
|
+
# SCP upload _release.tgz, _package_compiler.tar, _release.yml, micro.sh
|
428
|
+
upload_file @package_compiler_tar, "/home/vcap/_package_compiler.tar"
|
429
|
+
upload_file @release_tar, "/home/vcap/_release.tgz"
|
430
|
+
upload_file @release_manifest, "/home/vcap/_release.yml"
|
431
|
+
upload_file @micro_path, "/home/vcap/micro.sh"
|
432
|
+
# SSH execute micro.sh
|
433
|
+
@logger.info ssh_execute("./micro.sh")
|
434
|
+
|
435
|
+
# SCP download apply.spec
|
436
|
+
download_file "/var/vcap/micro/apply_spec.yml"
|
437
|
+
@stemcell_files << File.join(@prefix, "apply_spec.yml")
|
438
|
+
end
|
439
|
+
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
require 'stemcell/builders/ubuntu'
|
444
|
+
require 'stemcell/builders/redhat'
|
445
|
+
require 'stemcell/builders/centos'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'stemcell/builder'
|
2
|
+
|
3
|
+
module Bosh::Agent::StemCell
|
4
|
+
|
5
|
+
# This is concrete Stemcell builder for creating a Centos stemcell
|
6
|
+
# It creates a CentOS-6.3. The options passed are merged with
|
7
|
+
# {
|
8
|
+
# :type => 'centos',
|
9
|
+
# :iso => 'http://www.mirrorservice.org/sites/mirror.centos.org/6.3/isos/x86_64/CentOS-6.3-x86_64-minimal.iso',
|
10
|
+
# :iso_md5 => '087713752fa88c03a5e8471c661ad1a2',
|
11
|
+
# :iso_filename => 'CentOS-6.3-x86_64-minimal.iso'
|
12
|
+
# }
|
13
|
+
class CentosBuilder < BaseBuilder
|
14
|
+
|
15
|
+
def type
|
16
|
+
"centos"
|
17
|
+
end
|
18
|
+
|
19
|
+
def pre_shutdown_hook
|
20
|
+
super()
|
21
|
+
download_file "/var/vcap/bosh/stemcell_yum_list_installed.out"
|
22
|
+
# add file to the list of files to be packaged
|
23
|
+
@stemcell_files << File.join(@prefix, "stemcell_yum_list_installed.out")
|
24
|
+
end
|
25
|
+
|
26
|
+
def init_default_iso
|
27
|
+
@iso = "http://www.mirrorservice.org/sites/mirror.centos.org/6.3/isos/x86_64/CentOS-6.3-x86_64-minimal.iso"
|
28
|
+
@iso_md5 = "087713752fa88c03a5e8471c661ad1a2"
|
29
|
+
@iso_filename = "CentOS-6.3-x86_64-minimal.iso"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|