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

Archlinux, Debian, Fedora, OpenSuse, RedHat, Suse

Instance Attribute Summary

Attributes inherited from Base

#env, #host, #options, #vm

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#cleanup, distro, #initialize, #installer_version, #iso_file, #upload, #yield_installation_error_warning, #yield_installation_warning, #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

.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:



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

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) ⇒ Hash|nil

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.

Returns:

  • (Hash|nil)

    The os-release configuration as Hash, or ‘nil if file is not present or not parsable.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/vagrant-vbguest/installers/linux.rb', line 21

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

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.



205
206
207
208
209
210
211
# File 'lib/vagrant-vbguest/installers/linux.rb', line 205

def execute_installer(opts=nil, &block)
  yield_installation_warning(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

#find_tool(tool) ⇒ String|nil

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.

Returns:

  • (String|nil)

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



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/vagrant-vbguest/installers/linux.rb', line 171

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}",
  ]
  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) ⇒ 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.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/vagrant-vbguest/installers/linux.rb', line 91

def guest_version(reload = false)
  return @guest_version if @guest_version && !reload
  driver_version = super.to_s[/^(\d+\.\d+.\d+)/, 1]

  communicate.sudo('VBoxService --version', :error_check => false) do |type, data|
    service_version = data.to_s[/^(\d+\.\d+.\d+)/, 1]
    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) {|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.



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

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)
  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.



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

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

#installer_argumentsObject

The arguments string, which gets passed to the installer script



220
221
222
# File 'lib/vagrant-vbguest/installers/linux.rb', line 220

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.



232
233
234
# File 'lib/vagrant-vbguest/installers/linux.rb', line 232

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`. defaults to “/mnt” for all Linux based systems.



51
52
53
# File 'lib/vagrant-vbguest/installers/linux.rb', line 51

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

#os_releaseObject



36
37
38
# File 'lib/vagrant-vbguest/installers/linux.rb', line 36

def os_release
  self.class.os_release(vm)
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.



111
112
113
# File 'lib/vagrant-vbguest/installers/linux.rb', line 111

def rebuild(opts=nil, &block)
  communicate.sudo("#{find_tool('vboxadd')} 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)


75
76
77
78
79
80
# File 'lib/vagrant-vbguest/installers/linux.rb', line 75

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.



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

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 Gem::Version.new("#{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_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.



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

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_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



44
45
46
# File 'lib/vagrant-vbguest/installers/linux.rb', line 44

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.



244
245
246
# File 'lib/vagrant-vbguest/installers/linux.rb', line 244

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