bosh-stemcell 1.5.0.pre.1113

Sign up to get free protection for your applications and to get access to all the features.
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,86 @@
1
+ # rubocop:disable all
2
+ # => disabling rubocop to preserve original style
3
+ require 'serverspec'
4
+ require 'pathname'
5
+
6
+ raise "Unexpected Serverspec version #{Serverspec::VERSION}" unless Serverspec::VERSION == '0.7.10'
7
+ module Serverspec::Backend
8
+ class Exec
9
+ # ORIGINAL
10
+ #def run_command(cmd, opts={})
11
+ # cmd = build_command(cmd)
12
+ # cmd = add_pre_command(cmd)
13
+ # stdout = `#{build_command(cmd)} 2>&1`
14
+ # # In ruby 1.9, it is possible to use Open3.capture3, but not in 1.8
15
+ # #stdout, stderr, status = Open3.capture3(cmd)
16
+ #
17
+ # if @example
18
+ # @example.metadata[:command] = cmd
19
+ # @example.metadata[:stdout] = stdout
20
+ # end
21
+ #
22
+ # { :stdout => stdout, :stderr => nil,
23
+ # :exit_status => $?, :exit_signal => nil }
24
+ #end
25
+ #/ORIGINAL
26
+
27
+ def run_command(cmd, opts={})
28
+ cmd = build_command(cmd)
29
+ cmd = add_pre_command(cmd)
30
+ cmd = build_command(cmd)
31
+
32
+ if use_chroot?
33
+ chroot_stdout = `#{chroot_cmd(cmd)} 2>&1`
34
+
35
+ stdout = get_stdout(chroot_stdout)
36
+ exit_status = get_exit_status(chroot_stdout)
37
+ else
38
+ stdout = `#{cmd} 2>&1`
39
+ exit_status = $?
40
+ end
41
+ # In ruby 1.9, it is possible to use Open3.capture3, but not in 1.8
42
+ #stdout, stderr, status = Open3.capture3(cmd)
43
+
44
+ if @example
45
+ @example.metadata[:command] = cmd
46
+ @example.metadata[:stdout] = stdout
47
+ end
48
+
49
+ { :stdout => stdout, :stderr => nil,
50
+ :exit_status => exit_status, :exit_signal => nil }
51
+ end
52
+
53
+ attr_accessor :chroot_dir
54
+
55
+ private
56
+
57
+ def get_stdout(chroot_stdout)
58
+ chroot_stdout.gsub(/#{exit_code_regexp}/, '')
59
+ end
60
+
61
+ def get_exit_status(chroot_stdout)
62
+ chroot_command_exit_status = chroot_stdout.match(/#{exit_code_regexp}/)[1]
63
+ chroot_command_exit_status.to_i
64
+ end
65
+
66
+ def use_chroot?
67
+ chroot_dir
68
+ end
69
+
70
+ def exit_code_token
71
+ 'EXIT_CODE='
72
+ end
73
+
74
+ def exit_code_regexp
75
+ "#{exit_code_token}(\\d+)\s*\n"
76
+ end
77
+
78
+ def chroot_cmd(cmd)
79
+ %Q{
80
+ sudo chroot #{chroot_dir} /bin/bash <<CHROOT_CMD
81
+ #{cmd} 2>&1; echo #{exit_code_token}\\$?
82
+ CHROOT_CMD
83
+ }
84
+ end
85
+ end
86
+ end
Binary file
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module Serverspec::Backend
4
+ describe Exec do
5
+ subject(:exec) { Serverspec::Backend::Exec.instance }
6
+
7
+ describe '#run_command' do
8
+ context 'when #chroot_dir is NOT set' do
9
+ before do
10
+ exec.stub(chroot_dir: nil) # because "include Singleton"
11
+ end
12
+
13
+ it 'runs the provided command as expected' do
14
+ exec.should_receive(:`).with('echo "FOO" 2>&1')
15
+
16
+ exec.run_command('echo "FOO"')
17
+ end
18
+ end
19
+
20
+ context 'when #chroot_dir is set' do
21
+ before do
22
+ exec.stub(chroot_dir: '/path/to/chroot') # because "include Singleton"
23
+ end
24
+
25
+ it 'runs the provided command within the chroot' do
26
+ chroot_command = %Q{
27
+ sudo chroot /path/to/chroot /bin/bash <<CHROOT_CMD
28
+ echo "FOO" 2>&1; echo EXIT_CODE=\\$?
29
+ CHROOT_CMD
30
+ 2>&1}
31
+ exec.should_receive(:`).with(chroot_command).and_return("FOO\nEXIT_CODE=0\n")
32
+
33
+ exec.run_command('echo "FOO"')
34
+ end
35
+
36
+ it 'extracts the exit code returned from within the chroot into an Integer' do
37
+ exec.stub(:` => "ATTENTION\nDO NOT CARE\nEXIT_CODE=8675309\n")
38
+
39
+ result = exec.run_command('do_not_care')
40
+
41
+ expect(result[:exit_status]).to eq(867_5309)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ require 'bosh/stemcell/archive_filename'
4
+ require 'bosh/stemcell/infrastructure'
5
+ require 'bosh/stemcell/operating_system'
6
+
7
+ module Bosh::Stemcell
8
+ describe ArchiveFilename do
9
+ let(:version) { '007' }
10
+ let(:infrastructure) do
11
+ instance_double('Bosh::Stemcell::Infrastructure::Base',
12
+ name: 'INFRASTRUCTURE',
13
+ hypervisor: 'HYPERVISOR')
14
+ end
15
+ let(:operating_system) do
16
+ instance_double('Bosh::Stemcell::OperatingSystem::Base',
17
+ name: 'OPERATING_SYSTEM')
18
+ end
19
+
20
+ subject(:archive_filename) do
21
+ ArchiveFilename.new(version, infrastructure, operating_system, 'FAKE_NAME', light)
22
+ end
23
+
24
+ describe '#to_s' do
25
+ context 'when stemcell is NOT light' do
26
+ let(:light) { false }
27
+
28
+ it 'includes name, version, infrastructure name, infrastructure hypervisor' do
29
+ expect(archive_filename.to_s).to eq ('FAKE_NAME-007-INFRASTRUCTURE-HYPERVISOR-OPERATING_SYSTEM.tgz')
30
+ end
31
+ end
32
+
33
+ context 'when stemcell is light' do
34
+ let(:light) { true }
35
+
36
+ it 'prefixes the name with "light-"' do
37
+ expect(archive_filename.to_s).to eq ('light-FAKE_NAME-007-INFRASTRUCTURE-HYPERVISOR-OPERATING_SYSTEM.tgz')
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+ require 'bosh/stemcell/archive'
3
+
4
+ module Bosh::Stemcell
5
+ describe Archive do
6
+ let(:stemcell_path) { spec_asset('fake-stemcell-aws.tgz') }
7
+
8
+ subject { Archive.new(stemcell_path) }
9
+
10
+ describe '#initialize' do
11
+ it 'errors if path does not exist' do
12
+ expect { Archive.new('/not/found/stemcell.tgz') }.to raise_error "Cannot find file `/not/found/stemcell.tgz'"
13
+ end
14
+ end
15
+
16
+ describe '#manifest' do
17
+ it 'has a manifest' do
18
+ expect(subject.manifest).to be_a Hash
19
+ end
20
+ end
21
+
22
+ describe '#name' do
23
+ it 'has a name' do
24
+ expect(subject.name).to eq 'fake-stemcell'
25
+ end
26
+ end
27
+
28
+ describe '#infrastructure' do
29
+ it 'has an infrastructure' do
30
+ expect(subject.infrastructure).to eq 'aws'
31
+ end
32
+ end
33
+
34
+ describe '#path' do
35
+ it 'has a path' do
36
+ expect(subject.path).to eq(stemcell_path)
37
+ end
38
+ end
39
+
40
+ describe '#version' do
41
+ it 'has a version' do
42
+ expect(subject.version).to eq('007')
43
+ end
44
+ end
45
+
46
+ describe '#light?' do
47
+ context 'when infrastructure is "aws"' do
48
+ context 'when there is not an "ami" key in the "cloud_properties" section of the manifest' do
49
+ it { should_not be_light }
50
+ end
51
+
52
+ context 'when there is an "ami" key in the "cloud_properties" section of the manifest' do
53
+ let(:stemcell_path) { spec_asset('light-fake-stemcell-aws.tgz') }
54
+
55
+ it { should be_light }
56
+ end
57
+ end
58
+
59
+ context 'when infrastructure is anything but "aws"' do
60
+ let(:stemcell_path) { spec_asset('fake-stemcell-vsphere.tgz') }
61
+
62
+ it { should_not be_light }
63
+ end
64
+ end
65
+
66
+ describe '#ami_id' do
67
+ context 'when infrastructure is "aws"' do
68
+ context 'when there is not an "ami" key in the "cloud_properties" section of the manifest' do
69
+ its(:ami_id) { should be_nil }
70
+ end
71
+
72
+ context 'when there is an "ami" key in the "cloud_properties" section of the manifest' do
73
+ let(:stemcell_path) { spec_asset('light-fake-stemcell-aws.tgz') }
74
+
75
+ its(:ami_id) { should eq('ami-FAKE_AMI_KEY') }
76
+ end
77
+ end
78
+
79
+ context 'when infrastructure is anything but "aws"' do
80
+ let(:stemcell_path) { spec_asset('fake-stemcell-vsphere.tgz') }
81
+
82
+ its(:ami_id) { should be_nil }
83
+ end
84
+ end
85
+
86
+ describe '#extract' do
87
+ it 'extracts stemcell' do
88
+ Rake::FileUtilsExt.should_receive(:sh).with(/tar xzf .*#{stemcell_path} --directory/)
89
+ subject.extract {}
90
+ end
91
+
92
+ it 'extracts stemcell and excludes files' do
93
+ Rake::FileUtilsExt.should_receive(:sh).with(/tar xzf .*#{stemcell_path} --directory .* --exclude=image/)
94
+ subject.extract(exclude: 'image') {}
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'bosh/stemcell/aws/ami'
3
+
4
+ module Bosh::Stemcell::Aws
5
+ describe Ami do
6
+ let(:stemcell) do
7
+ stemcell = double('Bosh::Dev::Stemcell')
8
+ stemcell_manifest = { 'cloud_properties' => { 'ami' => '' } }
9
+ stemcell.stub(:extract).and_yield('/foo/bar', stemcell_manifest)
10
+ stemcell
11
+ end
12
+
13
+ subject(:ami) do
14
+ Ami.new(stemcell, instance_double('Bosh::Stemcell::Aws::Region', name: 'fake-region'))
15
+ end
16
+
17
+ before do
18
+ Logger.stub(:new)
19
+ end
20
+
21
+ describe 'publish' do
22
+ it 'creates a new ami' do
23
+ provider = instance_double('Bosh::AwsCloud::Cloud', create_stemcell: 'fake-ami-id').as_null_object
24
+ Bosh::Clouds::Provider.stub(create: provider)
25
+
26
+ expect(ami.publish).to eq('fake-ami-id')
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+ require 'bosh/stemcell/aws/light_stemcell'
3
+ require 'bosh/stemcell/archive'
4
+
5
+ module Bosh::Stemcell
6
+ module Aws
7
+ describe LightStemcell do
8
+ let(:stemcell) do
9
+ Archive.new(spec_asset('fake-stemcell-aws.tgz'))
10
+ end
11
+
12
+ subject(:light_stemcell) do
13
+ LightStemcell.new(stemcell)
14
+ end
15
+
16
+ its(:path) { should eq(spec_asset('light-fake-stemcell-aws.tgz')) }
17
+
18
+ describe '#write_archive' do
19
+ let(:region) do
20
+ instance_double('Bosh::Stemcell::Aws::Region', name: 'fake-region')
21
+ end
22
+
23
+ let(:ami) do
24
+ instance_double('Bosh::Stemcell::Aws::Ami', publish: 'fake-ami-id')
25
+ end
26
+
27
+ let(:stemcell) do
28
+ Archive.new(spec_asset('fake-stemcell-aws.tgz'))
29
+ end
30
+
31
+ subject(:light_stemcell) do
32
+ LightStemcell.new(stemcell)
33
+ end
34
+
35
+ before do
36
+ Region.stub(new: region)
37
+ Ami.stub(:new).with(stemcell, region).and_return(ami)
38
+ Rake::FileUtilsExt.stub(:sh)
39
+ FileUtils.stub(:touch)
40
+ end
41
+
42
+ it 'creates an ami from the stemcell' do
43
+ ami.should_receive(:publish)
44
+
45
+ light_stemcell.write_archive
46
+ end
47
+
48
+ it 'creates a new tgz' do
49
+ Rake::FileUtilsExt.should_receive(:sh) do |command|
50
+ command.should match(/tar xzf #{stemcell.path} --directory .*/)
51
+ end
52
+
53
+ expected_tarfile = File.join(File.dirname(stemcell.path), 'light-fake-stemcell-aws.tgz')
54
+
55
+ Rake::FileUtilsExt.should_receive(:sh) do |command|
56
+ command.should match(/sudo tar cvzf #{expected_tarfile} \*/)
57
+ end
58
+
59
+ light_stemcell.write_archive
60
+ end
61
+
62
+ it 'replaces the raw image with a blank placeholder' do
63
+ FileUtils.should_receive(:touch).and_return do |file, options|
64
+ expect(file).to match('image')
65
+ expect(options).to eq(verbose: true)
66
+ end
67
+ light_stemcell.write_archive
68
+ end
69
+
70
+ it 'adds the ami to the stemcell manifest' do
71
+ Psych.should_receive(:dump).and_return do |stemcell_properties, out|
72
+ expect(stemcell_properties['cloud_properties']['ami']).to eq({ 'fake-region' => 'fake-ami-id' })
73
+ end
74
+
75
+ light_stemcell.write_archive
76
+ end
77
+
78
+ it 'names the stemcell manifest correctly' do
79
+ # Example fails on linux without File.stub
80
+ File.stub(:open).and_call_original
81
+ File.should_receive(:open).with('stemcell.MF', 'w')
82
+
83
+ light_stemcell.write_archive
84
+ end
85
+
86
+ it 'does not mutate original stemcell manifest' do
87
+ expect {
88
+ light_stemcell.write_archive
89
+ }.not_to change { stemcell.manifest['cloud_properties'] }
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'bosh/stemcell/aws/region'
3
+
4
+ module Bosh::Stemcell::Aws
5
+ describe Region do
6
+ it 'queries AWS for its region' do
7
+ az_query = '/latest/meta-data/placement/availability-zone'
8
+ Net::HTTP.stub(:get).with('169.254.169.254', az_query).and_return("us-east-1\n")
9
+ expect(subject.name).to eq 'us-east-1'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,241 @@
1
+ require 'spec_helper'
2
+ require 'bosh/stemcell/builder_command'
3
+
4
+ module Bosh::Stemcell
5
+ describe BuilderCommand do
6
+ subject(:stemcell_builder_command) do
7
+ described_class.new(
8
+ env,
9
+ infrastructure_name: infrastructure.name,
10
+ operating_system_name: operating_system.name,
11
+ release_tarball_path: release_tarball_path,
12
+ version: version
13
+ )
14
+ end
15
+
16
+ let(:env) { {} }
17
+
18
+ let(:infrastructure) do
19
+ instance_double(
20
+ 'Bosh::Stemcell::Infrastructure::Vsphere',
21
+ name: 'vsphere',
22
+ hypervisor: 'esxi'
23
+ )
24
+ end
25
+
26
+ let(:operating_system) { instance_double('Bosh::Stemcell::OperatingSystem::Ubuntu', name: 'ubuntu') }
27
+ let(:release_tarball_path) { "/fake/path/to/bosh-#{version}.tgz" }
28
+ let(:version) { '007' }
29
+
30
+ before do
31
+ Infrastructure.stub(:for).with('vsphere').and_return(infrastructure)
32
+ OperatingSystem.stub(:for).with(operating_system.name).and_return(operating_system)
33
+ StageCollection.stub(:new).with(
34
+ infrastructure: infrastructure,
35
+ operating_system: operating_system
36
+ ).and_return(stage_collection)
37
+
38
+ StageRunner.stub(:new).with(
39
+ build_path: File.join(root_dir, 'build', 'build'),
40
+ command_env: 'env ',
41
+ settings_file: settings_file,
42
+ work_path: File.join(root_dir, 'work')
43
+ ).and_return(stage_runner)
44
+
45
+ BuilderOptions.stub(:new).with(
46
+ env,
47
+ tarball: release_tarball_path,
48
+ stemcell_version: version,
49
+ infrastructure: infrastructure,
50
+ operating_system: operating_system
51
+ ).and_return(stemcell_builder_options)
52
+ end
53
+
54
+ let(:root_dir) do
55
+ File.join('/mnt/stemcells', infrastructure.name, infrastructure.hypervisor, operating_system.name)
56
+ end
57
+
58
+ let(:stemcell_builder_options) do
59
+ instance_double('Bosh::Stemcell::BuilderOptions', default: options)
60
+ end
61
+
62
+ let(:stage_collection) do
63
+ instance_double(
64
+ 'Bosh::Stemcell::StageCollection',
65
+ operating_system_stages: ['FAKE_OS_STAGES'],
66
+ infrastructure_stages: ['FAKE_INFRASTRUCTURE_STAGES']
67
+ )
68
+ end
69
+
70
+ let(:stage_runner) { instance_double('Bosh::Stemcell::StageRunner', configure_and_apply: nil) }
71
+
72
+ let(:etc_dir) { File.join(root_dir, 'build', 'build', 'etc') }
73
+ let(:settings_file) { File.join(etc_dir, 'settings.bash') }
74
+
75
+ let(:options) do
76
+ {
77
+ 'hello' => 'world',
78
+ 'stemcell_tgz' => 'fake-stemcell.tgz',
79
+ 'stemcell_image_name' => 'fake-root-disk-image.raw'
80
+ }
81
+ end
82
+
83
+ its(:chroot_dir) { should eq(File.join(root_dir, 'work', 'work', 'chroot')) }
84
+
85
+ describe '#build' do
86
+ include FakeFS::SpecHelpers
87
+
88
+ before do
89
+ Process.stub(pid: 99999)
90
+
91
+ stemcell_builder_command.stub(system: true)
92
+ FileUtils.touch('leftover.tgz')
93
+
94
+ FileUtils.stub(:cp_r).with([], File.join(root_dir, 'build', 'build'), preserve: true, verbose: true) do
95
+ FileUtils.mkdir_p(etc_dir)
96
+ FileUtils.touch(settings_file)
97
+ end
98
+ end
99
+
100
+ describe 'sanitizing the environment' do
101
+ it 'removes any tgz files from current working directory' do
102
+ expect {
103
+ stemcell_builder_command.build
104
+ }.to change { Dir.glob('*.tgz').size }.to(0)
105
+ end
106
+
107
+ it 'unmounts the disk image used to install Grub' do
108
+ image_path = File.join(root_dir, 'work/work/mnt/tmp/grub/fake-root-disk-image.raw')
109
+ unmount_img_command = "sudo umount #{image_path} 2> /dev/null"
110
+ stemcell_builder_command.should_receive(:system).with(unmount_img_command)
111
+ stemcell_builder_command.build
112
+ end
113
+
114
+ it 'unmounts work/work/mnt directory' do
115
+ unmount_dir_command = "sudo umount #{File.join(root_dir, 'work/work/mnt')} 2> /dev/null"
116
+ stemcell_builder_command.should_receive(:system).with(unmount_dir_command)
117
+ stemcell_builder_command.build
118
+ end
119
+
120
+ it 'removes stemcell root directory' do
121
+ stemcell_builder_command.should_receive(:system).with("sudo rm -rf #{root_dir}")
122
+ stemcell_builder_command.build
123
+ end
124
+ end
125
+
126
+ it 'returns the full path of the generated stemcell archive' do
127
+ expect(stemcell_builder_command.build).to eq(File.join(root_dir, 'work', 'work', 'fake-stemcell.tgz'))
128
+ end
129
+
130
+ it 'creates a base directory for stemcell creation' do
131
+ expect {
132
+ stemcell_builder_command.build
133
+ }.to change { Dir.exists?(root_dir) }.from(false).to(true)
134
+ end
135
+
136
+ it 'creates a build directory for stemcell creation' do
137
+ expect {
138
+ stemcell_builder_command.build
139
+ }.to change { Dir.exists?(File.join(root_dir, 'build')) }.from(false).to(true)
140
+ end
141
+
142
+ it 'copies the stemcell_builder code into the build directory' do
143
+ FileUtils.should_receive(:cp_r).with([],
144
+ File.join(root_dir, 'build', 'build'),
145
+ preserve: true,
146
+ verbose: true) do
147
+ FileUtils.mkdir_p(etc_dir)
148
+ FileUtils.touch(settings_file)
149
+ end
150
+
151
+ stemcell_builder_command.build
152
+ end
153
+
154
+ it 'creates a work directory for stemcell creation chroot' do
155
+ expect {
156
+ stemcell_builder_command.build
157
+ }.to change { Dir.exists?(File.join(root_dir, 'work')) }.from(false).to(true)
158
+ end
159
+
160
+ it 'writes a settings file into the build directory' do
161
+ stemcell_builder_command.build
162
+
163
+ expect(File.read(settings_file)).to match(/hello=world/)
164
+ end
165
+
166
+ describe 'running stages' do
167
+ let(:expected_rspec_command) do
168
+ [
169
+ "cd #{File.expand_path('../../..', File.dirname(__FILE__))};",
170
+ "STEMCELL_IMAGE=#{File.join(root_dir, 'work', 'work', 'fake-root-disk-image.raw')}",
171
+ 'bundle exec rspec -fd',
172
+ "spec/stemcells/#{operating_system.name}_spec.rb",
173
+ "spec/stemcells/#{infrastructure.name}_spec.rb",
174
+ ].join(' ')
175
+ end
176
+
177
+ it 'calls #configure_and_apply' do
178
+ stage_runner.should_receive(:configure_and_apply).
179
+ with(['FAKE_OS_STAGES']).ordered
180
+ stage_runner.should_receive(:configure_and_apply).
181
+ with(['FAKE_INFRASTRUCTURE_STAGES']).ordered
182
+ stemcell_builder_command.should_receive(:system).
183
+ with(expected_rspec_command).ordered
184
+
185
+ stemcell_builder_command.build
186
+ end
187
+
188
+ context 'with CentOS' do
189
+ let(:operating_system) { instance_double('Bosh::Stemcell::OperatingSystem::Centos', name: 'centos') }
190
+
191
+ it 'calls #configure_and_apply' do
192
+ stage_runner.should_receive(:configure_and_apply).
193
+ with(['FAKE_OS_STAGES']).ordered
194
+ stage_runner.should_receive(:configure_and_apply).
195
+ with(['FAKE_INFRASTRUCTURE_STAGES']).ordered
196
+ stemcell_builder_command.should_receive(:system).
197
+ with(expected_rspec_command).ordered
198
+
199
+ stemcell_builder_command.build
200
+ end
201
+ end
202
+ end
203
+
204
+ context 'when ENV contains variables besides HTTP_PROXY and NO_PROXY' do
205
+ let(:env) do
206
+ {
207
+ 'NOT_HTTP_PROXY' => 'nice_proxy',
208
+ 'no_proxy_just_kidding' => 'naughty_proxy'
209
+ }
210
+ end
211
+
212
+ it 'nothing is passed to sudo via "env"' do
213
+ StageRunner.stub(:new).with(build_path: File.join(root_dir, 'build', 'build'),
214
+ command_env: 'env ',
215
+ settings_file: settings_file,
216
+ work_path: File.join(root_dir, 'work')).and_return(stage_runner)
217
+
218
+ stemcell_builder_command.build
219
+ end
220
+ end
221
+
222
+ context 'ENV variables for HTTP_PROXY and NO_PROXY are passed to "env"' do
223
+ let(:env) do
224
+ {
225
+ 'HTTP_PROXY' => 'nice_proxy',
226
+ 'no_proxy' => 'naughty_proxy'
227
+ }
228
+ end
229
+
230
+ it 'they are passed to sudo via "env"' do
231
+ StageRunner.stub(:new).with(build_path: File.join(root_dir, 'build', 'build'),
232
+ command_env: "env HTTP_PROXY='nice_proxy' no_proxy='naughty_proxy'",
233
+ settings_file: settings_file,
234
+ work_path: File.join(root_dir, 'work')).and_return(stage_runner)
235
+
236
+ stemcell_builder_command.build
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end