Skip to content
This repository
Browse code

major rewrite on how to deal with installers.

- no longer using shell scripts to upload into the box.
- provide a config options to mount a custom Installer class into vagrant-vbguest
  • Loading branch information...
commit 43d343a7cd6379250edf2ae8f4a4c2147e7f84d6 1 parent 8c85649
Robert Schulze fnordfish authored
5 files/setup_debian.sh
... ... @@ -1,5 +0,0 @@
1   -#!/bin/bash
2   -apt-get install -y linux-headers-`uname -r` dkms
3   -mount /tmp/VBoxGuestAdditions.iso -o loop /mnt
4   -/mnt/VBoxLinuxAdditions.run --nox11
5   -umount /mnt
4 files/setup_linux.sh
... ... @@ -1,4 +0,0 @@
1   -#!/bin/bash
2   -mount /tmp/VBoxGuestAdditions.iso -o loop /mnt
3   -/mnt/VBoxLinuxAdditions.run --nox11
4   -umount /mnt
25 lib/vagrant-vbguest.rb
... ... @@ -1,20 +1,25 @@
1 1 require 'vagrant'
2   -require "vagrant-vbguest/errors"
  2 +require 'vagrant-vbguest/errors'
  3 +
  4 +require 'vagrant-vbguest/installer'
  5 +require 'vagrant-vbguest/installers/base'
  6 +require 'vagrant-vbguest/installers/linux'
  7 +require 'vagrant-vbguest/installers/debian'
  8 +require 'vagrant-vbguest/installers/ubuntu'
  9 +
  10 +require 'vagrant-vbguest/action'
  11 +require 'vagrant-vbguest/config'
  12 +require 'vagrant-vbguest/command'
  13 +
  14 +require 'vagrant-vbguest/detector'
  15 +require 'vagrant-vbguest/download'
  16 +
3 17
4 18 # Add our custom translations to the load path
5 19 I18n.load_path << File.expand_path("../../locales/en.yml", __FILE__)
6 20
7 21 module VagrantVbguest
8 22
9   - autoload :Action, 'vagrant-vbguest/action'
10   - autoload :Config, 'vagrant-vbguest/config'
11   - autoload :Command, 'vagrant-vbguest/command'
12   - autoload :Errors, 'vagrant-vbguest/errors'
13   -
14   - autoload :Detector, "vagrant-vbguest/detector"
15   - autoload :Download, "vagrant-vbguest/download"
16   - autoload :Installer, "vagrant-vbguest/installer"
17   -
18 23 class Plugin < Vagrant.plugin("1")
19 24 name "vbguest management"
20 25 description <<-DESC
12 lib/vagrant-vbguest/config.rb
... ... @@ -1,10 +1,13 @@
1 1 module VagrantVbguest
2 2
3 3 class Config < Vagrant::Config::Base
4   - attr_accessor :iso_path
5   - attr_accessor :auto_update
6   - attr_accessor :no_install
7   - attr_accessor :no_remote
  4 + attr_accessor :iso_path, :auto_update, :installer, :no_install, :no_remote
  5 +
  6 + def validate(env, errors)
  7 + if !installer.nil? && (!installer.is_a?(Class) || installer <= Installer::Base)
  8 + errors.add I18n.t("vagrant.plugins.vbguest.invalid_installer_class")
  9 + end
  10 + end
8 11
9 12 def auto_update; @auto_update.nil? ? (@auto_update = true) : @auto_update; end
10 13 def no_remote; @no_remote.nil? ? (@no_remote = false) : @no_remote; end
@@ -15,6 +18,7 @@ def to_hash
15 18 {
16 19 :iso_path => iso_path,
17 20 :auto_update => auto_update,
  21 + :installer => installer,
18 22 :no_install => no_install,
19 23 :no_remote => no_remote
20 24 }
4 lib/vagrant-vbguest/detector.rb
@@ -14,7 +14,7 @@ def iso_path
14 14 private
15 15
16 16 def autodetect_iso
17   - path = media_manager_iso || guess_iso || web_iso
  17 + path = media_manager_iso || guess_iso || (!@options[:no_remote] && web_iso)
18 18 raise VagrantVbguest::Errors::IsoPathAutodetectionError if !path || path.empty?
19 19 path
20 20 end
@@ -35,7 +35,7 @@ def guess_iso
35 35 end
36 36
37 37 def web_iso
38   - "http://download.virtualbox.org/virtualbox/$VBOX_VERSION/VBoxGuestAdditions_$VBOX_VERSION.iso" unless @options[:no_remote]
  38 + "http://download.virtualbox.org/virtualbox/$VBOX_VERSION/VBoxGuestAdditions_$VBOX_VERSION.iso"
39 39 end
40 40
41 41 end
59 lib/vagrant-vbguest/installer.rb
@@ -4,6 +4,22 @@ module VagrantVbguest
4 4
5 5 class Installer
6 6
  7 + class << self
  8 + def register(installer_class, prio = 5)
  9 + @installers ||= {}
  10 + @installers[prio] ||= []
  11 + @installers[prio] << installer_class
  12 + end
  13 +
  14 + def detect(vm)
  15 + @installers.keys.sort.reverse.each do |prio|
  16 + klass = @installers[prio].detect { |k| k.match?(vm) }
  17 + return klass.new(vm) if klass
  18 + end
  19 + return nil
  20 + end
  21 + end
  22 +
7 23 def initialize(vm, options = {})
8 24 @env = {
9 25 :ui => vm.ui,
@@ -32,26 +48,16 @@ def run
32 48 if @options[:force] || (!@options[:no_install] && needs_update?)
33 49 @vm.ui.warn(I18n.t("vagrant.plugins.vbguest.installing#{@options[:force] ? '_forced' : ''}", :host => vb_version, :guest => guest_version))
34 50
35   - # :TODO:
36   - # the whole installation process should be put into own classes
37   - # like the vagrant system loading
38   - if (i_script = installer_script)
  51 + if (installer = guest_installer)
39 52 @options[:iso_path] ||= VagrantVbguest::Detector.new(@vm, @options).iso_path
40 53
41   - @vm.ui.info(I18n.t("vagrant.plugins.vbguest.start_copy_iso", :from => iso_path, :to => iso_destination))
42   - @vm.channel.upload(iso_path, iso_destination)
43   -
44   - @vm.ui.info(I18n.t("vagrant.plugins.vbguest.start_copy_script", :from => File.basename(i_script), :to => installer_destination))
45   - @vm.channel.upload(i_script, installer_destination)
46   -
47   - @vm.channel.sudo("sh #{installer_destination}") do |type, data|
  54 + installer.install(iso_path) do |type, data|
48 55 @vm.ui.info(data, :prefix => false, :new_line => false)
49 56 end
50   -
51   - @vm.channel.execute("rm #{installer_destination} #{iso_destination}") do |type, data|
52   - @vm.ui.error(data.chomp, :prefix => false)
53   - end
  57 + else
  58 + @vm.ui.error(I18n.t("vagrant.plugins.vbguest.no_install_script_for_platform"))
54 59 end
  60 +
55 61 end
56 62 end
57 63 ensure
@@ -71,28 +77,14 @@ def vb_version
71 77 @vm.driver.version
72 78 end
73 79
74   - def installer_script
75   - platform = @vm.guest.distro_dispatch
76   - case platform
77   - when :debian, :ubuntu
78   - File.expand_path("../../../files/setup_debian.sh", __FILE__)
79   - when :gentoo, :redhat, :suse, :arch, :linux
80   - @vm.ui.warn(I18n.t("vagrant.plugins.vbguest.generic_install_script_for_platform", :platform => platform.to_s))
81   - File.expand_path("../../../files/setup_linux.sh", __FILE__)
  80 + def guest_installer
  81 + if @options[:installer]
  82 + @options[:installer].new(@vm)
82 83 else
83   - @vm.ui.error(I18n.t("vagrant.plugins.vbguest.no_install_script_for_platform", :platform => platform.to_s))
84   - nil
  84 + Installer.detect(@vm)
85 85 end
86 86 end
87 87
88   - def installer_destination
89   - '/tmp/install_vbguest.sh'
90   - end
91   -
92   - def iso_destination
93   - '/tmp/VBoxGuestAdditions.iso'
94   - end
95   -
96 88 def iso_path
97 89 @iso_path ||= begin
98 90 @env[:iso_url] ||= @options[:iso_path].gsub '$VBOX_VERSION', vb_version
@@ -119,3 +111,4 @@ def cleanup
119 111
120 112 end
121 113 end
  114 +
34 lib/vagrant-vbguest/installers/base.rb
... ... @@ -0,0 +1,34 @@
  1 +module VagrantVbguest
  2 + module Installers
  3 + class Base
  4 +
  5 + def self.match?(vm)
  6 + nil
  7 + end
  8 +
  9 + attr_reader :vm
  10 +
  11 + def initialize(vm)
  12 + @vm = vm
  13 + end
  14 +
  15 + def upload(file)
  16 + @vm.ui.info(I18n.t("vagrant.plugins.vbguest.start_copy_iso", :from => file, :to => tmp_path))
  17 + @vm.channel.upload(file, tmp_path)
  18 + end
  19 +
  20 + def cleanup
  21 + @vm.channel.execute("rm #{tmp_path}") do |type, data|
  22 + @vm.ui.error(data.chomp, :prefix => false)
  23 + end
  24 + end
  25 +
  26 + def tmp_path
  27 + end
  28 +
  29 + def install(iso_file, opts=nil, &block)
  30 + end
  31 +
  32 + end
  33 + end
  34 +end
21 lib/vagrant-vbguest/installers/debian.rb
... ... @@ -0,0 +1,21 @@
  1 +module VagrantVbguest
  2 + module Installers
  3 + class Debian < Linux
  4 +
  5 + def self.match?(vm)
  6 + :debian == self.distro(vm)
  7 + end
  8 +
  9 + def install(iso_file, opts=nil, &block)
  10 + upload(iso_file)
  11 + vm.channel.sudo('apt-get install -y linux-headers-`uname -r` dkms', opts, &block)
  12 + vm.channel.sudo("mount #{tmp_path} -o loop #{mount_point}", opts, &block)
  13 + vm.channel.sudo("#{mount_point}/VBoxLinuxAdditions.run --nox11", opts, &block)
  14 + vm.channel.sudo("umount #{mount_point}", opts, &block)
  15 + cleanup
  16 + end
  17 +
  18 + end
  19 + end
  20 +end
  21 +VagrantVbguest::Installer.register(VagrantVbguest::Installers::Debian, 5)
34 lib/vagrant-vbguest/installers/linux.rb
... ... @@ -0,0 +1,34 @@
  1 +module VagrantVbguest
  2 + module Installers
  3 + class Linux < Base
  4 +
  5 + def self.distro(vm)
  6 + @@ditro ||= {}
  7 + @@ditro[vm.uuid] ||= vm.guest.distro_dispatch
  8 + end
  9 +
  10 + def self.match?(vm)
  11 + vm.channel.test("uname | grep 'Linux'")
  12 + end
  13 +
  14 + def tmp_path
  15 + '/tmp/VBoxGuestAdditions.iso'
  16 + end
  17 +
  18 + def mount_point
  19 + '/mnt'
  20 + end
  21 +
  22 + def install(iso_file, opts=nil, &block)
  23 + @vm.ui.warn I18n.t("vagrant.plugins.vbguest.generic_linux_installer")
  24 + upload(iso_file)
  25 + vm.channel.sudo("mount #{tmp_path} -o loop #{mount_point}", opts, &block)
  26 + vm.channel.sudo("#{mount_point}/VBoxLinuxAdditions.run --nox11", opts, &block)
  27 + vm.channel.sudo("umount #{mount_point}", opts, &block)
  28 + cleanup
  29 + end
  30 +
  31 + end
  32 + end
  33 +end
  34 +VagrantVbguest::Installer.register(VagrantVbguest::Installers::Linux, 2)
12 lib/vagrant-vbguest/installers/ubuntu.rb
... ... @@ -0,0 +1,12 @@
  1 +module VagrantVbguest
  2 + module Installers
  3 + class Ubuntu < Debian
  4 +
  5 + def self.match?(vm)
  6 + :ubuntu == self.distro(vm)
  7 + end
  8 +
  9 + end
  10 + end
  11 +end
  12 +VagrantVbguest::Installer.register(VagrantVbguest::Installers::Ubuntu, 5)
9 locales/en.yml
@@ -8,8 +8,8 @@ en:
8 8 installing_forced: "Forcing installation of Virtualbox Guest Additions %{host} - guest's version is %{guest}"
9 9 start_copy_iso: "Copy iso file %{from} into the box %{to}"
10 10 start_copy_script: "Copy installer file %{from} into the box %{to}"
11   - no_install_script_for_platform: "Sorry, don't know how to install on a %{platform} system. Stopping installation."
12   - generic_install_script_for_platform: "%{platform} is currently not supported, will try generic Linux method..."
  11 + no_install_script_for_platform: "Sorry, don't know how to install on a this platform. Stopping installation."
  12 + generic_linux_installer: "The guest's platform is currently not supported, will try generic Linux method..."
13 13
14 14 errors:
15 15 autodetect_iso_path: |-
@@ -26,6 +26,11 @@ en:
26 26 Please configure a local path to the iso using `config.vbguest.iso_path`
27 27 in your Vagrantfile or the `--iso` command line option.
28 28
  29 + config:
  30 + errors:
  31 + invalid_installer_class: |-
  32 + The specified installer does not inherit from `VagrantVbguest::Installer::Base`
  33 +
29 34 download:
30 35 with: "Downloading VirtualBox Guest Additions ISO with %{class}..."
31 36 cleaning: "Cleaning up downloaded VirtualBox Guest Additions ISO..."

2 comments on commit 43d343a

Matthias Günther

All in all, a great commit and huge benefit for the Vagrant Community

Robert Schulze

It's kind of an "abstract" method. It just declares the signature.

Matthias Günther

Okay :) - a small comment wouldn't be so wrong!

Robert Schulze

full-ack. need to do some API doc all over the place.

Matthias Günther

Okay - take your time before moving on to create new features.

Please sign in to comment.
Something went wrong with that request. Please try again.