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,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