boxgrinder-core 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. data/CHANGELOG +10 -0
  2. data/Rakefile +13 -9
  3. data/boxgrinder-core.gemspec +11 -8
  4. data/lib/boxgrinder-core/appliance-parser.rb +84 -0
  5. data/{spec/validators/appliance-config-validator-spec.rb → lib/boxgrinder-core/appliance-validator.rb} +15 -2
  6. data/lib/boxgrinder-core/{validators/errors.rb → errors.rb} +16 -0
  7. data/lib/boxgrinder-core/helpers/appliance-config-helper.rb +10 -18
  8. data/lib/boxgrinder-core/helpers/appliance-definition-helper.rb +19 -59
  9. data/lib/boxgrinder-core/helpers/appliance-transformation-helper.rb +58 -0
  10. data/lib/boxgrinder-core/helpers/exec-helper.rb +48 -21
  11. data/lib/boxgrinder-core/models/appliance-config.rb +39 -23
  12. data/lib/boxgrinder-core/models/config.rb +4 -2
  13. data/lib/boxgrinder-core/schemas/appliance_schema_0.8.0.yaml +95 -0
  14. data/lib/boxgrinder-core/schemas/appliance_schema_0.9.0.yaml +92 -0
  15. data/rubygem-boxgrinder-core.spec +13 -1
  16. data/spec/appliance-parser-spec.rb +68 -0
  17. data/spec/appliance-validator-spec.rb +71 -0
  18. data/spec/helpers/appliance-config-helper-spec.rb +136 -1
  19. data/spec/helpers/appliance-definition-helper-spec.rb +51 -79
  20. data/spec/helpers/appliance-transformation-helper-spec.rb +51 -0
  21. data/spec/helpers/exec-helper-spec.rb +40 -12
  22. data/spec/helpers/log-helper-spec.rb +1 -0
  23. data/spec/models/config-spec.rb +2 -1
  24. data/spec/rspec/src/appliances/0.8.x.appl +38 -0
  25. data/spec/rspec/src/appliances/0.9.x-invalid.appl +40 -0
  26. data/spec/rspec/src/appliances/0.9.x.appl +36 -0
  27. metadata +48 -19
  28. data/lib/boxgrinder-core/validators/appliance-config-validator.rb +0 -65
@@ -22,32 +22,33 @@ require 'hashery/opencascade'
22
22
  module BoxGrinder
23
23
  class ApplianceConfig
24
24
  def initialize
25
- @name = nil
26
- @summary = nil
25
+ @name = nil
26
+ @summary = nil
27
27
 
28
- @variables = {}
28
+ @variables = {}
29
29
 
30
- @os = OpenCascade.new
30
+ @os = OpenCascade.new
31
31
 
32
- @os.name = nil
33
- @os.version = nil
34
- @os.password = 'boxgrinder'
32
+ @os.name = nil
33
+ @os.version = nil
34
+ @os.password = nil
35
+ @os.pae = true
35
36
 
36
- @hardware = OpenCascade.new
37
+ @hardware = OpenCascade.new
37
38
 
38
- @hardware.cpus = 1
39
- @hardware.memory = 256
40
- @hardware.network = 'NAT'
41
- @hardware.partitions = {"/" => { 'size' => 1 }}
39
+ @hardware.cpus = 1
40
+ @hardware.memory = 256
41
+ @hardware.network = 'NAT'
42
+ @hardware.partitions = {"/" => {'size' => 1}}
42
43
 
43
- @post = {}
44
+ @post = {}
44
45
 
45
- @packages = []
46
- @appliances = []
47
- @repos = []
46
+ @packages = []
47
+ @appliances = []
48
+ @repos = []
48
49
 
49
- @version = 1
50
- @release = 0
50
+ @version = 1
51
+ @release = 0
51
52
  end
52
53
 
53
54
  attr_reader :variables
@@ -72,22 +73,37 @@ module BoxGrinder
72
73
  end
73
74
 
74
75
  def init_arch
75
- @hardware.arch = `uname -m`.chomp.strip
76
+ @hardware.arch = `uname -m`.chomp.strip
76
77
  @hardware.base_arch = is64bit? ? "x86_64" : "i386"
77
78
  self
78
79
  end
79
80
 
80
81
  def initialize_paths
81
- @path = OpenCascade.new
82
+ @path = OpenCascade.new
82
83
 
83
- @path.os = "#{@os.name}/#{@os.version}"
84
- @path.main = "#{@hardware.arch}/#{@path.os}"
84
+ @path.os = "#{@os.name}/#{@os.version}"
85
+ @path.main = "#{@hardware.arch}/#{@path.os}"
85
86
  @path.appliance = "appliances/#{@path.main}/#{@name}"
86
- @path.build = "build/#{@path.appliance}"
87
+ @path.build = "build/#{@path.appliance}"
87
88
 
88
89
  self
89
90
  end
90
91
 
92
+ # Returns default filesystem type for current OS
93
+ def default_filesystem_type
94
+ fs = 'ext4'
95
+
96
+ case @os.name
97
+ when 'rhel', 'centos'
98
+ case @os.version
99
+ when '5'
100
+ fs = 'ext3'
101
+ end
102
+ end
103
+
104
+ fs
105
+ end
106
+
91
107
  # used to checking if configuration differs from previous in appliance-kickstart
92
108
  def hash
93
109
  "#{@name}-#{@summary}-#{@version}-#{@release}-#{@os.name}-#{@os.version}-#{@os.password}-#{@hardware.cpus}-#{@hardware.memory}-#{@hardware.partitions}-#{@appliances}".hash
@@ -36,7 +36,8 @@ module BoxGrinder
36
36
  :dir => {
37
37
  :root => Dir.pwd,
38
38
  :build => 'build',
39
- :cache => '/var/cache/boxgrinder' # required for appliance-creator
39
+ :cache => '/var/cache/boxgrinder', # required for appliance-creator
40
+ :tmp => '/tmp'
40
41
  },
41
42
  :os_config => {},
42
43
  :platform_config => {},
@@ -44,9 +45,10 @@ module BoxGrinder
44
45
  :additional_plugins => []
45
46
  )
46
47
 
48
+ deep_merge(self, YAML.load_file(self.file)) if File.exists?(self.file)
47
49
  merge!(values.inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo })
48
50
 
49
- deep_merge(self, YAML.load_file(self.file)) if File.exists?(self.file)
51
+ self.backtrace = true if [:debug, :trace].include?(self.log_level)
50
52
  end
51
53
 
52
54
  def deep_merge(first, second)
@@ -0,0 +1,95 @@
1
+ #0.8.x schema
2
+ version: 0.8.0
3
+ type: map
4
+ mapping:
5
+ "name":
6
+ type: str
7
+ length: { min: 1 }
8
+ required: yes
9
+ "summary":
10
+ type: str
11
+ length: { min: 1 }
12
+ "version":
13
+ type: int
14
+ "release":
15
+ type: int
16
+ "os":
17
+ type: map
18
+ mapping:
19
+ "name":
20
+ type: str
21
+ length: { min: 1 }
22
+ required: yes
23
+ "version":
24
+ type: text
25
+ required: yes
26
+ "password":
27
+ type: str
28
+ "hardware":
29
+ type: map
30
+ name: Hardware
31
+ mapping:
32
+ "cpus":
33
+ type: int
34
+ range: { min: 1, max: 4 }
35
+ "memory":
36
+ type: int
37
+ range: { min: 1 }
38
+ "partitions":
39
+ type: map
40
+ mapping:
41
+ "=": #No way of providing validation regex for wildcard name.
42
+ type: map
43
+ mapping:
44
+ "size":
45
+ type: number
46
+ range: { min: 0.01 }
47
+ "type":
48
+ type: str
49
+ enum: [ext3, ext4]
50
+ "appliances":
51
+ type: seq
52
+ sequence:
53
+ - type: str
54
+ pattern: /^[^\/]+$/ #dont support path resolution yet
55
+ length: { min: 1 }
56
+ "packages":
57
+ type: map
58
+ mapping:
59
+ "includes": &pkg
60
+ type: seq
61
+ sequence:
62
+ - type: str
63
+ pattern: /^[\w\-+.@\043]+$/ #fedora packaging standard http://bit.ly/h0JN9u (plus a few more, disallow symbols/spaces)
64
+ length: { min: 1 }
65
+ "excludes": *pkg
66
+ "repos":
67
+ type: seq
68
+ sequence:
69
+ - type: map
70
+ mapping:
71
+ "name":
72
+ type: str
73
+ pattern: /^[\w\-+.\043]+$/
74
+ length: { min: 1 }
75
+ required: yes
76
+ "baseurl": &pkg-mirror
77
+ type: str
78
+ pattern: /(^((http|ftp):)(\/\/([^\/?\043]*))?([^?\043]*)(\?([^\043]*))?(\043(.*))?$|^file:\/\/.+$)/ #customised rfc3986 standard regexp for URIs
79
+ "mirrorlist": *pkg-mirror
80
+ "ephemeral":
81
+ type: bool
82
+ "post":
83
+ type: map
84
+ mapping:
85
+ "=":
86
+ type: seq
87
+ sequence:
88
+ - type: str
89
+ length: { min: 1 }
90
+ "variables":
91
+ type: map
92
+ mapping:
93
+ "=": # wibble: value
94
+ type: str
95
+ length: { min: 1 }
@@ -0,0 +1,92 @@
1
+ #0.9.x schema
2
+ version: 0.9.0
3
+ type: map
4
+ mapping:
5
+ "name":
6
+ type: str
7
+ length: { min: 1 }
8
+ required: yes
9
+ "summary":
10
+ type: str
11
+ length: { min: 1 }
12
+ "version":
13
+ type: int
14
+ "release":
15
+ type: int
16
+ "os":
17
+ type: map
18
+ mapping:
19
+ "name":
20
+ type: str
21
+ length: { min: 1 }
22
+ required: yes
23
+ "version":
24
+ type: text
25
+ required: yes
26
+ "password":
27
+ type: str
28
+ "hardware":
29
+ type: map
30
+ name: Hardware
31
+ mapping:
32
+ "cpus":
33
+ type: int
34
+ range: { min: 1, max: 4 }
35
+ "memory":
36
+ type: int
37
+ range: { min: 1 }
38
+ "partitions":
39
+ type: map
40
+ mapping:
41
+ "=": #No way of providing validation regex for wildcard name.
42
+ type: map
43
+ mapping:
44
+ "size":
45
+ type: number
46
+ range: { min: 0.01 }
47
+ "type":
48
+ type: str
49
+ enum: [ext3, ext4]
50
+ "appliances":
51
+ type: seq
52
+ sequence:
53
+ - type: str
54
+ pattern: /^[^\/]+$/ #dont support path resolution yet
55
+ length: { min: 1 }
56
+ "packages":
57
+ type: seq
58
+ sequence:
59
+ - type: str
60
+ pattern: /^[\w\-+.@\043]+$/ #fedora packaging standard http://bit.ly/h0JN9u (plus a few more, disallow symbols/spaces)
61
+ length: { min: 1 }
62
+ "repos":
63
+ type: seq
64
+ sequence:
65
+ - type: map
66
+ name: Repository
67
+ mapping:
68
+ "name":
69
+ type: str
70
+ pattern: /^[\w\-+.\043]+$/
71
+ length: { min: 1 }
72
+ required: yes
73
+ "baseurl": &pkg-mirror
74
+ type: str
75
+ pattern: /(^((http|ftp):)(\/\/([^\/?\043]*))?([^?\043]*)(\?([^\043]*))?(\043(.*))?$|^file:\/\/.+$)/ #customised rfc3986 standard regexp for URIs
76
+ "mirrorlist": *pkg-mirror
77
+ "ephemeral":
78
+ type: bool
79
+ "post":
80
+ type: map
81
+ mapping:
82
+ "=":
83
+ type: seq
84
+ sequence:
85
+ - type: str
86
+ length: { min: 1 }
87
+ "variables":
88
+ type: map
89
+ mapping:
90
+ "=": # wibble: value
91
+ type: str
92
+ length: { min: 1 }
@@ -5,7 +5,7 @@
5
5
 
6
6
  Summary: Core library for BoxGrinder
7
7
  Name: rubygem-%{gemname}
8
- Version: 0.3.0
8
+ Version: 0.3.1
9
9
  Release: 1%{?dist}
10
10
  Group: Development/Languages
11
11
  License: LGPLv3+
@@ -16,12 +16,14 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
16
16
  Requires: ruby(abi) = %{rubyabi}
17
17
  Requires: rubygem(open4)
18
18
  Requires: rubygem(hashery)
19
+ Requires: rubygem(kwalify)
19
20
 
20
21
  BuildRequires: rubygem(rake)
21
22
  BuildRequires: rubygem(rspec)
22
23
  BuildRequires: rubygem(open4)
23
24
  BuildRequires: rubygem(hashery)
24
25
  BuildRequires: rubygem(echoe)
26
+ BuildRequires: rubygem(kwalify)
25
27
 
26
28
  BuildArch: noarch
27
29
  Provides: rubygem(%{gemname}) = %{version}
@@ -74,6 +76,16 @@ popd
74
76
  %{gemdir}/doc/%{gemname}-%{version}
75
77
 
76
78
  %changelog
79
+ * Thu Mar 17 2011 <mgoldman@redhat.com> - 0.3.1-1
80
+ - Upstream release: 0.3.1
81
+ - [BGBUILD-164] Guestfs writes to /tmp/ by default, potentially filling the root filesystem
82
+ - [BGBUILD-97] some filesystems dont get unmounted on BG interruption
83
+ - [BGBUILD-155] Images built on Centos5.x (el5) for VirtualBox kernel panic (/dev/root missing)
84
+ - [BGBUILD-190] Allow to specify kernel variant (PAE or not) for Fedora OS
85
+ - [BGBUILD-192] Use IO.popen4 instead open4 gem on JRuby
86
+ - [BGBUILD-198] root password is not inherited
87
+ - [BGBUILD-156] Validate appliance definition files early and return meaningful error messages
88
+
77
89
  * Sat Mar 05 2011 <mgoldman@redhat.com> - 0.3.0-1
78
90
  - Upstream release: 0.3.0
79
91
  - [BGBUILD-178] Remove sensitive data from logs
@@ -0,0 +1,68 @@
1
+ #
2
+ # Copyright 2010 Red Hat, Inc.
3
+ #
4
+ # This is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU Lesser General Public License as
6
+ # published by the Free Software Foundation; either version 3 of
7
+ # the License, or (at your option) any later version.
8
+ #
9
+ # This software is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this software; if not, write to the Free
16
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
+
19
+ require 'rubygems'
20
+ require 'boxgrinder-core/appliance-parser'
21
+ require 'boxgrinder-core/helpers/log-helper'
22
+
23
+ module BoxGrinder
24
+ describe ApplianceParser do
25
+ before(:each) do
26
+ @log = LogHelper.new(:level => :trace, :type => :stdout)
27
+ @parser = ApplianceParser.new(:log => @log)
28
+ end
29
+
30
+ describe ".load_schemas" do
31
+ it "should load all available schemas" do
32
+ Kwalify::Yaml.should_receive(:load_file).with('filea').and_return({'version' => '0.8.0'})
33
+ Kwalify::Yaml.should_receive(:load_file).with('fileb').and_return({'version' => '0.9.0'})
34
+
35
+ Dir.should_receive(:glob).with(an_instance_of(String)).and_return(['filea', 'fileb'])
36
+
37
+ @parser.load_schemas
38
+ @parser.instance_variable_get(:@schemas).should == {'0.8.0' => {'version' => '0.8.0'}, '0.9.0' => {'version' => '0.9.0'}}
39
+ end
40
+ end
41
+
42
+ describe ".parse_definition" do
43
+ it "should raise exception because the appliance definition is invalid" do
44
+ @parser.load_schemas
45
+
46
+ lambda {
47
+ @parser.parse_definition(File.read("#{File.dirname(__FILE__)}/rspec/src/appliances/invalid-yaml.appl"), false)
48
+ }.should raise_error(ApplianceValidationError, "The appliance definition was invalid according to schema 0.9.0. See log for details.")
49
+ end
50
+
51
+ it "should validate 0.9.0 version definition without error" do
52
+ @parser.load_schemas
53
+ definition = @parser.parse_definition(File.read("#{File.dirname(__FILE__)}/rspec/src/appliances/0.9.x.appl"), false)
54
+
55
+ definition['os']['password'].should == 'boxgrinder-ftw'
56
+ definition['packages'].size.should == 2
57
+ end
58
+
59
+ it "should validate 0.8.0 version definition without error" do
60
+ @parser.load_schemas
61
+ definition = @parser.parse_definition("#{File.dirname(__FILE__)}/rspec/src/appliances/0.8.x.appl")
62
+
63
+ definition['os']['password'].should == 'boxgrinder-ftw'
64
+ definition['packages'].size.should == 3
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,71 @@
1
+ #
2
+ # Copyright 2010 Red Hat, Inc.
3
+ #
4
+ # This is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU Lesser General Public License as
6
+ # published by the Free Software Foundation; either version 3 of
7
+ # the License, or (at your option) any later version.
8
+ #
9
+ # This software is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this software; if not, write to the Free
16
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
+
19
+ require 'rubygems'
20
+ require 'boxgrinder-core/appliance-validator'
21
+ require 'hashery/opencascade'
22
+
23
+ module BoxGrinder
24
+ describe ApplianceValidator do
25
+ before(:each) do
26
+ schema = YAML.load_file("#{File.dirname(__FILE__)}/../lib/boxgrinder-core/schemas/appliance_schema_0.9.0.yaml")
27
+ schema.delete('version')
28
+
29
+ @validator = ApplianceValidator.new(schema)
30
+ end
31
+
32
+ describe ".validate_hook" do
33
+ context "repository" do
34
+ it "should generate error when no baseurl or mirrorlist is specified for repository" do
35
+ a = []
36
+ @validator.validate_hook({}, OpenCascade.new(:name => 'Repository'), '/', a)
37
+ a.size.should == 1
38
+ a.first.message.should == 'Please specify either a baseurl or a mirrorlist.'
39
+ end
40
+
41
+ it "should generate error when both baseurl and mirrorlist are specified for repository" do
42
+ a = []
43
+ @validator.validate_hook({'baseurl' => 'abc', 'mirrorlist' => 'def'}, OpenCascade.new(:name => 'Repository'), '/', a)
44
+ a.size.should == 1
45
+ a.first.message.should == 'Please specify either a baseurl or a mirrorlist.'
46
+ end
47
+
48
+ it "should pass if baseurl or mirrorlist is specified for repository" do
49
+ a = []
50
+ @validator.validate_hook({'baseurl' => 'abc'}, OpenCascade.new(:name => 'Repository'), '/', a)
51
+ a.size.should == 0
52
+ end
53
+ end
54
+
55
+ context "hardware" do
56
+ it "should allow only multiplicity of 64 for memory" do
57
+ a = []
58
+ @validator.validate_hook({'memory' => 235}, OpenCascade.new(:name => 'Hardware'), '/', a)
59
+ a.size.should == 1
60
+ a.first.message.should == "Specified memory amount: 235 is invalid. The value must be a multiple of 64."
61
+ end
62
+
63
+ it "should pass if the memory is 256" do
64
+ a = []
65
+ @validator.validate_hook({'memory' => 256}, OpenCascade.new(:name => 'Hardware'), '/', a)
66
+ a.size.should == 0
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -16,7 +16,9 @@
16
16
  # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
17
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
18
 
19
+ require 'rubygems'
19
20
  require 'boxgrinder-core/helpers/appliance-config-helper'
21
+ require 'boxgrinder-core/models/appliance-config'
20
22
 
21
23
  module BoxGrinder
22
24
  describe ApplianceConfigHelper do
@@ -237,9 +239,33 @@ module BoxGrinder
237
239
 
238
240
  @helper.merge_partitions
239
241
 
242
+ config = @helper.instance_variable_get(:@appliance_config)
243
+ config.hardware.partitions.size.should == 3
244
+ config.hardware.partitions.should == {"/" => {'size' => '4', 'type' => 'ext3'}, "/home" => {'size' => '2', 'type' => 'ext3'}, "/boot" => {'type' => 'ext3', 'size' => 0.1}}
245
+ end
246
+
247
+ it "should merge partitions for default fs_types without options for RHEL 5 (ext3) with /boot partition" do
248
+ config_a = ApplianceConfig.new
249
+ config_a.name = 'a'
250
+ config_a.appliances << 'b'
251
+ config_a.hardware.partitions = {"/" => {'size' => '2'}}
252
+ config_a.os.name = 'rhel'
253
+ config_a.os.version = '5'
254
+
255
+ config_b = ApplianceConfig.new
256
+ config_b.name = 'b'
257
+ config_b.hardware.partitions = {"/" => {'size' => '4'}, "/boot" => {'size' => '2'}}
258
+ config_b.os.name = 'rhel'
259
+ config_b.os.version = '5'
260
+
261
+ prepare_helper([config_a, config_b])
262
+ @helper.instance_variable_set(:@appliance_config, config_a.clone)
263
+
264
+ @helper.merge_partitions
265
+
240
266
  config = @helper.instance_variable_get(:@appliance_config)
241
267
  config.hardware.partitions.size.should == 2
242
- config.hardware.partitions.should == {"/" => {'size' => '4', 'type' => 'ext3'}, "/home" => {'size' => '2', 'type' => 'ext3'}}
268
+ config.hardware.partitions.should == {"/" => {'size' => '4', 'type' => 'ext3'}, "/boot" => {'size' => '2', 'type' => 'ext3'}}
243
269
  end
244
270
 
245
271
  it "should merge partitions with different filesystem types" do
@@ -480,5 +506,114 @@ module BoxGrinder
480
506
  config.default_repos.should == false
481
507
  end
482
508
  end
509
+
510
+ describe ".prepare_os" do
511
+ it "should set default value for pae" do
512
+ config_a = ApplianceConfig.new
513
+ config_a.name = 'a'
514
+ config_a.appliances << 'b'
515
+
516
+ config_b = ApplianceConfig.new
517
+ config_b.name = 'b'
518
+
519
+ prepare_helper([config_a, config_b])
520
+ @helper.instance_variable_set(:@appliance_config, config_a.clone)
521
+
522
+ @helper.prepare_os
523
+
524
+ config = @helper.instance_variable_get(:@appliance_config)
525
+ config.os.pae.should == true
526
+ end
527
+
528
+ it "should set pae to false if it set so in dependent appliances" do
529
+ config_a = ApplianceConfig.new
530
+ config_a.name = 'a'
531
+ config_a.appliances << 'b'
532
+
533
+ config_b = ApplianceConfig.new
534
+ config_b.name = 'b'
535
+ config_b.os.pae = false
536
+
537
+ prepare_helper([config_a, config_b])
538
+ @helper.instance_variable_set(:@appliance_config, config_a.clone)
539
+
540
+ @helper.prepare_os
541
+
542
+ config = @helper.instance_variable_get(:@appliance_config)
543
+ config.os.pae.should == false
544
+ end
545
+
546
+ it "should set default value for pae" do
547
+ config_a = ApplianceConfig.new
548
+ config_a.name = 'a'
549
+ config_a.appliances << 'b'
550
+
551
+ config_b = ApplianceConfig.new
552
+ config_b.name = 'b'
553
+
554
+ prepare_helper([config_a, config_b])
555
+ @helper.instance_variable_set(:@appliance_config, config_a.clone)
556
+
557
+ @helper.prepare_os
558
+
559
+ config = @helper.instance_variable_get(:@appliance_config)
560
+ config.os.pae.should == true
561
+ end
562
+
563
+ context "root password" do
564
+ it "should set default password" do
565
+ config_a = ApplianceConfig.new
566
+ config_a.name = 'a'
567
+ config_a.appliances << 'b'
568
+
569
+ config_b = ApplianceConfig.new
570
+ config_b.name = 'b'
571
+
572
+ prepare_helper([config_a, config_b])
573
+ @helper.instance_variable_set(:@appliance_config, config_a.clone)
574
+
575
+ @helper.prepare_os
576
+
577
+ config = @helper.instance_variable_get(:@appliance_config)
578
+ config.os.password.should == 'boxgrinder'
579
+ end
580
+
581
+ it "should set password from top-level appliance" do
582
+ config_a = ApplianceConfig.new
583
+ config_a.name = 'a'
584
+ config_a.os.password = 'test'
585
+ config_a.appliances << 'b'
586
+
587
+ config_b = ApplianceConfig.new
588
+ config_b.name = 'b'
589
+
590
+ prepare_helper([config_a, config_b])
591
+ @helper.instance_variable_set(:@appliance_config, config_a.clone)
592
+
593
+ @helper.prepare_os
594
+
595
+ config = @helper.instance_variable_get(:@appliance_config)
596
+ config.os.password.should == 'test'
597
+ end
598
+
599
+ it "should set password from inherited appliance" do
600
+ config_a = ApplianceConfig.new
601
+ config_a.name = 'a'
602
+ config_a.appliances << 'b'
603
+
604
+ config_b = ApplianceConfig.new
605
+ config_b.name = 'b'
606
+ config_b.os.password = 'test'
607
+
608
+ prepare_helper([config_a, config_b])
609
+ @helper.instance_variable_set(:@appliance_config, config_a.clone)
610
+
611
+ @helper.prepare_os
612
+
613
+ config = @helper.instance_variable_get(:@appliance_config)
614
+ config.os.password.should == 'test'
615
+ end
616
+ end
617
+ end
483
618
  end
484
619
  end