bosh-stemcell 1.5.0.pre.1113

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.
Files changed (50) hide show
  1. data/.rspec +3 -0
  2. data/README.md +104 -0
  3. data/Vagrantfile +37 -0
  4. data/bosh-stemcell.gemspec +28 -0
  5. data/lib/bosh/stemcell.rb +4 -0
  6. data/lib/bosh/stemcell/archive.rb +59 -0
  7. data/lib/bosh/stemcell/archive_filename.rb +29 -0
  8. data/lib/bosh/stemcell/aws/ami.rb +58 -0
  9. data/lib/bosh/stemcell/aws/light_stemcell.rb +44 -0
  10. data/lib/bosh/stemcell/aws/region.rb +15 -0
  11. data/lib/bosh/stemcell/builder_command.rb +174 -0
  12. data/lib/bosh/stemcell/builder_options.rb +85 -0
  13. data/lib/bosh/stemcell/disk_image.rb +61 -0
  14. data/lib/bosh/stemcell/infrastructure.rb +49 -0
  15. data/lib/bosh/stemcell/operating_system.rb +31 -0
  16. data/lib/bosh/stemcell/stage_collection.rb +154 -0
  17. data/lib/bosh/stemcell/stage_runner.rb +53 -0
  18. data/lib/bosh/stemcell/version.rb +5 -0
  19. data/lib/monkeypatch/serverspec/backend/exec.rb +86 -0
  20. data/spec/assets/fake-stemcell-aws.tgz +0 -0
  21. data/spec/assets/fake-stemcell-vsphere.tgz +0 -0
  22. data/spec/assets/light-fake-stemcell-aws.tgz +0 -0
  23. data/spec/bosh/monkeypatch/serverspec/backend/exec_spec.rb +46 -0
  24. data/spec/bosh/stemcell/archive_filename_spec.rb +42 -0
  25. data/spec/bosh/stemcell/archive_spec.rb +98 -0
  26. data/spec/bosh/stemcell/aws/ami_spec.rb +30 -0
  27. data/spec/bosh/stemcell/aws/light_stemcell_spec.rb +94 -0
  28. data/spec/bosh/stemcell/aws/region_spec.rb +12 -0
  29. data/spec/bosh/stemcell/builder_command_spec.rb +241 -0
  30. data/spec/bosh/stemcell/builder_options_spec.rb +201 -0
  31. data/spec/bosh/stemcell/disk_image_spec.rb +163 -0
  32. data/spec/bosh/stemcell/infrastructure_spec.rb +66 -0
  33. data/spec/bosh/stemcell/operating_system_spec.rb +47 -0
  34. data/spec/bosh/stemcell/stage_collection_spec.rb +213 -0
  35. data/spec/bosh/stemcell/stage_runner_spec.rb +141 -0
  36. data/spec/bosh/stemcell/version_spec.rb +12 -0
  37. data/spec/bosh/stemcell_spec.rb +6 -0
  38. data/spec/spec_helper.rb +6 -0
  39. data/spec/stemcells/aws_spec.rb +9 -0
  40. data/spec/stemcells/centos_spec.rb +131 -0
  41. data/spec/stemcells/openstack_spec.rb +9 -0
  42. data/spec/stemcells/ubuntu_spec.rb +143 -0
  43. data/spec/stemcells/vsphere_spec.rb +9 -0
  44. data/spec/support/rspec_fire.rb +9 -0
  45. data/spec/support/serverspec.rb +4 -0
  46. data/spec/support/spec_assets.rb +11 -0
  47. data/spec/support/stemcell_image.rb +26 -0
  48. data/spec/support/stemcell_shared_examples.rb +43 -0
  49. data/spec/support/stub_env.rb +5 -0
  50. metadata +236 -0
@@ -0,0 +1,85 @@
1
+ require 'rbconfig'
2
+ require 'bosh_agent/version'
3
+ require 'bosh/stemcell/archive_filename'
4
+
5
+ module Bosh::Stemcell
6
+ class BuilderOptions
7
+ def initialize(env, options)
8
+ @environment = env
9
+ @infrastructure = options.fetch(:infrastructure)
10
+ @operating_system = options.fetch(:operating_system)
11
+
12
+ @stemcell_version = options.fetch(:stemcell_version)
13
+ @image_create_disk_size = options.fetch(:disk_size, infrastructure.default_disk_size)
14
+ @bosh_micro_release_tgz_path = options.fetch(:tarball)
15
+ end
16
+
17
+ def default
18
+ {
19
+ 'stemcell_name' => "bosh-#{infrastructure.name}-#{infrastructure.hypervisor}-#{operating_system.name}",
20
+ 'stemcell_tgz' => archive_filename.to_s,
21
+ 'stemcell_image_name' => stemcell_image_name,
22
+ 'stemcell_version' => stemcell_version,
23
+ 'stemcell_hypervisor' => infrastructure.hypervisor,
24
+ 'stemcell_infrastructure' => infrastructure.name,
25
+ 'stemcell_operating_system' => operating_system.name,
26
+ 'bosh_protocol_version' => Bosh::Agent::BOSH_PROTOCOL,
27
+ 'ruby_bin' => ruby_bin,
28
+ 'bosh_release_src_dir' => File.join(source_root, 'release/src/bosh'),
29
+ 'bosh_agent_src_dir' => File.join(source_root, 'bosh_agent'),
30
+ 'image_create_disk_size' => image_create_disk_size
31
+ }.merge(bosh_micro_options).merge(environment_variables).merge(vsphere_options)
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader(
37
+ :environment,
38
+ :infrastructure,
39
+ :operating_system,
40
+ :stemcell_version,
41
+ :image_create_disk_size,
42
+ :bosh_micro_release_tgz_path
43
+ )
44
+
45
+ def vsphere_options
46
+ if infrastructure.name == 'vsphere'
47
+ { 'image_vsphere_ovf_ovftool_path' => environment['OVFTOOL'] }
48
+ else
49
+ {}
50
+ end
51
+ end
52
+
53
+ def environment_variables
54
+ {
55
+ 'UBUNTU_ISO' => environment['UBUNTU_ISO'],
56
+ 'UBUNTU_MIRROR' => environment['UBUNTU_MIRROR'],
57
+ }
58
+ end
59
+
60
+ def bosh_micro_options
61
+ {
62
+ 'bosh_micro_enabled' => 'yes',
63
+ 'bosh_micro_package_compiler_path' => File.join(source_root, 'bosh-release'),
64
+ 'bosh_micro_manifest_yml_path' => File.join(source_root, 'release', 'micro', "#{infrastructure.name}.yml"),
65
+ 'bosh_micro_release_tgz_path' => bosh_micro_release_tgz_path,
66
+ }
67
+ end
68
+
69
+ def archive_filename
70
+ ArchiveFilename.new(stemcell_version, infrastructure, operating_system, 'bosh-stemcell', false)
71
+ end
72
+
73
+ def stemcell_image_name
74
+ "#{infrastructure.name}-#{infrastructure.hypervisor}-#{operating_system.name}.raw"
75
+ end
76
+
77
+ def ruby_bin
78
+ environment['RUBY_BIN'] || File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
79
+ end
80
+
81
+ def source_root
82
+ File.expand_path('../../../../..', __FILE__)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,61 @@
1
+ require 'bosh/core/shell'
2
+ require 'tmpdir'
3
+
4
+ module Bosh::Stemcell
5
+ class DiskImage
6
+
7
+ attr_reader :image_mount_point
8
+
9
+ def initialize(options)
10
+ @image_file_path = options.fetch(:image_file_path)
11
+ @image_mount_point = options.fetch(:image_mount_point, Dir.mktmpdir)
12
+ @verbose = options.fetch(:verbose, false)
13
+ @shell = Bosh::Core::Shell.new
14
+ end
15
+
16
+ def mount
17
+ device_path = stemcell_loopback_device_name
18
+ mount_command = "sudo mount #{device_path} #{image_mount_point}"
19
+ shell.run(mount_command, output_command: verbose)
20
+ rescue => e
21
+ raise e unless e.message.include?(mount_command)
22
+
23
+ sleep 0.5
24
+ shell.run(mount_command, output_command: verbose)
25
+ end
26
+
27
+ def unmount
28
+ shell.run("sudo umount #{image_mount_point}", output_command: verbose)
29
+ ensure
30
+ unmap_image
31
+ end
32
+
33
+ def while_mounted
34
+ mount
35
+ yield self
36
+ ensure
37
+ unmount
38
+ end
39
+
40
+ private
41
+
42
+ attr_reader :image_file_path, :verbose, :shell, :device
43
+
44
+ def stemcell_loopback_device_name
45
+ split_output = map_image.split(' ')
46
+ device_name = split_output[2]
47
+
48
+ File.join('/dev/mapper', device_name)
49
+ end
50
+
51
+ def map_image
52
+ @device = shell.run("sudo losetup --show --find #{image_file_path}", output_command: verbose)
53
+ shell.run("sudo kpartx -av #{device}", output_command: verbose)
54
+ end
55
+
56
+ def unmap_image
57
+ shell.run("sudo kpartx -dv #{device}", output_command: verbose)
58
+ shell.run("sudo losetup -dv #{device}", output_command: verbose)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,49 @@
1
+ module Bosh::Stemcell
2
+ module Infrastructure
3
+ def self.for(name)
4
+ case name
5
+ when 'openstack'
6
+ OpenStack.new
7
+ when 'aws'
8
+ Aws.new
9
+ when 'vsphere'
10
+ Vsphere.new
11
+ else
12
+ raise ArgumentError.new("invalid infrastructure: #{name}")
13
+ end
14
+ end
15
+
16
+ class Base
17
+ attr_reader :name, :hypervisor, :default_disk_size
18
+
19
+ def initialize(options = {})
20
+ @name = options.fetch(:name)
21
+ @supports_light_stemcell = options.fetch(:supports_light_stemcell, false)
22
+ @hypervisor = options.fetch(:hypervisor)
23
+ @default_disk_size = options.fetch(:default_disk_size)
24
+ end
25
+
26
+ def light?
27
+ @supports_light_stemcell
28
+ end
29
+ end
30
+
31
+ class OpenStack < Base
32
+ def initialize
33
+ super(name: 'openstack', hypervisor: 'kvm', default_disk_size: 10240)
34
+ end
35
+ end
36
+
37
+ class Vsphere < Base
38
+ def initialize
39
+ super(name: 'vsphere', hypervisor: 'esxi', default_disk_size: 2048)
40
+ end
41
+ end
42
+
43
+ class Aws < Base
44
+ def initialize
45
+ super(name: 'aws', hypervisor: 'xen', supports_light_stemcell: true, default_disk_size: 2048)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,31 @@
1
+ module Bosh::Stemcell
2
+ module OperatingSystem
3
+ def self.for(operating_system_name)
4
+ case operating_system_name
5
+ when 'centos' then Centos.new
6
+ when 'ubuntu' then Ubuntu.new
7
+ else raise ArgumentError.new("invalid operating system: #{operating_system_name}")
8
+ end
9
+ end
10
+
11
+ class Base
12
+ attr_reader :name
13
+
14
+ def initialize(options = {})
15
+ @name = options.fetch(:name)
16
+ end
17
+ end
18
+
19
+ class Centos < Base
20
+ def initialize
21
+ super(name: 'centos')
22
+ end
23
+ end
24
+
25
+ class Ubuntu < Base
26
+ def initialize
27
+ super(name: 'ubuntu')
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,154 @@
1
+ require 'bosh/stemcell/infrastructure'
2
+ require 'bosh/stemcell/operating_system'
3
+
4
+ module Bosh::Stemcell
5
+ class StageCollection
6
+
7
+ def initialize(options)
8
+ @infrastructure = options.fetch(:infrastructure)
9
+ @operating_system = options.fetch(:operating_system)
10
+ end
11
+
12
+ def operating_system_stages
13
+ case operating_system
14
+ when OperatingSystem::Centos then
15
+ [:base_centos, :base_yum] + hacked_centos_common
16
+ when OperatingSystem::Ubuntu then
17
+ [:base_debootstrap, :base_apt] + common_stages
18
+ end
19
+ end
20
+
21
+ def infrastructure_stages
22
+ case infrastructure
23
+ when Infrastructure::Aws then
24
+ aws_stages
25
+ when Infrastructure::OpenStack then
26
+ openstack_stages
27
+ when Infrastructure::Vsphere then
28
+ operating_system.instance_of?(OperatingSystem::Centos) ? hacked_centos_vsphere : vsphere_stages
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :infrastructure, :operating_system
35
+
36
+ def hacked_centos_common
37
+ [
38
+ # Bosh steps
39
+ :bosh_users,
40
+ :bosh_monit,
41
+ :bosh_ruby,
42
+ :bosh_agent,
43
+ #:bosh_sysstat,
44
+ #:bosh_sysctl,
45
+ #:bosh_ntpdate,
46
+ :bosh_sudoers,
47
+ # Micro BOSH
48
+ :bosh_micro,
49
+ # Install GRUB/kernel/etc
50
+ :system_grub,
51
+ #:system_kernel,
52
+ ]
53
+ end
54
+
55
+ def hacked_centos_vsphere
56
+ [
57
+ #:system_open_vm_tools,
58
+ :system_parameters,
59
+ :bosh_clean,
60
+ #:bosh_harden,
61
+ #:bosh_dpkg_list,
62
+ :image_create,
63
+ :image_install_grub,
64
+ :image_vsphere_vmx,
65
+ :image_vsphere_ovf,
66
+ :image_vsphere_prepare_stemcell,
67
+ :stemcell
68
+ ]
69
+ end
70
+
71
+ def common_stages
72
+ [
73
+ # Bosh steps
74
+ :bosh_users,
75
+ :bosh_monit,
76
+ :bosh_ruby,
77
+ :bosh_agent,
78
+ :bosh_sysstat,
79
+ :bosh_sysctl,
80
+ :bosh_ntpdate,
81
+ :bosh_sudoers,
82
+ # Micro BOSH
83
+ :bosh_micro,
84
+ # Install GRUB/kernel/etc
85
+ :system_grub,
86
+ :system_kernel,
87
+ ]
88
+ end
89
+
90
+ def aws_stages
91
+ [
92
+ # Misc
93
+ :system_aws_network,
94
+ :system_aws_clock,
95
+ :system_aws_modules,
96
+ :system_parameters,
97
+ # Finalisation
98
+ :bosh_clean,
99
+ :bosh_harden,
100
+ :bosh_harden_ssh,
101
+ :bosh_dpkg_list,
102
+ # Image/bootloader
103
+ :image_create,
104
+ :image_install_grub,
105
+ :image_aws_update_grub,
106
+ :image_aws_prepare_stemcell,
107
+ # Final stemcell
108
+ :stemcell
109
+ ]
110
+ end
111
+
112
+ def openstack_stages
113
+ [
114
+ # Misc
115
+ :system_openstack_network,
116
+ :system_openstack_clock,
117
+ :system_openstack_modules,
118
+ :system_parameters,
119
+ # Finalisation,
120
+ :bosh_clean,
121
+ :bosh_harden,
122
+ :bosh_harden_ssh,
123
+ :bosh_dpkg_list,
124
+ # Image/bootloader
125
+ :image_create,
126
+ :image_install_grub,
127
+ :image_openstack_qcow2,
128
+ :image_openstack_prepare_stemcell,
129
+ # Final stemcell
130
+ :stemcell_openstack
131
+ ]
132
+ end
133
+
134
+ def vsphere_stages
135
+ [
136
+ :system_open_vm_tools,
137
+ # Misc
138
+ :system_parameters,
139
+ # Finalisation
140
+ :bosh_clean,
141
+ :bosh_harden,
142
+ :bosh_dpkg_list,
143
+ # Image/bootloader
144
+ :image_create,
145
+ :image_install_grub,
146
+ :image_vsphere_vmx,
147
+ :image_vsphere_ovf,
148
+ :image_vsphere_prepare_stemcell,
149
+ # Final stemcell
150
+ :stemcell
151
+ ]
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,53 @@
1
+ require 'bosh/core/shell'
2
+
3
+ module Bosh::Stemcell
4
+ class StageRunner
5
+ def initialize(options)
6
+ @build_path = options.fetch(:build_path)
7
+ @command_env = options.fetch(:command_env)
8
+ @settings_file = options.fetch(:settings_file)
9
+ @work_path = options.fetch(:work_path)
10
+ end
11
+
12
+ def configure_and_apply(stages)
13
+ configure(stages)
14
+ apply(stages)
15
+ end
16
+
17
+ def configure(stages)
18
+ stages.each do |stage|
19
+ stage_config_script = File.join(build_path, 'stages', stage.to_s, 'config.sh')
20
+
21
+ puts "=== Configuring '#{stage}' stage ==="
22
+ if File.exists?(stage_config_script) && File.executable?(stage_config_script)
23
+ run_sudo_with_command_env("#{stage_config_script} #{settings_file}")
24
+ end
25
+ end
26
+ end
27
+
28
+ def apply(stages)
29
+ work_directory = File.join(work_path, 'work')
30
+
31
+ stages.each do |stage|
32
+ FileUtils.mkdir_p(work_directory)
33
+
34
+ puts "=== Applying '#{stage}' stage ==="
35
+ puts "== Started #{Time.now.strftime('%a %b %e %H:%M:%S %Z %Y')} =="
36
+
37
+ stage_apply_script = File.join(build_path, 'stages', stage.to_s, 'apply.sh')
38
+
39
+ run_sudo_with_command_env("#{stage_apply_script} #{work_directory}")
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :stages, :build_path, :command_env, :settings_file, :work_path
46
+
47
+ def run_sudo_with_command_env(command)
48
+ shell = Bosh::Core::Shell.new
49
+
50
+ shell.run("sudo #{command_env} #{command} 2>&1")
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ module Bosh
2
+ module Stemcell
3
+ VERSION = '1.5.0.pre.1113'
4
+ end
5
+ end