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:



14
15
16
17
# 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) ⇒ 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.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 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

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.



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

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



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

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.



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

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.



64
65
66
67
68
69
70
71
# 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)
  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.



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

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

#installer_argumentsObject

The arguments string, which gets passed to the installer script



222
223
224
# File 'lib/vagrant-vbguest/installers/linux.rb', line 222

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.



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

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_pointObject

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



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

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

#os_releaseObject



38
39
40
# File 'lib/vagrant-vbguest/installers/linux.rb', line 38

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.



113
114
115
# File 'lib/vagrant-vbguest/installers/linux.rb', line 113

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)


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

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.



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

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.



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

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



46
47
48
# File 'lib/vagrant-vbguest/installers/linux.rb', line 46

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.



258
259
260
261
# File 'lib/vagrant-vbguest/installers/linux.rb', line 258

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

#yesObject

Determine if yes needs to be called or not



227
228
229
230
231
232
233
234
235
# File 'lib/vagrant-vbguest/installers/linux.rb', line 227

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