vagrant-vbguest 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/vagrant-vbguest.rb +4 -0
- data/lib/vagrant-vbguest/helpers.rb +6 -0
- data/lib/vagrant-vbguest/helpers/os_release.rb +177 -0
- data/lib/vagrant-vbguest/installers/archlinux.rb +30 -0
- data/lib/vagrant-vbguest/installers/debian.rb +4 -4
- data/lib/vagrant-vbguest/installers/linux.rb +27 -4
- data/lib/vagrant-vbguest/installers/suse.rb +45 -0
- data/lib/vagrant-vbguest/machine.rb +3 -3
- data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_1/rebootable.rb +2 -2
- data/lib/vagrant-vbguest/version.rb +1 -1
- data/locales/en.yml +4 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec63b20919df037edfd5cc748964d9285308c0f9
|
4
|
+
data.tar.gz: 7c1c9a39baa48fd06d6a63849f278759bf437125
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 08db7ea5d28c561e1d7020e49d2c156fb79a7f92f0a9cda5cd88b2eddb223f962ad12c813e9a1105408239ec2d9987f2fdd6933823969e89148407fa2b79c78e
|
7
|
+
data.tar.gz: 66df0d6f87b027c563bd9a4167402510170ac527180e6d0e32b399289e621f59c879f55d1790c7cf74c4ced1f51a94c4c1cf59c74f647cf99c2433640d117d8d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 0.13.0 (2016-08-12)
|
2
|
+
|
3
|
+
- Fix a bug introduced by upgrading "micormachine". Thanks @omenlabs for [GH-225]
|
4
|
+
- Fix a typo in a local variable. Thanks @vdloo for [GH-227]
|
5
|
+
- Add a Arch Linux specific installer. Thanks @vdloo, also for fixing some typos in [GH-229]
|
6
|
+
- Add a SUSE Linux Enterprise Server (sles) specific installer to address [GH-219] and [GH-216]. Thanks @vpereira, @glookie1 for the hard digging. Thanks @vpereira for [GH-219]. Thanks @bkeepers for the dontenv project, from which I stole it's parser.
|
7
|
+
|
1
8
|
## 0.12.0 (2016-06-16)
|
2
9
|
|
3
10
|
- Fix version comparison when version is reported with revision. Thanks @apeabody for [GH-179], [GH-201]
|
data/lib/vagrant-vbguest.rb
CHANGED
@@ -11,6 +11,8 @@ I18n.reload!
|
|
11
11
|
require "vagrant-vbguest/errors"
|
12
12
|
require 'vagrant-vbguest/vagrant_compat'
|
13
13
|
|
14
|
+
require 'vagrant-vbguest/helpers'
|
15
|
+
|
14
16
|
require 'vagrant-vbguest/machine'
|
15
17
|
|
16
18
|
require 'vagrant-vbguest/hosts/base'
|
@@ -25,6 +27,8 @@ require 'vagrant-vbguest/installers/redhat'
|
|
25
27
|
require 'vagrant-vbguest/installers/oracle'
|
26
28
|
require 'vagrant-vbguest/installers/fedora'
|
27
29
|
require 'vagrant-vbguest/installers/opensuse'
|
30
|
+
require 'vagrant-vbguest/installers/suse'
|
31
|
+
require 'vagrant-vbguest/installers/archlinux'
|
28
32
|
|
29
33
|
require 'vagrant-vbguest/middleware'
|
30
34
|
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# This file uses a the parsing component of the environment file parser
|
2
|
+
# dotenv (https://github.com/bkeepers/dotenv) in order to parse the
|
3
|
+
# `/etc/os-release` file of systemd, which uses loosely the same format.
|
4
|
+
#
|
5
|
+
# This parser will only substitute env variables in values which are already
|
6
|
+
# present in the parsed Hash. The original parser would try to read it's value
|
7
|
+
# from the `ENV` the process is running in. We would need to run this on the
|
8
|
+
# vagrant guest.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
#
|
12
|
+
# FOO=123
|
13
|
+
# BAR=$FOO # => `"BAR" => "123"`
|
14
|
+
# BAZ=$ZORT # => `"BAZ" => "$ZORT"
|
15
|
+
#
|
16
|
+
# This parser will *not* try to substitute shell commands in a value, since it
|
17
|
+
# would require us to let it run on the guest system.
|
18
|
+
#
|
19
|
+
# Example:
|
20
|
+
#
|
21
|
+
# SHA=$(git rev-parse HEAD) # => "SHA"=>"$(git rev-parse HEAD)"
|
22
|
+
#
|
23
|
+
|
24
|
+
# The original code (https://github.com/bkeepers/dotenv) was licensed under:
|
25
|
+
#
|
26
|
+
# Copyright (c) 2012 Brandon Keepers
|
27
|
+
#
|
28
|
+
# MIT License
|
29
|
+
#
|
30
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
31
|
+
# a copy of this software and associated documentation files (the
|
32
|
+
# "Software"), to deal in the Software without restriction, including
|
33
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
34
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
35
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
36
|
+
# the following conditions:
|
37
|
+
#
|
38
|
+
# The above copyright notice and this permission notice shall be
|
39
|
+
# included in all copies or substantial portions of the Software.
|
40
|
+
#
|
41
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
42
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
43
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
44
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
45
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
46
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
47
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
48
|
+
|
49
|
+
require "English"
|
50
|
+
|
51
|
+
module VagrantVbguest
|
52
|
+
module Helpers
|
53
|
+
module OsRelease
|
54
|
+
class FormatError < SyntaxError; end
|
55
|
+
|
56
|
+
module Substitutions
|
57
|
+
# Substitute variables in a value.
|
58
|
+
#
|
59
|
+
# HOST=example.com
|
60
|
+
# URL="https://$HOST"
|
61
|
+
#
|
62
|
+
module Variable
|
63
|
+
class << self
|
64
|
+
VARIABLE = /
|
65
|
+
(\\)? # is it escaped with a backslash?
|
66
|
+
(\$) # literal $
|
67
|
+
(?!\() # shouldnt be followed by paranthesis
|
68
|
+
(\{)? # allow brace wrapping
|
69
|
+
([A-Z0-9_]+)? # optional alpha nums
|
70
|
+
(\})? # closing brace
|
71
|
+
/xi
|
72
|
+
|
73
|
+
def call(value, env)
|
74
|
+
value.gsub(VARIABLE) do |variable|
|
75
|
+
match = $LAST_MATCH_INFO
|
76
|
+
|
77
|
+
if match[1] == '\\'
|
78
|
+
variable[1..-1]
|
79
|
+
elsif match[4]
|
80
|
+
env.fetch(match[4]) { match[2..5].join }
|
81
|
+
else
|
82
|
+
variable
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# This class enables parsing of a string for key value pairs to be returned
|
91
|
+
# and stored in the Environment. It allows for variable substitutions and
|
92
|
+
# exporting of variables.
|
93
|
+
class Parser
|
94
|
+
@substitutions = [Substitutions::Variable]
|
95
|
+
|
96
|
+
LINE = /
|
97
|
+
\A
|
98
|
+
(?:export\s+)? # optional export
|
99
|
+
([\w\.]+) # key
|
100
|
+
(?:\s*=\s*|:\s+?) # separator
|
101
|
+
( # optional value begin
|
102
|
+
'(?:\'|[^'])*' # single quoted value
|
103
|
+
| # or
|
104
|
+
"(?:\"|[^"])*" # double quoted value
|
105
|
+
| # or
|
106
|
+
[^#\n]+ # unquoted value
|
107
|
+
)? # value end
|
108
|
+
(?:\s*\#.*)? # optional comment
|
109
|
+
\z
|
110
|
+
/x
|
111
|
+
|
112
|
+
class << self
|
113
|
+
attr_reader :substitutions
|
114
|
+
|
115
|
+
def call(string)
|
116
|
+
new(string).call
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def initialize(string)
|
121
|
+
@string = string
|
122
|
+
@hash = {}
|
123
|
+
end
|
124
|
+
|
125
|
+
def call
|
126
|
+
@string.split(/[\n\r]+/).each do |line|
|
127
|
+
parse_line(line)
|
128
|
+
end
|
129
|
+
@hash
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def parse_line(line)
|
135
|
+
if (match = line.match(LINE))
|
136
|
+
key, value = match.captures
|
137
|
+
@hash[key] = parse_value(value || "")
|
138
|
+
elsif line.split.first == "export"
|
139
|
+
if variable_not_set?(line)
|
140
|
+
raise FormatError, "Line #{line.inspect} has an unset variable"
|
141
|
+
end
|
142
|
+
elsif line !~ /\A\s*(?:#.*)?\z/ # not comment or blank line
|
143
|
+
raise FormatError, "Line #{line.inspect} doesn't match format"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def parse_value(value)
|
148
|
+
# Remove surrounding quotes
|
149
|
+
value = value.strip.sub(/\A(['"])(.*)\1\z/, '\2')
|
150
|
+
|
151
|
+
if Regexp.last_match(1) == '"'
|
152
|
+
value = unescape_characters(expand_newlines(value))
|
153
|
+
end
|
154
|
+
|
155
|
+
if Regexp.last_match(1) != "'"
|
156
|
+
self.class.substitutions.each do |proc|
|
157
|
+
value = proc.call(value, @hash)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
value
|
161
|
+
end
|
162
|
+
|
163
|
+
def unescape_characters(value)
|
164
|
+
value.gsub(/\\([^$])/, '\1')
|
165
|
+
end
|
166
|
+
|
167
|
+
def expand_newlines(value)
|
168
|
+
value.gsub('\n', "\n").gsub('\r', "\r")
|
169
|
+
end
|
170
|
+
|
171
|
+
def variable_not_set?(line)
|
172
|
+
!line.split[1..-1].all? { |var| @hash.member?(var) }
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module VagrantVbguest
|
2
|
+
module Installers
|
3
|
+
class Archlinux < Linux
|
4
|
+
|
5
|
+
def self.match?(vm)
|
6
|
+
:arch == self.distro(vm)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Install missing deps and yield up to regular linux installation
|
10
|
+
def install(opts=nil, &block)
|
11
|
+
# Update the package list
|
12
|
+
communicate.sudo("pacman -Sy", opts, &block)
|
13
|
+
# Install the dependencies
|
14
|
+
communicate.sudo(install_dependencies_cmd, opts, &block)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
def install_dependencies_cmd
|
20
|
+
"pacman -S #{dependencies} --noconfirm --needed"
|
21
|
+
end
|
22
|
+
|
23
|
+
def dependencies
|
24
|
+
packages = ['gcc', 'dkms', 'make', 'bzip2']
|
25
|
+
packages.join ' '
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
VagrantVbguest::Installer.register(VagrantVbguest::Installers::Archlinux, 5)
|
@@ -6,9 +6,9 @@ module VagrantVbguest
|
|
6
6
|
/\Adebian\d*\Z/ =~ self.distro(vm)
|
7
7
|
end
|
8
8
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# @param opts [Hash] Optional options Hash
|
9
|
+
# installs the correct linux-headers package
|
10
|
+
# installs `dkms` package for dynamic kernel module loading
|
11
|
+
# @param opts [Hash] Optional options Hash which might get passed to {Vagrant::Communication::SSH#execute} and friends
|
12
12
|
# @yield [type, data] Takes a Block like {Vagrant::Communication::Base#execute} for realtime output of the command being executed
|
13
13
|
# @yieldparam [String] type Type of the output, `:stdout`, `:stderr`, etc.
|
14
14
|
# @yieldparam [String] data Data for the given output.
|
@@ -29,7 +29,7 @@ module VagrantVbguest
|
|
29
29
|
|
30
30
|
def dependencies
|
31
31
|
packages = ['linux-headers-`uname -r`']
|
32
|
-
# some Debian system (lenny)
|
32
|
+
# some Debian system (lenny) don't come with a dkms package so we need to skip that.
|
33
33
|
# apt-cache search will exit with 0 even if nothing was found, so we need to grep.
|
34
34
|
packages << 'dkms' if communicate.test('apt-cache search --names-only \'^dkms$\' | grep dkms')
|
35
35
|
packages.join ' '
|
@@ -12,8 +12,8 @@ module VagrantVbguest
|
|
12
12
|
# @see {Vagrant::Guest::Linux#distro_dispatch}
|
13
13
|
# @return [Symbol] One of `:debian`, `:ubuntu`, `:gentoo`, `:fedora`, `:redhat`, `:suse`, `:arch`
|
14
14
|
def self.distro(vm)
|
15
|
-
@@
|
16
|
-
@@
|
15
|
+
@@distro ||= {}
|
16
|
+
@@distro[ vm_id(vm) ] ||= distro_name vm
|
17
17
|
end
|
18
18
|
|
19
19
|
# Matches if the operating system name prints "Linux"
|
@@ -27,6 +27,29 @@ module VagrantVbguest
|
|
27
27
|
communicate_to(vm).test("uname | grep 'Linux'")
|
28
28
|
end
|
29
29
|
|
30
|
+
# Reads the `/etc/os-release` for the given `Vagrant::VM` if present, and
|
31
|
+
# returns it's config as a parsed Hash. The result is cached on a per-vm basis.
|
32
|
+
#
|
33
|
+
# @return [Hash|nil] The os-release configuration as Hash, or `nil if file is not present or not parsable.
|
34
|
+
def self.os_release(vm)
|
35
|
+
@@os_release_info ||= {}
|
36
|
+
if !@@os_release_info.has_key?(vm_id(vm)) && communicate_to(vm).test("test -f /etc/os-release")
|
37
|
+
osr_raw = communicate_to(vm).download("/etc/os-release")
|
38
|
+
osr_parsed = begin
|
39
|
+
VagrantVbguest::Helpers::OsRelease::Parser.(osr_raw)
|
40
|
+
rescue VagrantVbguest::Helpers::OsRelease::FormatError => e
|
41
|
+
vm.env.ui.warn(e.message)
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
@@os_release_info[vm_id(vm)] = osr_parsed
|
45
|
+
end
|
46
|
+
@@os_release_info[vm_id(vm)]
|
47
|
+
end
|
48
|
+
|
49
|
+
def os_release
|
50
|
+
self.class.os_release(vm)
|
51
|
+
end
|
52
|
+
|
30
53
|
# The temporary path where to upload the iso file to.
|
31
54
|
# Configurable via `config.vbguest.iso_upload_path`.
|
32
55
|
# Defaults the temp path to `/tmp/VBoxGuestAdditions.iso" for
|
@@ -37,7 +60,7 @@ module VagrantVbguest
|
|
37
60
|
|
38
61
|
# Mount point for the iso file.
|
39
62
|
# Configurable via `config.vbguest.iso_mount_point`.
|
40
|
-
#
|
63
|
+
# defaults to "/mnt" for all Linux based systems.
|
41
64
|
def mount_point
|
42
65
|
options[:iso_mount_point] || '/mnt'
|
43
66
|
end
|
@@ -83,7 +106,7 @@ module VagrantVbguest
|
|
83
106
|
|
84
107
|
communicate.sudo('VBoxService --version', :error_check => false) do |type, data|
|
85
108
|
service_version = data.to_s[/^(\d+\.\d+.\d+)/, 1]
|
86
|
-
if service_version
|
109
|
+
if service_version
|
87
110
|
if driver_version != service_version
|
88
111
|
@env.ui.warn(I18n.t("vagrant_vbguest.guest_version_reports_differ", :driver => driver_version, :service => service_version))
|
89
112
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module VagrantVbguest
|
2
|
+
module Installers
|
3
|
+
class Suse < Linux
|
4
|
+
# To distingish between OpenSuse and SLEs (both shows up as "suse"),
|
5
|
+
# check for presence of the zypper and entry on os-release
|
6
|
+
|
7
|
+
def self.match?(vm)
|
8
|
+
:suse == self.distro(vm) && has_zypper?(vm) && sles?(vm)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Install missing deps and yield up to regular linux installation
|
12
|
+
def install(opts=nil, &block)
|
13
|
+
communicate.sudo(install_dependencies_cmd, opts, &block)
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
def self.sles?(vm)
|
19
|
+
osr = self.os_release(vm)
|
20
|
+
osr && osr["ID"] == "sles"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.has_zypper?(vm)
|
24
|
+
communicate_to(vm).test "which zypper"
|
25
|
+
end
|
26
|
+
|
27
|
+
def install_dependencies_cmd
|
28
|
+
"zypper --non-interactive install #{dependencies}"
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def dependencies
|
33
|
+
packages = case os_release["VERSION_ID"].to_f
|
34
|
+
when 10..11.4
|
35
|
+
['kernel-default-devel', 'gcc', 'make', 'tar']
|
36
|
+
when 12.0..13.0
|
37
|
+
['kernel-devel', 'gcc', 'make', 'tar']
|
38
|
+
end
|
39
|
+
|
40
|
+
packages.join ' '
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
VagrantVbguest::Installer.register(VagrantVbguest::Installers::Suse, 6)
|
@@ -45,9 +45,9 @@ module VagrantVbguest
|
|
45
45
|
guest_additions_state.trigger :start
|
46
46
|
end
|
47
47
|
|
48
|
-
def installation_ran?; guest_additions_state == :installed end
|
49
|
-
def started?; guest_additions_state == :started end
|
50
|
-
def rebuilt?; guest_additions_state == :rebuilt end
|
48
|
+
def installation_ran?; guest_additions_state.state == :installed end
|
49
|
+
def started?; guest_additions_state.state == :started end
|
50
|
+
def rebuilt?; guest_additions_state.state == :rebuilt end
|
51
51
|
|
52
52
|
def reboot; box_state.trigger :reboot end
|
53
53
|
def reboot?; box_state.state == :rebooted end
|
@@ -6,7 +6,7 @@ module VagrantVbguest
|
|
6
6
|
module Rebootable
|
7
7
|
def reboot(vm, options)
|
8
8
|
if reboot? vm, options
|
9
|
-
|
9
|
+
simple_reboot = Vagrant::Action::Builder.new.tap do |b|
|
10
10
|
b.use Vagrant::Action::Builtin::Call, Vagrant::Action::Builtin::GracefulHalt, :poweroff, :running do |env2, b2|
|
11
11
|
if !env2[:result]
|
12
12
|
b2.use VagrantPlugins::ProviderVirtualBox::Action::ForcedHalt
|
@@ -17,7 +17,7 @@ module VagrantVbguest
|
|
17
17
|
b.use Vagrant::Action::Builtin::WaitForCommunicator, [:starting, :running]
|
18
18
|
end
|
19
19
|
end
|
20
|
-
@env[:action_runner].run(
|
20
|
+
@env[:action_runner].run(simple_reboot, @env)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/locales/en.yml
CHANGED
@@ -56,6 +56,10 @@ en:
|
|
56
56
|
do_not_inherit_match_method: |-
|
57
57
|
Installer classes must provide their own `match?` method.
|
58
58
|
|
59
|
+
os_release_parse_error: |-
|
60
|
+
Error while parsing the /etc/os-release file:
|
61
|
+
%{message}
|
62
|
+
|
59
63
|
download:
|
60
64
|
started: "Downloading VirtualBox Guest Additions ISO from %{source}"
|
61
65
|
with: "Downloading VirtualBox Guest Additions ISO with %{class}..."
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-vbguest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Schulze
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: micromachine
|
@@ -72,9 +72,12 @@ files:
|
|
72
72
|
- lib/vagrant-vbguest/core_ext/string/interpolate.rb
|
73
73
|
- lib/vagrant-vbguest/download.rb
|
74
74
|
- lib/vagrant-vbguest/errors.rb
|
75
|
+
- lib/vagrant-vbguest/helpers.rb
|
76
|
+
- lib/vagrant-vbguest/helpers/os_release.rb
|
75
77
|
- lib/vagrant-vbguest/hosts/base.rb
|
76
78
|
- lib/vagrant-vbguest/hosts/virtualbox.rb
|
77
79
|
- lib/vagrant-vbguest/installer.rb
|
80
|
+
- lib/vagrant-vbguest/installers/archlinux.rb
|
78
81
|
- lib/vagrant-vbguest/installers/base.rb
|
79
82
|
- lib/vagrant-vbguest/installers/debian.rb
|
80
83
|
- lib/vagrant-vbguest/installers/fedora.rb
|
@@ -82,6 +85,7 @@ files:
|
|
82
85
|
- lib/vagrant-vbguest/installers/opensuse.rb
|
83
86
|
- lib/vagrant-vbguest/installers/oracle.rb
|
84
87
|
- lib/vagrant-vbguest/installers/redhat.rb
|
88
|
+
- lib/vagrant-vbguest/installers/suse.rb
|
85
89
|
- lib/vagrant-vbguest/installers/ubuntu.rb
|
86
90
|
- lib/vagrant-vbguest/machine.rb
|
87
91
|
- lib/vagrant-vbguest/middleware.rb
|