Class: VagrantVbguest::Installers::Linux

Inherits:
Base
  • Object
show all
Defined in:
lib/vagrant-vbguest/installers/linux.rb

Overview

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

Direct Known Subclasses

Debian, Fedora, OpenSuse, RedHat

Instance Attribute Summary

Attributes inherited from Base

#env, #host, #options, #vm

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#cleanup, #initialize, #installer_version, #iso_file, #upload, #yield_installation_error_warning, #yield_installation_waring, #yield_rebuild_warning

Methods included from Helpers::VmCompatible

#communicate, #driver, included

Constructor Details

This class inherits a constructor from VagrantVbguest::Installers::Base

Class Method Details

.distro(vm) ⇒ Symbol

A helper method to cache the result of Vagrant::Guest::Base#distro_dispatch which speeds up Installer detection runs a lot, when having lots of Linux based Installer classes to check.

Returns:

  • (Symbol)

    One of ‘:debian`, `:ubuntu`, `:gentoo`, `:fedora`, `:redhat`, `:suse`, `:arch`

See Also:

  • {Vagrant{Vagrant::Guest{Vagrant::Guest::Linux{Vagrant::Guest::Linux#distro_dispatch}


14
15
16
17
# File 'lib/vagrant-vbguest/installers/linux.rb', line 14

def self.distro(vm)
  @@ditro ||= {}
  @@ditro[ vm_id(vm) ] ||= distro_name vm
end

.match?(vm) ⇒ Boolean

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.

Returns:

  • (Boolean)

Raises:



25
26
27
28
# File 'lib/vagrant-vbguest/installers/linux.rb', line 25

def self.match?(vm)
  raise Error, :_key => :do_not_inherit_match_method if self != Linux
  communicate_to(vm).test("uname | grep 'Linux'")
end

Instance Method Details

#execute_installer(opts = nil) {|type, data| ... } ⇒ Object

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.

Parameters:

  • opts (Hash) (defaults to: nil)

    Optional options Hash wich meight get passed to Vagrant::Communication::SSH#execute and firends

Yields:

  • (type, data)

    Takes a Block like Vagrant::Communication::Base#execute for realtime output of the command being executed

Yield Parameters:

  • type (String)

    Type of the output, ‘:stdout`, `:stderr`, etc.

  • data (String)

    Data for the given output.



177
178
179
180
181
182
183
# File 'lib/vagrant-vbguest/installers/linux.rb', line 177

def execute_installer(opts=nil, &block)
  yield_installation_waring(installer)
  opts = {:error_check => false}.merge(opts || {})
  exit_status = communicate.sudo("#{installer} #{installer_arguments}", opts, &block)
  yield_installation_error_warning(installer) unless exit_status == 0
  exit_status
end

#guest_version(reload = false) ⇒ String

This overrides 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.

Returns:

  • (String)

    The version code of the VirtualBox Guest Additions available on the guest, or ‘nil` if none installed.



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/vagrant-vbguest/installers/linux.rb', line 80

def guest_version(reload = false)
  return @guest_version if @guest_version && !reload
  driver_version = super

  communicate.sudo('VBoxService --version', :error_check => false) do |type, data|
    if (v = data.to_s.match(/^(\d+\.\d+.\d+)/)) && driver_version != v[1]
      @env.ui.warn(I18n.t("vagrant_vbguest.guest_version_reports_differ", :driver => driver_version, :service => v[1]))
      @guest_version = v[1]
    end
  end
  @guest_version
end

#install(opts = nil) {|type, data| ... } ⇒ Object

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

Parameters:

  • opts (Hash) (defaults to: nil)

    Optional options Hash wich meight get passed to Vagrant::Communication::SSH#execute and firends

Yields:

  • (type, data)

    Takes a Block like Vagrant::Communication::Base#execute for realtime output of the command being executed

Yield Parameters:

  • type (String)

    Type of the output, ‘:stdout`, `:stderr`, etc.

  • data (String)

    Data for the given output.



52
53
54
55
56
57
58
# File 'lib/vagrant-vbguest/installers/linux.rb', line 52

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)
  unmount_iso(opts, &block) unless options[:no_cleanup]
end

#installerObject

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



187
188
189
# File 'lib/vagrant-vbguest/installers/linux.rb', line 187

def installer
  @installer ||= File.join(mount_point, 'VBoxLinuxAdditions.run')
end

#installer_argumentsObject

The arguments string, which gets passed to the installer script



192
193
194
# File 'lib/vagrant-vbguest/installers/linux.rb', line 192

def installer_arguments
  @installer_arguments ||= Array(options[:installer_arguments]).join " "
end

#mount_iso(opts = nil) {|type, data| ... } ⇒ Object

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.

Parameters:

  • opts (Hash) (defaults to: nil)

    Optional options Hash wich meight get passed to Vagrant::Communication::SSH#execute and firends

Yields:

  • (type, data)

    Takes a Block like Vagrant::Communication::Base#execute for realtime output of the command being executed

Yield Parameters:

  • type (String)

    Type of the output, ‘:stdout`, `:stderr`, etc.

  • data (String)

    Data for the given output.



204
205
206
# File 'lib/vagrant-vbguest/installers/linux.rb', line 204

def mount_iso(opts=nil, &block)
  communicate.sudo("mount #{tmp_path} -o loop #{mount_point}", opts, &block)
end

#mount_pointObject

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



41
42
43
# File 'lib/vagrant-vbguest/installers/linux.rb', line 41

def mount_point
  options[:iso_mount_point] || '/mnt'
end

#rebuild(opts = nil) {|type, data| ... } ⇒ Object

Parameters:

  • opts (Hash) (defaults to: nil)

    Optional options Hash wich meight get passed to Vagrant::Communication::SSH#execute and firends

Yields:

  • (type, data)

    Takes a Block like Vagrant::Communication::Base#execute for realtime output of the command being executed

Yield Parameters:

  • type (String)

    Type of the output, ‘:stdout`, `:stderr`, etc.

  • data (String)

    Data for the given output.



97
98
99
# File 'lib/vagrant-vbguest/installers/linux.rb', line 97

def rebuild(opts=nil, &block)
  communicate.sudo("#{vboxadd_tool} setup", opts, &block)
end

#running?(opts = nil) {|type, data| ... } ⇒ Boolean

Parameters:

  • opts (Hash) (defaults to: nil)

    Optional options Hash wich meight get passed to Vagrant::Communication::SSH#execute and firends

Yields:

  • (type, data)

    Takes a Block like Vagrant::Communication::Base#execute for realtime output of the command being executed

Yield Parameters:

  • type (String)

    Type of the output, ‘:stdout`, `:stderr`, etc.

  • data (String)

    Data for the given output.

Returns:

  • (Boolean)


64
65
66
67
68
69
# File 'lib/vagrant-vbguest/installers/linux.rb', line 64

def running?(opts=nil, &block)
  opts = {
    :sudo => true
  }.merge(opts || {})
  communicate.test('lsmod | grep vboxsf', opts, &block)
end

#start(opts = nil) {|type, data| ... } ⇒ Object

Parameters:

  • opts (Hash) (defaults to: nil)

    Optional options Hash wich meight get passed to Vagrant::Communication::SSH#execute and firends

Yields:

  • (type, data)

    Takes a Block like Vagrant::Communication::Base#execute for realtime output of the command being executed

Yield Parameters:

  • type (String)

    Type of the output, ‘:stdout`, `:stderr`, etc.

  • data (String)

    Data for the given output.



105
106
107
108
109
110
111
112
113
# File 'lib/vagrant-vbguest/installers/linux.rb', line 105

def start(opts=nil, &block)
  opts = {:error_check => false}.merge(opts || {})
  systemd = systemd_tool
  if systemd
    communicate.sudo("#{systemd[:path]} vboxadd #{systemd[:up]}", opts, &block)
  else
    communicate.sudo("#{vboxadd_tool} start", opts, &block)
  end
end

#systemd_toolHash|nil

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

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

Returns:

  • (Hash|nil)

    Hash with an absolute path to the tool and the command string for starting. +nil* if neither was found.



122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/vagrant-vbguest/installers/linux.rb', line 122

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

#tmp_pathObject

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



34
35
36
# File 'lib/vagrant-vbguest/installers/linux.rb', line 34

def tmp_path
  options[:iso_upload_path] || '/tmp/VBoxGuestAdditions.iso'
end

#unmount_iso(opts = nil) {|type, data| ... } ⇒ Object

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

Parameters:

  • opts (Hash) (defaults to: nil)

    Optional options Hash wich meight get passed to Vagrant::Communication::SSH#execute and firends

Yields:

  • (type, data)

    Takes a Block like Vagrant::Communication::Base#execute for realtime output of the command being executed

Yield Parameters:

  • type (String)

    Type of the output, ‘:stdout`, `:stderr`, etc.

  • data (String)

    Data for the given output.



216
217
218
# File 'lib/vagrant-vbguest/installers/linux.rb', line 216

def unmount_iso(opts=nil, &block)
  communicate.sudo("umount #{mount_point}", opts, &block)
end

#vboxadd_toolString|nil

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

Returns:

  • (String|nil)

    Absolute path to the vboxadd tool, or nil if none found.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/vagrant-vbguest/installers/linux.rb', line 142

def vboxadd_tool
  candidates = [
    "/usr/lib/i386-linux-gnu/VBoxGuestAdditions/vboxadd",
    "/usr/lib/x86_64-linux-gnu/VBoxGuestAdditions/vboxadd",
    "/usr/lib64/VBoxGuestAdditions/vboxadd",
    "/usr/lib/VBoxGuestAdditions/vboxadd",
    "/lib64/VBoxGuestAdditions/vboxadd",
    "/lib/VBoxGuestAdditions/vboxadd",
    "/etc/init.d/vboxadd",
  ]
  bin_path = ""
  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