class VagrantVbguest::Installers::Linux

A basic Installer implementation for vanilla or unknown Linux based systems.

Public Class Methods

match?(vm) click to toggle source

Matches if the operating system name prints “Linux” Raises an Error if this class is beeing subclassed but this method was not overridden. This is considered an error because, subclassed Installers usually indicate a more specific distributen like ‘ubuntu’ or ‘arch’ and therefore should do a more specific check.

# File lib/vagrant-vbguest/installers/linux.rb, line 14
def self.match?(vm)
  raise Error, :_key => :do_not_inherit_match_method if self != Linux
  communicate_to(vm).test("uname | grep 'Linux'")
end
os_release(vm) click to toggle source

Reads the ‘/etc/os-release` for the given `Vagrant::VM` if present, and returns it’s config as a parsed Hash. The result is cached on a per-vm basis.

@return [Hash|nil] The os-release configuration as Hash, or ‘nil if file is not present or not parsable.

# File lib/vagrant-vbguest/installers/linux.rb, line 23
def self.os_release(vm)
  @@os_release_info ||= {}
  if !@@os_release_info.has_key?(vm_id(vm)) && communicate_to(vm).test("test -f /etc/os-release")
    osr_raw = communicate_to(vm).download("/etc/os-release")
    osr_parsed = begin
      VagrantVbguest::Helpers::OsRelease::Parser.(osr_raw)
    rescue VagrantVbguest::Helpers::OsRelease::FormatError => e
      vm.env.ui.warn(e.message)
      nil
    end
    @@os_release_info[vm_id(vm)] = osr_parsed
  end
  @@os_release_info[vm_id(vm)]
end

Public Instance Methods

cleanup(opts=nil, &block) click to toggle source
# File lib/vagrant-vbguest/installers/linux.rb, line 288
def cleanup(opts=nil, &block)
  unless options[:no_cleanup]
    unmount_iso(opts, &block)
    super
  end
end
execute_installer(opts=nil, &block) click to toggle source

A generic helper method to execute the installer. This also yields a installation warning to the user, and an error warning in the event that the installer returns a non-zero exit status.

@param opts [Hash] Optional options Hash wich meight get passed to {Vagrant::Communication::SSH#execute} and firends @yield [type, data] Takes a Block like {Vagrant::Communication::Base#execute} for realtime output of the command being executed @yieldparam [String] type Type of the output, ‘:stdout`, `:stderr`, etc. @yieldparam [String] data Data for the given output.

# File lib/vagrant-vbguest/installers/linux.rb, line 226
def execute_installer(opts=nil, &block)
  yield_installation_warning(installer)
  opts = {:error_check => false}.merge(opts || {})
  exit_status = communicate.sudo("#{yes}#{installer} #{installer_arguments}", opts, &block)
  yield_installation_error_warning(installer) unless exit_status == 0
  exit_status
end
find_tool(tool) click to toggle source

Checks for the correct location of the tool provided. It checks for a given list of possible locations. This list got extracted from the ‘VBoxLinuxAdditions.run’ script.

@return [String|nil] Absolute path to the tool,

or +nil+ if none found.
# File lib/vagrant-vbguest/installers/linux.rb, line 190
      def find_tool(tool)
        candidates = [
          "/usr/lib/i386-linux-gnu/VBoxGuestAdditions/#{tool}",
          "/usr/lib/x86_64-linux-gnu/VBoxGuestAdditions/#{tool}",
          "/usr/lib64/VBoxGuestAdditions/#{tool}",
          "/usr/lib/VBoxGuestAdditions/#{tool}",
          "/lib64/VBoxGuestAdditions/#{tool}",
          "/lib/VBoxGuestAdditions/#{tool}",
          "/etc/init.d/#{tool}",
          "/usr/sbin/rc#{tool}",
          "/sbin/rc#{tool}"
        ]
        cmd = <<-SHELL
        for c in #{candidates.join(" ")}; do
          if test -x "$c"; then
            echo $c
            break
          fi
        done
        SHELL

        path = nil
        communicate.sudo(cmd, {:error_check => false}) do |type, data|
          path = data.strip unless data.empty?
        end
        path
      end
guest_version(reload = false) click to toggle source

This overrides {VagrantVbguest::Installers::Base#guest_version} to also query the ‘VBoxService` on the host system (if available) for it’s version. In some scenarios the results of the VirtualBox driver and the additions installed on the host may differ. If this happens, we assume, that the host binaries are right and yield a warning message.

@return [Gem::Version] The version code of the VirtualBox Guest Additions

available on the guest, or `nil` if none installed.
# File lib/vagrant-vbguest/installers/linux.rb, line 102
def guest_version(reload = false)
  return @guest_version if @guest_version && !reload
  driver_version = VagrantVbguest::Version(super)

  communicate.sudo('VBoxService --version', :error_check => false) do |type, data|
    service_version = VagrantVbguest::Version(data)
    if service_version
      if driver_version != service_version
        @env.ui.warn(I18n.t("vagrant_vbguest.guest_version_reports_differ", :driver => driver_version, :service => service_version))
      end
      @guest_version = service_version
    end
  end
  @guest_version
end
install(opts=nil, &block) click to toggle source

a generic way of installing GuestAdditions assuming all dependencies on the guest are installed

@param opts [Hash] Optional options Hash wich meight get passed to {Vagrant::Communication::SSH#execute} and firends @yield [type, data] Takes a Block like {Vagrant::Communication::Base#execute} for realtime output of the command being executed @yieldparam [String] type Type of the output, ‘:stdout`, `:stderr`, etc. @yieldparam [String] data Data for the given output.

# File lib/vagrant-vbguest/installers/linux.rb, line 64
def install(opts=nil, &block)
  env.ui.warn I18n.t("vagrant_vbguest.errors.installer.generic_linux_installer", distro: self.class.distro(vm)) if self.class == Linux
  upload(iso_file)
  mount_iso(opts, &block)
  execute_installer(opts, &block)
  start(opts, &block)
end
installer() click to toggle source

The absolute path to the GuestAdditions installer script. The iso file has to be mounted on mount_point.

# File lib/vagrant-vbguest/installers/linux.rb, line 236
def installer
  @installer ||= File.join(mount_point, 'VBoxLinuxAdditions.run')
end
installer_arguments() click to toggle source

The arguments string, which gets passed to the installer script

# File lib/vagrant-vbguest/installers/linux.rb, line 241
def installer_arguments
  @installer_arguments ||= Array(options[:installer_arguments]).join " "
end
installer_options() click to toggle source
# File lib/vagrant-vbguest/installers/linux.rb, line 245
def installer_options
  @installer_options ||= {
    running_kernel_modules: ["vboxguest", "vboxsf"]
  }.merge!(super)
end
mount_iso(opts=nil, &block) click to toggle source

A generic helper method for mounting the GuestAdditions iso file on most linux system. Mounts the given uploaded file from tmp_path on mount_point.

@param opts [Hash] Optional options Hash wich meight get passed to {Vagrant::Communication::SSH#execute} and firends @yield [type, data] Takes a Block like {Vagrant::Communication::Base#execute} for realtime output of the command being executed @yieldparam [String] type Type of the output, ‘:stdout`, `:stderr`, etc. @yieldparam [String] data Data for the given output.

# File lib/vagrant-vbguest/installers/linux.rb, line 270
def mount_iso(opts=nil, &block)
  env.ui.info(I18n.t("vagrant_vbguest.mounting_iso", :mount_point => mount_point))
  communicate.sudo("mount #{tmp_path} -o loop #{mount_point}", opts, &block)
end
mount_point() click to toggle source

Mount point for the iso file. Configurable via ‘config.vbguest.iso_mount_point`. defaults to “/mnt” for all Linux based systems.

# File lib/vagrant-vbguest/installers/linux.rb, line 53
def mount_point
  options[:iso_mount_point] || '/mnt'
end
os_release() click to toggle source
# File lib/vagrant-vbguest/installers/linux.rb, line 38
def os_release
  self.class.os_release(vm)
end
provides_vboxadd_tools?() click to toggle source
# File lib/vagrant-vbguest/installers/linux.rb, line 147
def provides_vboxadd_tools?
  true
end
rebuild(opts=nil, &block) click to toggle source

@param opts [Hash] Optional options Hash wich meight get passed to {Vagrant::Communication::SSH#execute} and firends @yield [type, data] Takes a Block like {Vagrant::Communication::Base#execute} for realtime output of the command being executed @yieldparam [String] type Type of the output, ‘:stdout`, `:stderr`, etc. @yieldparam [String] data Data for the given output.

# File lib/vagrant-vbguest/installers/linux.rb, line 122
def rebuild(opts=nil, &block)
  communicate.sudo("#{find_tool('vboxadd')} setup", opts, &block)
end
running?(opts=nil, &block) click to toggle source

@param opts [Hash] Optional options Hash wich meight get passed to {Vagrant::Communication::SSH#execute} and firends @yield [type, data] Takes a Block like {Vagrant::Communication::Base#execute} for realtime output of the command being executed @yieldparam [String] type Type of the output, ‘:stdout`, `:stderr`, etc. @yieldparam [String] data Data for the given output.

# File lib/vagrant-vbguest/installers/linux.rb, line 76
def running?(opts=nil, &block)
  kmods = nil
  communicate.sudo('cat /proc/modules', opts) do |type, data|
    block.call(type, data) if block
    kmods = data if type == :stdout && data
  end

  unless kmods
    env.ui.warn "Could not read /proc/modules"
    return true
  end

  Array(installer_options[:running_kernel_modules]).all? do |mod|
    /^#{mod}\b/i.match(kmods)
  end
end
start(opts=nil, &block) click to toggle source

@param opts [Hash] Optional options Hash wich meight get passed to {Vagrant::Communication::SSH#execute} and firends @yield [type, data] Takes a Block like {Vagrant::Communication::Base#execute} for realtime output of the command being executed @yieldparam [String] type Type of the output, ‘:stdout`, `:stderr`, etc. @yieldparam [String] data Data for the given output.

# File lib/vagrant-vbguest/installers/linux.rb, line 130
def start(opts=nil, &block)
  opts = {:error_check => false}.merge(opts || {})
  if systemd_tool
    communicate.sudo("#{systemd_tool[:path]} vboxadd #{systemd_tool[:up]}", opts, &block)
  else
    communicate.sudo("#{find_tool('vboxadd')} start", opts, &block)
  end

  if guest_version && guest_version >= Gem::Version.new('5.1')
    if systemd_tool
      communicate.sudo("#{systemd_tool[:path]} vboxadd-service #{systemd_tool[:up]}", opts, &block)
    else
      communicate.sudo("#{find_tool('vboxadd-service')} start", opts, &block)
    end
  end
end
systemd_tool() click to toggle source

Check for the presence of ‘systemd’ chkconfg or service command.

systemd_tool # => {:path=>"/usr/sbin/service", :up=>"start"}

@return [Hash|nil] Hash with an absolute path to the tool and the

command string for starting.
+nil* if neither was found.
# File lib/vagrant-vbguest/installers/linux.rb, line 162
def systemd_tool
  return nil if @systemd_tool == false

  result = nil
  communicate.sudo('(which chkconfg || which service) 2>/dev/null', {:error_check => false}) do |type, data|
    path = data.to_s.strip
    case path
    when /\bservice\b/
      result = { path: path, up: "start", down: "stop" }
    when /\bchkconfg\b/
      result = { path: path, up: "on", down: "off" }
    end
  end

  if result.nil?
    @systemd_tool = false
    nil
  else
    @systemd_tool = result
  end
end
tmp_path() click to toggle source

The temporary path where to upload the iso file to. Configurable via ‘config.vbguest.iso_upload_path`. Defaults the temp path to `/tmp/VBoxGuestAdditions.iso“ for all Linux based systems

# File lib/vagrant-vbguest/installers/linux.rb, line 46
def tmp_path
  options[:iso_upload_path] || '/tmp/VBoxGuestAdditions.iso'
end
unmount_iso(opts=nil, &block) click to toggle source

A generic helper method for un-mounting the GuestAdditions iso file on most linux system Unmounts the mount_point.

@param opts [Hash] Optional options Hash wich meight get passed to {Vagrant::Communication::SSH#execute} and firends @yield [type, data] Takes a Block like {Vagrant::Communication::Base#execute} for realtime output of the command being executed @yieldparam [String] type Type of the output, ‘:stdout`, `:stderr`, etc. @yieldparam [String] data Data for the given output.

# File lib/vagrant-vbguest/installers/linux.rb, line 283
def unmount_iso(opts=nil, &block)
  env.ui.info(I18n.t("vagrant_vbguest.unmounting_iso", :mount_point => mount_point))
  communicate.sudo("umount #{mount_point}", opts, &block)
end
vboxadd_tools_available?() click to toggle source
# File lib/vagrant-vbguest/installers/linux.rb, line 151
def vboxadd_tools_available?
  !!find_tool('vboxadd') || communicate.test('systemctl list-units --type service | grep -q vboxadd', {:sudo => true})
end
yes() click to toggle source

Determine if yes needs to be called or not

# File lib/vagrant-vbguest/installers/linux.rb, line 252
def yes
  value = @options[:yes]
  # Simple yes if explicitly boolean true
  return "yes | " if !!value == value && value
  # Nothing if set to false
  return "" if !value
  # Otherwise pass input string to yes
  "yes #{value} | "
end