vagrantup 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Rakefile +1 -1
  4. data/VERSION +1 -1
  5. data/bin/vagrant +1 -1
  6. data/bin/vagrant-box +1 -2
  7. data/bin/vagrant-down +1 -2
  8. data/bin/vagrant-halt +1 -2
  9. data/bin/vagrant-init +1 -2
  10. data/bin/vagrant-package +1 -2
  11. data/bin/vagrant-reload +1 -2
  12. data/bin/vagrant-resume +1 -2
  13. data/bin/vagrant-ssh +1 -2
  14. data/bin/vagrant-status +29 -0
  15. data/bin/vagrant-suspend +1 -2
  16. data/bin/vagrant-up +1 -2
  17. data/config/default.rb +5 -9
  18. data/keys/README.md +10 -0
  19. data/keys/vagrant +27 -0
  20. data/keys/vagrant.pub +1 -0
  21. data/lib/vagrant.rb +10 -5
  22. data/lib/vagrant/actions/base.rb +14 -0
  23. data/lib/vagrant/actions/box/download.rb +3 -0
  24. data/lib/vagrant/actions/collection.rb +36 -0
  25. data/lib/vagrant/actions/runner.rb +4 -10
  26. data/lib/vagrant/actions/vm/boot.rb +4 -5
  27. data/lib/vagrant/actions/vm/customize.rb +17 -0
  28. data/lib/vagrant/actions/vm/destroy.rb +11 -2
  29. data/lib/vagrant/actions/vm/forward_ports.rb +24 -0
  30. data/lib/vagrant/actions/vm/import.rb +1 -0
  31. data/lib/vagrant/actions/vm/provision.rb +30 -52
  32. data/lib/vagrant/actions/vm/reload.rb +2 -2
  33. data/lib/vagrant/actions/vm/shared_folders.rb +37 -25
  34. data/lib/vagrant/actions/vm/up.rb +8 -4
  35. data/lib/vagrant/active_list.rb +66 -0
  36. data/lib/vagrant/commands.rb +44 -0
  37. data/lib/vagrant/config.rb +64 -47
  38. data/lib/vagrant/downloaders/base.rb +3 -0
  39. data/lib/vagrant/downloaders/file.rb +11 -11
  40. data/lib/vagrant/env.rb +48 -12
  41. data/lib/vagrant/provisioners/base.rb +22 -0
  42. data/lib/vagrant/provisioners/chef.rb +102 -0
  43. data/lib/vagrant/provisioners/chef_server.rb +96 -0
  44. data/lib/vagrant/provisioners/chef_solo.rb +67 -0
  45. data/lib/vagrant/ssh.rb +25 -6
  46. data/lib/vagrant/stacked_proc_runner.rb +33 -0
  47. data/lib/vagrant/vm.rb +8 -0
  48. data/test/test_helper.rb +22 -6
  49. data/test/vagrant/actions/box/download_test.rb +11 -0
  50. data/test/vagrant/actions/collection_test.rb +110 -0
  51. data/test/vagrant/actions/runner_test.rb +11 -7
  52. data/test/vagrant/actions/vm/boot_test.rb +7 -7
  53. data/test/vagrant/actions/vm/customize_test.rb +16 -0
  54. data/test/vagrant/actions/vm/destroy_test.rb +19 -6
  55. data/test/vagrant/actions/vm/forward_ports_test.rb +52 -0
  56. data/test/vagrant/actions/vm/import_test.rb +10 -3
  57. data/test/vagrant/actions/vm/provision_test.rb +75 -70
  58. data/test/vagrant/actions/vm/reload_test.rb +3 -2
  59. data/test/vagrant/actions/vm/shared_folders_test.rb +62 -9
  60. data/test/vagrant/actions/vm/up_test.rb +4 -4
  61. data/test/vagrant/active_list_test.rb +169 -0
  62. data/test/vagrant/config_test.rb +145 -29
  63. data/test/vagrant/downloaders/base_test.rb +7 -0
  64. data/test/vagrant/downloaders/file_test.rb +12 -18
  65. data/test/vagrant/env_test.rb +96 -23
  66. data/test/vagrant/provisioners/base_test.rb +27 -0
  67. data/test/vagrant/provisioners/chef_server_test.rb +175 -0
  68. data/test/vagrant/provisioners/chef_solo_test.rb +142 -0
  69. data/test/vagrant/provisioners/chef_test.rb +116 -0
  70. data/test/vagrant/ssh_test.rb +29 -8
  71. data/test/vagrant/stacked_proc_runner_test.rb +43 -0
  72. data/test/vagrant/vm_test.rb +23 -0
  73. data/vagrant.gemspec +34 -7
  74. metadata +33 -5
  75. data/script/vagrant-ssh-expect.sh +0 -22
@@ -2,6 +2,30 @@ module Vagrant
2
2
  module Actions
3
3
  module VM
4
4
  class ForwardPorts < Base
5
+ def prepare
6
+ VirtualBox::VM.all.each do |vm|
7
+ next if !vm.running? || vm.uuid == @runner.uuid
8
+
9
+ vm.forwarded_ports.each do |fp|
10
+ Vagrant.config.vm.forwarded_ports.each do |name, options|
11
+ if fp.hostport.to_s == options[:hostport].to_s
12
+ raise ActionException.new(<<-msg)
13
+ Vagrant cannot forward the specified ports on this VM, since they
14
+ would collide with another VirtualBox virtual machine's forwarded
15
+ ports! The "#{name}" forwarded port (#{fp.hostport}) is already in use on the host
16
+ machine.
17
+
18
+ To fix this, modify your current projects Vagrantfile to use another
19
+ port. Example, where '1234' would be replaced by a unique host port:
20
+
21
+ config.vm.forward_port("#{name}", #{options[:guestport]}, 1234)
22
+ msg
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
5
29
  def execute!
6
30
  clear
7
31
  forward_ports
@@ -8,6 +8,7 @@ module Vagrant
8
8
  logger.info "Importing base VM (#{Vagrant::Env.box.ovf_file})..."
9
9
  # Use the first argument passed to the action
10
10
  @runner.vm = VirtualBox::VM.import(Vagrant::Env.box.ovf_file)
11
+ raise ActionException.new("The VM import failed! Try running `VBoxManage import` on the box file manually for more verbose error output.") unless @runner.vm
11
12
  end
12
13
  end
13
14
  end
@@ -2,68 +2,46 @@ module Vagrant
2
2
  module Actions
3
3
  module VM
4
4
  class Provision < Base
5
- def execute!
6
- chown_provisioning_folder
7
- setup_json
8
- setup_solo_config
9
- run_chef_solo
10
- end
11
-
12
- def chown_provisioning_folder
13
- logger.info "Setting permissions on provisioning folder..."
14
- SSH.execute do |ssh|
15
- ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}")
16
- end
17
- end
18
-
19
- def setup_json
20
- logger.info "Generating JSON and uploading..."
21
-
22
- # Set up initial configuration
23
- data = {
24
- :config => Vagrant.config,
25
- :directory => Vagrant.config.vm.project_directory,
26
- }
5
+ attr_reader :provisioner
27
6
 
28
- # And wrap it under the "vagrant" namespace
29
- data = { :vagrant => data }
7
+ def intialize(*args)
8
+ super
30
9
 
31
- # Merge with the "extra data" which isn't put under the
32
- # vagrant namespace by default
33
- data.merge!(Vagrant.config.chef.json)
34
-
35
- json = data.to_json
36
-
37
- SSH.upload!(StringIO.new(json), File.join(Vagrant.config.chef.provisioning_path, "dna.json"))
10
+ @provisioner = nil
38
11
  end
39
12
 
40
- def setup_solo_config
41
- solo_file = <<-solo
42
- file_cache_path "#{Vagrant.config.chef.provisioning_path}"
43
- cookbook_path "#{cookbooks_path}"
44
- solo
13
+ def prepare
14
+ provisioner = Vagrant.config.vm.provisioner
45
15
 
46
- logger.info "Uploading chef-solo configuration script..."
47
- SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "solo.rb"))
48
- end
16
+ if provisioner.nil?
17
+ logger.info("Provisioning not enabled, ignoring this step")
18
+ return
19
+ end
49
20
 
50
- def run_chef_solo
51
- logger.info "Running chef recipes..."
52
- SSH.execute do |ssh|
53
- ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json") do |channel, data, stream|
54
- # TODO: Very verbose. It would be easier to save the data and only show it during
55
- # an error, or when verbosity level is set high
56
- logger.info("#{stream}: #{data}")
57
- end
21
+ if provisioner.is_a?(Class)
22
+ @provisioner = provisioner.new
23
+ raise ActionException.new("Provisioners must be an instance of Vagrant::Provisioners::Base") unless @provisioner.is_a?(Provisioners::Base)
24
+ elsif provisioner.is_a?(Symbol)
25
+ # We have a few hard coded provisioners for built-ins
26
+ mapping = {
27
+ :chef_solo => Provisioners::ChefSolo,
28
+ :chef_server => Provisioners::ChefServer
29
+ }
30
+
31
+ provisioner_klass = mapping[provisioner]
32
+ raise ActionException.new("Unknown provisioner type: #{provisioner}") if provisioner_klass.nil?
33
+ @provisioner = provisioner_klass.new
58
34
  end
59
- end
60
35
 
61
- def cookbooks_path
62
- File.join(Vagrant.config.chef.provisioning_path, "cookbooks")
36
+ logger.info "Provisioning enabled with #{@provisioner.class}"
37
+ @provisioner.prepare
63
38
  end
64
39
 
65
- def collect_shared_folders
66
- ["vagrant-provisioning", File.expand_path(Vagrant.config.chef.cookbooks_path, Env.root_path), cookbooks_path]
40
+ def execute!
41
+ if provisioner
42
+ logger.info "Beginning provisioning process..."
43
+ provisioner.provision!
44
+ end
67
45
  end
68
46
  end
69
47
  end
@@ -3,9 +3,9 @@ module Vagrant
3
3
  module VM
4
4
  class Reload < Base
5
5
  def prepare
6
- steps = [ForwardPorts, SharedFolders, Boot]
6
+ steps = [Customize, ForwardPorts, SharedFolders, Boot]
7
7
  steps.unshift(Halt) if @runner.vm.running?
8
- steps << Provision if Vagrant.config.chef.enabled
8
+ steps << Provision if !Vagrant.config.vm.provisioner.nil?
9
9
 
10
10
  steps.each do |action_klass|
11
11
  @runner.add_action(action_klass)
@@ -3,32 +3,15 @@ module Vagrant
3
3
  module VM
4
4
  class SharedFolders < Base
5
5
  def shared_folders
6
- shared_folders = @runner.invoke_callback(:collect_shared_folders)
7
-
8
- # Basic filtering of shared folders. Basically only verifies that
9
- # the result is an array of 3 elements. In the future this should
10
- # also verify that the host path exists, the name is valid,
11
- # and that the guest path is valid.
12
- shared_folders.collect do |folder|
13
- if folder.is_a?(Array) && folder.length == 3
14
- folder
15
- else
16
- nil
17
- end
18
- end.compact
6
+ Vagrant.config.vm.shared_folders.inject([]) do |acc, data|
7
+ name, value = data
8
+ acc << [name, File.expand_path(value[:hostpath]), value[:guestpath]]
9
+ end
19
10
  end
20
11
 
21
12
  def before_boot
22
- logger.info "Creating shared folders metadata..."
23
-
24
- shared_folders.each do |name, hostpath, guestpath|
25
- folder = VirtualBox::SharedFolder.new
26
- folder.name = name
27
- folder.hostpath = hostpath
28
- @runner.vm.shared_folders << folder
29
- end
30
-
31
- @runner.vm.save(true)
13
+ clear_shared_folders
14
+ create_metadata
32
15
  end
33
16
 
34
17
  def after_boot
@@ -44,14 +27,43 @@ module Vagrant
44
27
  end
45
28
  end
46
29
 
30
+ def clear_shared_folders
31
+ logger.info "Clearing previously set shared folders..."
32
+
33
+ @runner.vm.shared_folders.each do |shared_folder|
34
+ shared_folder.destroy
35
+ end
36
+
37
+ @runner.reload!
38
+ end
39
+
40
+ def create_metadata
41
+ logger.info "Creating shared folders metadata..."
42
+
43
+ shared_folders.each do |name, hostpath, guestpath|
44
+ folder = VirtualBox::SharedFolder.new
45
+ folder.name = name
46
+ folder.hostpath = hostpath
47
+ @runner.vm.shared_folders << folder
48
+ end
49
+
50
+ @runner.vm.save(true)
51
+ end
52
+
47
53
  def mount_folder(ssh, name, guestpath, sleeptime=5)
48
54
  # Note: This method seems pretty OS-specific and could also use
49
55
  # some configuration options. For now its duct tape and "works"
50
56
  # but should be looked at in the future.
51
- attempts = 0
52
57
 
58
+ # Determine the permission string to attach to the mount command
59
+ perms = []
60
+ perms << "uid=#{Vagrant.config.vm.shared_folder_uid}"
61
+ perms << "gid=#{Vagrant.config.vm.shared_folder_gid}"
62
+ perms = " -o #{perms.join(",")}" if !perms.empty?
63
+
64
+ attempts = 0
53
65
  while true
54
- result = ssh.exec!("sudo mount -t vboxsf #{name} #{guestpath}") do |ch, type, data|
66
+ result = ssh.exec!("sudo mount -t vboxsf#{perms} #{name} #{guestpath}") do |ch, type, data|
55
67
  # net/ssh returns the value in ch[:result] (based on looking at source)
56
68
  ch[:result] = !!(type == :stderr && data =~ /No such device/i)
57
69
  end
@@ -11,13 +11,17 @@ virtual machine already exists and is not a file! The dotfile is
11
11
  currently configured to be `#{Env.dotfile_path}`
12
12
 
13
13
  To change this value, please see `config.vagrant.dotfile_name`
14
+
15
+ This often exists if you're trying to create a Vagrant virtual
16
+ environment from your home directory. To resolve this, you can either
17
+ modify the configuration a bit, or simply use a different directory.
14
18
  msg
15
19
  end
16
20
 
17
21
  # Up is a "meta-action" so it really just queues up a bunch
18
22
  # of other actions in its place:
19
- steps = [Import, ForwardPorts, SharedFolders, Boot]
20
- steps << Provision if Vagrant.config.chef.enabled
23
+ steps = [Import, Customize, ForwardPorts, SharedFolders, Boot]
24
+ steps << Provision if !Vagrant.config.vm.provisioner.nil?
21
25
  steps.insert(0, MoveHardDrive) if Vagrant.config.vm.hd_location
22
26
 
23
27
  steps.each do |action_klass|
@@ -31,8 +35,8 @@ msg
31
35
  end
32
36
 
33
37
  def persist
34
- logger.info "Persisting the VM UUID (#{@runner.vm.uuid})..."
35
- Env.persist_vm(@runner.vm)
38
+ logger.info "Persisting the VM UUID (#{@runner.uuid})..."
39
+ Env.persist_vm(@runner)
36
40
  end
37
41
 
38
42
  def setup_mac_address
@@ -0,0 +1,66 @@
1
+ module Vagrant
2
+ # This class represents the active list of vagrant virtual
3
+ # machines.
4
+ class ActiveList
5
+ FILENAME = "active.json"
6
+
7
+ @@list = nil
8
+
9
+ class <<self
10
+ # Parses and returns the list of UUIDs from the active VM
11
+ # JSON file. This will cache the result, which can be reloaded
12
+ # by setting the `reload` parameter to true.
13
+ #
14
+ # @return [Array<String>]
15
+ def list(reload = false)
16
+ return @@list unless @@list.nil? || reload
17
+
18
+ @@list ||= []
19
+ return @@list unless File.file?(path)
20
+ File.open(path, "r") do |f|
21
+ @@list = JSON.parse(f.read)
22
+ end
23
+
24
+ @@list
25
+ end
26
+
27
+ # Returns an array of {Vagrant::VM} objects which are currently
28
+ # active.
29
+ def vms
30
+ list.collect { |uuid| Vagrant::VM.find(uuid) }.compact
31
+ end
32
+
33
+ # Returns an array of UUIDs filtered so each is verified to exist.
34
+ def filtered_list
35
+ vms.collect { |vm| vm.uuid }
36
+ end
37
+
38
+ # Adds a virtual environment to the list of active virtual machines
39
+ def add(vm)
40
+ list << vm.uuid
41
+ list.uniq!
42
+ save
43
+ end
44
+
45
+ # Remove a virtual environment from the list of active virtual machines
46
+ def remove(vm)
47
+ vm = vm.uuid if vm.is_a?(Vagrant::VM)
48
+ list.delete(vm)
49
+ save
50
+ end
51
+
52
+ # Persists the list down to the JSON file.
53
+ def save
54
+ File.open(path, "w+") do |f|
55
+ f.write(filtered_list.to_json)
56
+ end
57
+ end
58
+
59
+ # Returns the path to the JSON file which holds the UUIDs of the
60
+ # active virtual machines managed by Vagrant.
61
+ def path
62
+ File.join(Env.home_path, FILENAME)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -24,6 +24,49 @@ error
24
24
  FileUtils.cp(File.join(PROJECT_ROOT, "templates", Env::ROOTFILE_NAME), rootfile_path)
25
25
  end
26
26
 
27
+ # Outputs the status of the current environment. This command outputs
28
+ # useful information such as whether or not the environment is created
29
+ # and if its running, suspended, etc.
30
+ def status
31
+ Env.load!
32
+
33
+ wrap_output do
34
+ if !Env.persisted_vm
35
+ puts <<-msg
36
+ The environment has not yet been created. Run `vagrant up` to create the
37
+ environment.
38
+ msg
39
+ else
40
+ additional_msg = ""
41
+ if Env.persisted_vm.vm.running?
42
+ additional_msg = <<-msg
43
+ To stop this VM, you can run `vagrant halt` to shut it down forcefully,
44
+ or you can run `vagrant suspend` to simply suspend the virtual machine.
45
+ In either case, to restart it again, simply run a `vagrant up`.
46
+ msg
47
+ elsif Env.persisted_vm.vm.saved?
48
+ additional_msg = <<-msg
49
+ To resume this VM, simply run `vagrant up`.
50
+ msg
51
+ elsif Env.persisted_vm.vm.powered_off?
52
+ additional_msg = <<-msg
53
+ To restart this VM, simply run `vagrant up`.
54
+ msg
55
+ end
56
+
57
+ if !additional_msg.empty?
58
+ additional_msg.chomp!
59
+ additional_msg = "\n\n#{additional_msg}"
60
+ end
61
+
62
+ puts <<-msg
63
+ The environment has been created. The status of the current environment's
64
+ virtual machine is: "#{Env.persisted_vm.vm.state}."#{additional_msg}
65
+ msg
66
+ end
67
+ end
68
+ end
69
+
27
70
  # Bring up a vagrant instance. This handles everything from importing
28
71
  # the base VM, setting up shared folders, forwarded ports, etc to
29
72
  # provisioning the instance with chef. {up} also starts the instance,
@@ -139,6 +182,7 @@ Please specify a valid action to take on the boxes, either
139
182
 
140
183
  vagrant box add name uri
141
184
  vagrant box remove name
185
+ vagrant box list
142
186
  error
143
187
  end
144
188
 
@@ -4,32 +4,30 @@ module Vagrant
4
4
  end
5
5
 
6
6
  class Config
7
- @config = nil
8
- @config_runners = []
7
+ extend StackedProcRunner
8
+
9
+ @@config = nil
9
10
 
10
11
  class << self
11
12
  def reset!
12
- @config = nil
13
- config_runners.clear
13
+ @@config = nil
14
+ proc_stack.clear
14
15
  end
15
16
 
16
- def config
17
- @config ||= Config::Top.new
17
+ def configures(key, klass)
18
+ config.class.configures(key, klass)
18
19
  end
19
20
 
20
- def config_runners
21
- @config_runners ||= []
21
+ def config
22
+ @@config ||= Config::Top.new
22
23
  end
23
24
 
24
25
  def run(&block)
25
- config_runners << block
26
+ push_proc(&block)
26
27
  end
27
28
 
28
29
  def execute!
29
- config_runners.each do |block|
30
- block.call(config)
31
- end
32
-
30
+ run_procs!(config)
33
31
  config.loaded!
34
32
  end
35
33
  end
@@ -60,20 +58,32 @@ module Vagrant
60
58
  attr_accessor :forwarded_port_key
61
59
  attr_accessor :max_tries
62
60
  attr_accessor :timeout
61
+ attr_accessor :private_key_path
62
+
63
+ def private_key_path
64
+ File.expand_path(@private_key_path, Env.root_path)
65
+ end
63
66
  end
64
67
 
65
68
  class VMConfig < Base
69
+ include StackedProcRunner
70
+
66
71
  attr_accessor :box
67
72
  attr_accessor :box_ovf
68
73
  attr_accessor :base_mac
69
74
  attr_accessor :project_directory
70
75
  attr_reader :forwarded_ports
76
+ attr_reader :shared_folders
71
77
  attr_accessor :hd_location
72
78
  attr_accessor :disk_image_format
73
-
79
+ attr_accessor :provisioner
80
+ attr_accessor :shared_folder_uid
81
+ attr_accessor :shared_folder_gid
74
82
 
75
83
  def initialize
76
84
  @forwarded_ports = {}
85
+ @shared_folders = {}
86
+ @provisioner = nil
77
87
  end
78
88
 
79
89
  def forward_port(name, guestport, hostport, protocol="TCP")
@@ -84,13 +94,28 @@ module Vagrant
84
94
  }
85
95
  end
86
96
 
97
+ def share_folder(name, guestpath, hostpath)
98
+ @shared_folders[name] = {
99
+ :guestpath => guestpath,
100
+ :hostpath => hostpath
101
+ }
102
+ end
103
+
87
104
  def hd_location=(val)
88
- raise Exception.new "disk_storage must be set to a directory" unless File.directory?(val)
105
+ raise Exception.new("disk_storage must be set to a directory") unless File.directory?(val)
89
106
  @hd_location=val
90
107
  end
91
108
 
92
- def base
93
- File.expand_path(@base)
109
+ def shared_folder_uid
110
+ @shared_folder_uid || Vagrant.config.ssh.username
111
+ end
112
+
113
+ def shared_folder_gid
114
+ @shared_folder_gid || Vagrant.config.ssh.username
115
+ end
116
+
117
+ def customize(&block)
118
+ push_proc(&block)
94
119
  end
95
120
  end
96
121
 
@@ -99,48 +124,40 @@ module Vagrant
99
124
  attr_accessor :extension
100
125
  end
101
126
 
102
- class ChefConfig < Base
103
- attr_accessor :cookbooks_path
104
- attr_accessor :provisioning_path
105
- attr_accessor :json
106
- attr_accessor :enabled
107
-
108
- def initialize
109
- @enabled = false
110
- end
111
-
112
- def to_json
113
- # Overridden so that the 'json' key could be removed, since its just
114
- # merged into the config anyways
115
- data = instance_variables_hash
116
- data.delete(:json)
117
- data.to_json
118
- end
119
- end
120
-
121
127
  class VagrantConfig < Base
122
128
  attr_accessor :dotfile_name
123
129
  attr_accessor :log_output
124
130
  attr_accessor :home
125
131
 
126
132
  def home
127
- File.expand_path(@home)
133
+ @home ? File.expand_path(@home) : nil
128
134
  end
129
135
  end
130
136
 
131
137
  class Top < Base
132
- attr_reader :package
133
- attr_reader :ssh
134
- attr_reader :vm
135
- attr_reader :chef
136
- attr_reader :vagrant
138
+ @@configures = []
139
+
140
+ class <<self
141
+ def configures_list
142
+ @@configures ||= []
143
+ end
144
+
145
+ def configures(key, klass)
146
+ configures_list << [key, klass]
147
+ attr_reader key.to_sym
148
+ end
149
+ end
150
+
151
+ # Setup default configures
152
+ configures :package, PackageConfig
153
+ configures :ssh, SSHConfig
154
+ configures :vm, VMConfig
155
+ configures :vagrant, VagrantConfig
137
156
 
138
157
  def initialize
139
- @ssh = SSHConfig.new
140
- @vm = VMConfig.new
141
- @chef = ChefConfig.new
142
- @vagrant = VagrantConfig.new
143
- @package = PackageConfig.new
158
+ self.class.configures_list.each do |key, klass|
159
+ instance_variable_set("@#{key}".to_sym, klass.new)
160
+ end
144
161
 
145
162
  @loaded = false
146
163
  end