vagrant-vbguest-update 0.10.1.dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/CHANGELOG.md +209 -0
  4. data/Gemfile +11 -0
  5. data/LICENSE +21 -0
  6. data/Rakefile +11 -0
  7. data/Readme.md +267 -0
  8. data/lib/vagrant-vbguest.rb +57 -0
  9. data/lib/vagrant-vbguest/command.rb +95 -0
  10. data/lib/vagrant-vbguest/config.rb +51 -0
  11. data/lib/vagrant-vbguest/core_ext/string/interpolate.rb +110 -0
  12. data/lib/vagrant-vbguest/download.rb +28 -0
  13. data/lib/vagrant-vbguest/errors.rb +18 -0
  14. data/lib/vagrant-vbguest/hosts/base.rb +118 -0
  15. data/lib/vagrant-vbguest/hosts/virtualbox.rb +103 -0
  16. data/lib/vagrant-vbguest/installer.rb +121 -0
  17. data/lib/vagrant-vbguest/installers/base.rb +201 -0
  18. data/lib/vagrant-vbguest/installers/debian.rb +40 -0
  19. data/lib/vagrant-vbguest/installers/linux.rb +158 -0
  20. data/lib/vagrant-vbguest/installers/redhat.rb +29 -0
  21. data/lib/vagrant-vbguest/installers/ubuntu.rb +44 -0
  22. data/lib/vagrant-vbguest/machine.rb +105 -0
  23. data/lib/vagrant-vbguest/middleware.rb +43 -0
  24. data/lib/vagrant-vbguest/rebootable.rb +39 -0
  25. data/lib/vagrant-vbguest/vagrant_compat.rb +21 -0
  26. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_0/command.rb +17 -0
  27. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_0/download.rb +51 -0
  28. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_0/rebootable.rb +23 -0
  29. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_0/vm_compatible.rb +31 -0
  30. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_1/command.rb +18 -0
  31. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_1/download.rb +1 -0
  32. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_1/rebootable.rb +33 -0
  33. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_1/vm_compatible.rb +31 -0
  34. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_2/command.rb +1 -0
  35. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_2/download.rb +18 -0
  36. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_2/rebootable.rb +1 -0
  37. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_2/vm_compatible.rb +15 -0
  38. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_3/command.rb +1 -0
  39. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_3/download.rb +1 -0
  40. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_3/rebootable.rb +1 -0
  41. data/lib/vagrant-vbguest/vagrant_compat/vagrant_1_3/vm_compatible.rb +1 -0
  42. data/lib/vagrant-vbguest/version.rb +3 -0
  43. data/lib/vagrant_init.rb +38 -0
  44. data/locales/en.yml +63 -0
  45. data/vagrant-vbguest.gemspec +30 -0
  46. metadata +161 -0
@@ -0,0 +1,57 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Vagrant VBGuest plugin must be run within Vagrant."
5
+ end
6
+
7
+ # Add our custom translations to the load path
8
+ I18n.load_path << File.expand_path("../../locales/en.yml", __FILE__)
9
+ I18n.reload!
10
+
11
+ require "vagrant-vbguest/errors"
12
+ require 'vagrant-vbguest/vagrant_compat'
13
+
14
+ require 'vagrant-vbguest/machine'
15
+
16
+ require 'vagrant-vbguest/hosts/base'
17
+ require 'vagrant-vbguest/hosts/virtualbox'
18
+
19
+ require 'vagrant-vbguest/installer'
20
+ require 'vagrant-vbguest/installers/base'
21
+ require 'vagrant-vbguest/installers/linux'
22
+ require 'vagrant-vbguest/installers/debian'
23
+ require 'vagrant-vbguest/installers/ubuntu'
24
+ require 'vagrant-vbguest/installers/redhat'
25
+
26
+ require 'vagrant-vbguest/middleware'
27
+
28
+ module VagrantVbguest
29
+
30
+ class Plugin < Vagrant.plugin("2")
31
+
32
+ name "vagrant-vbguest"
33
+ description <<-DESC
34
+ Provides automatic and/or manual management of the
35
+ VirtualBox Guest Additions inside the Vagrant environment.
36
+ DESC
37
+
38
+ config('vbguest') do
39
+ require File.expand_path("../vagrant-vbguest/config", __FILE__)
40
+ Config
41
+ end
42
+
43
+ command('vbguest') do
44
+ Command
45
+ end
46
+
47
+ # hook after anything that boots:
48
+ # that's all middlewares which will run the buildin "VM::Boot" action
49
+ action_hook('vbguest') do |hook|
50
+ if defined?(VagrantPlugins::ProviderVirtualBox::Action::CheckGuestAdditions)
51
+ hook.before(VagrantPlugins::ProviderVirtualBox::Action::CheckGuestAdditions, VagrantVbguest::Middleware)
52
+ else
53
+ hook.after(VagrantPlugins::ProviderVirtualBox::Action::Boot, VagrantVbguest::Middleware)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,95 @@
1
+ require 'optparse'
2
+
3
+ module VagrantVbguest
4
+
5
+ module CommandCommons
6
+ include VagrantVbguest::Helpers::Rebootable
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ # Runs the vbguest installer on the VMs that are represented
12
+ # by this environment.
13
+ def execute
14
+ options = {
15
+ :_method => :run,
16
+ :_rebootable => true,
17
+ :auto_reboot => false
18
+ }
19
+ opts = OptionParser.new do |opts|
20
+ opts.banner = "Usage: vagrant vbguest [vm-name] [--do start|rebuild|install] [--status] [-f|--force] [-b|--auto-reboot] [-R|--no-remote] [--iso VBoxGuestAdditions.iso]"
21
+ opts.separator ""
22
+
23
+ opts.on("--do COMMAND", [:start, :rebuild, :install], "Manually `start`, `rebuild` or `install` GuestAdditions.") do |command|
24
+ options[:_method] = command
25
+ options[:force] = true
26
+ end
27
+
28
+ opts.on("--status", "Print current GuestAdditions status and exit.") do
29
+ options[:_method] = :status
30
+ options[:_rebootable] = false
31
+ end
32
+
33
+ opts.on("-f", "--force", "Whether to force the installation. (Implied by --do start|rebuild|install)") do
34
+ options[:force] = true
35
+ end
36
+
37
+ opts.on("--auto-reboot", "-b", "Allow rebooting the VM after installation. (when GuestAdditions won't start)") do
38
+ options[:auto_reboot] = true
39
+ end
40
+
41
+ opts.on("--no-remote", "-R", "Do not attempt do download the iso file from a webserver") do
42
+ options[:no_remote] = true
43
+ end
44
+
45
+ opts.on("--iso file_or_uri", "Full path or URI to the VBoxGuestAdditions.iso") do |file_or_uri|
46
+ options[:iso_path] = file_or_uri
47
+ end
48
+
49
+ build_start_options(opts, options)
50
+ end
51
+
52
+
53
+ argv = parse_options(opts)
54
+ return if !argv
55
+
56
+ if argv.empty?
57
+ with_target_vms(nil) { |vm| execute_on_vm(vm, options) }
58
+ else
59
+ argv.each do |vm_name|
60
+ with_target_vms(vm_name) { |vm| execute_on_vm(vm, options) }
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ protected
67
+
68
+ # Executes a command on a specific VM.
69
+ def execute_on_vm(vm, options)
70
+ check_runable_on(vm)
71
+
72
+ options = options.clone
73
+ _method = options.delete(:_method)
74
+ _rebootable = options.delete(:_rebootable)
75
+
76
+ options = vm.config.vbguest.to_hash.merge(options)
77
+ machine = VagrantVbguest::Machine.new(vm, options)
78
+ status = machine.state
79
+ vm.env.ui.send((:ok == status ? :success : :warn), I18n.t("vagrant_vbguest.status.#{status}", machine.info))
80
+
81
+ if _method != :status
82
+ machine.send(_method)
83
+ end
84
+
85
+ reboot!(vm, options) if _rebootable && machine.reboot?
86
+ rescue VagrantVbguest::Installer::NoInstallerFoundError => e
87
+ vm.env.ui.error e.message
88
+ end
89
+
90
+ def check_runable_on(vm)
91
+ raise NotImplementedError
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,51 @@
1
+ module VagrantVbguest
2
+
3
+ class Config <( Vagrant::VERSION < "1.1.0" ? Vagrant::Config::Base : Vagrant.plugin("2", :config) )
4
+
5
+ module Attributes
6
+ attr_accessor :iso_path, :auto_update, :auto_reboot, :no_install, :no_remote, :installer, :installer_arguments
7
+ end
8
+
9
+ class << self
10
+ include Attributes
11
+
12
+ def auto_update; @auto_update.nil? ? true : @auto_update end
13
+ def auto_reboot; @auto_reboot.nil? ? true : @auto_reboot end
14
+ def no_install; @no_install.nil? ? false : @no_install end
15
+ def no_remote; @no_remote.nil? ? false : @no_remote end
16
+ def installer_arguments; @installer_arguments.nil? ? '--nox11' : @installer_arguments end
17
+
18
+ def iso_path
19
+ return nil if !@iso_path || @iso_path == :auto
20
+ @iso_path
21
+ end
22
+ end
23
+
24
+ include Attributes
25
+
26
+ def auto_update; @auto_update.nil? ? self.class.auto_update : @auto_update end
27
+ def auto_reboot; @auto_reboot.nil? ? self.class.auto_reboot : @auto_reboot end
28
+ def no_install; @no_install.nil? ? self.class.no_install : @no_install end
29
+ def no_remote; @no_remote.nil? ? self.class.no_remote : @no_remote end
30
+ def installer_arguments; @installer_arguments.nil? ? self.class.installer_arguments : @installer_arguments end
31
+
32
+ def iso_path
33
+ return self.class.iso_path if !@iso_path || @iso_path == :auto
34
+ @iso_path
35
+ end
36
+
37
+ # explicit hash, to get symbols in hash keys
38
+ def to_hash
39
+ {
40
+ :installer => installer,
41
+ :installer_arguments => installer_arguments,
42
+ :iso_path => iso_path,
43
+ :auto_update => auto_update,
44
+ :auto_reboot => auto_reboot,
45
+ :no_install => no_install,
46
+ :no_remote => no_remote
47
+ }
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,110 @@
1
+ # This backports the Ruby 1.9 String interpolation syntax to Ruby 1.8.
2
+ #
3
+ # This file is a copy from I18n
4
+ # https://github.com/mattetti/i18n/blob/master/lib/i18n/core_ext/string/interpolate.rb
5
+ # Copyright (c) 2008 The Ruby I18n team
6
+ # It's copied here for the resons given below:
7
+ #
8
+ # This backport has been shipped with I18n for a number of versions. Meanwhile
9
+ # Rails has started to rely on it and we are going to move it to ActiveSupport.
10
+ # See https://rails.lighthouseapp.com/projects/8994/tickets/6013-move-19-string-interpolation-syntax-backport-from-i18n-to-activesupport
11
+ #
12
+ # Once the above patch has been applied to Rails the following code will be
13
+ # removed from I18n.
14
+
15
+ =begin
16
+ heavily based on Masao Mutoh's gettext String interpolation extension
17
+ http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
18
+ Copyright (C) 2005-2009 Masao Mutoh
19
+ You may redistribute it and/or modify it under the same license terms as Ruby.
20
+ =end
21
+
22
+ begin
23
+ raise ArgumentError if ("a %{x}" % {:x=>'b'}) != 'a b'
24
+ rescue ArgumentError
25
+ # KeyError is raised by String#% when the string contains a named placeholder
26
+ # that is not contained in the given arguments hash. Ruby 1.9 includes and
27
+ # raises this exception natively. We define it to mimic Ruby 1.9's behaviour
28
+ # in Ruby 1.8.x
29
+ class KeyError < IndexError
30
+ def initialize(message = nil)
31
+ super(message || "key not found")
32
+ end
33
+ end unless defined?(KeyError)
34
+
35
+ # Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
36
+ #
37
+ # String#% method which accept "named argument". The translator can know
38
+ # the meaning of the msgids using "named argument" instead of %s/%d style.
39
+ class String
40
+ # For older ruby versions, such as ruby-1.8.5
41
+ alias :bytesize :size unless instance_methods.find {|m| m.to_s == 'bytesize'}
42
+ alias :interpolate_without_ruby_19_syntax :% # :nodoc:
43
+
44
+ INTERPOLATION_PATTERN = Regexp.union(
45
+ /%\{(\w+)\}/, # matches placeholders like "%{foo}"
46
+ /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
47
+ )
48
+
49
+ INTERPOLATION_PATTERN_WITH_ESCAPE = Regexp.union(
50
+ /%%/,
51
+ INTERPOLATION_PATTERN
52
+ )
53
+
54
+ # % uses self (i.e. the String) as a format specification and returns the
55
+ # result of applying it to the given arguments. In other words it interpolates
56
+ # the given arguments to the string according to the formats the string
57
+ # defines.
58
+ #
59
+ # There are three ways to use it:
60
+ #
61
+ # * Using a single argument or Array of arguments.
62
+ #
63
+ # This is the default behaviour of the String class. See Kernel#sprintf for
64
+ # more details about the format string.
65
+ #
66
+ # Example:
67
+ #
68
+ # "%d %s" % [1, "message"]
69
+ # # => "1 message"
70
+ #
71
+ # * Using a Hash as an argument and unformatted, named placeholders.
72
+ #
73
+ # When you pass a Hash as an argument and specify placeholders with %{foo}
74
+ # it will interpret the hash values as named arguments.
75
+ #
76
+ # Example:
77
+ #
78
+ # "%{firstname}, %{lastname}" % {:firstname => "Masao", :lastname => "Mutoh"}
79
+ # # => "Masao Mutoh"
80
+ #
81
+ # * Using a Hash as an argument and formatted, named placeholders.
82
+ #
83
+ # When you pass a Hash as an argument and specify placeholders with %<foo>d
84
+ # it will interpret the hash values as named arguments and format the value
85
+ # according to the formatting instruction appended to the closing >.
86
+ #
87
+ # Example:
88
+ #
89
+ # "%<integer>d, %<float>.1f" % { :integer => 10, :float => 43.4 }
90
+ # # => "10, 43.3"
91
+ def %(args)
92
+ if args.kind_of?(Hash)
93
+ dup.gsub(INTERPOLATION_PATTERN_WITH_ESCAPE) do |match|
94
+ if match == '%%'
95
+ '%'
96
+ else
97
+ key = ($1 || $2).to_sym
98
+ raise KeyError unless args.has_key?(key)
99
+ $3 ? sprintf("%#{$3}", args[key]) : args[key]
100
+ end
101
+ end
102
+ elsif self =~ INTERPOLATION_PATTERN
103
+ raise ArgumentError.new('one hash required')
104
+ else
105
+ result = gsub(/%([{<])/, '%%\1')
106
+ result.send :'interpolate_without_ruby_19_syntax', args
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,28 @@
1
+ module VagrantVbguest
2
+
3
+ class DownloadBase
4
+ attr_reader :source, :destination, :downloader
5
+
6
+ def initialize(source, destination, options=nil)
7
+ @downloader = nil
8
+ @source = source
9
+ @destination = destination
10
+ if File.directory?(destination)
11
+ @destination = File.join(destination, "vbguest_download_#{Time.now.to_i.to_s}")
12
+ end
13
+ @ui = options[:ui]
14
+ end
15
+
16
+ def download!
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def cleanup
21
+ if destination && File.exist?(destination)
22
+ @ui.info I18n.t("vagrant_vbguest.download.cleaning")
23
+ File.unlink(destination)
24
+ end
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,18 @@
1
+ module VagrantVbguest
2
+
3
+ class VbguestError < Vagrant::Errors::VagrantError
4
+ def error_namespace; "vagrant_vbguest.errors"; end
5
+ end
6
+
7
+ class IsoPathAutodetectionError < VagrantVbguest::VbguestError
8
+ error_key :autodetect_iso_path
9
+ end
10
+
11
+ class DownloadingDisabledError < VagrantVbguest::VbguestError
12
+ error_key :downloading_disabled
13
+ end
14
+
15
+ class NoVirtualBoxMachineError < VagrantVbguest::VbguestError
16
+ error_key :no_virtualbox_machine
17
+ end
18
+ end
@@ -0,0 +1,118 @@
1
+ require 'uri'
2
+
3
+ module VagrantVbguest
4
+ module Hosts
5
+ class Base
6
+ include VagrantVbguest::Helpers::VmCompatible
7
+
8
+ attr_reader :env, :vm, :options
9
+
10
+ def initialize(vm, options=nil)
11
+ @vm = vm
12
+ @env = vm.env
13
+ @options = options
14
+ end
15
+
16
+ # Determinates the host's version
17
+ #
18
+ # @return [String] The version code of the *host*'s virtualisation
19
+ def version
20
+ @version ||= driver.version
21
+ end
22
+
23
+
24
+ # Additions-file-detection-magig.
25
+ #
26
+ # Detection runs in those stages:
27
+ # 1. Uses the +iso_path+ config option, if present and not set to +:auto+
28
+ # 2. Look out for a local additions file
29
+ # 3. Use the default web URI
30
+ #
31
+ # If the detected or configured path is not a local file and remote downloads
32
+ # are allowed (the config option +:no_remote+ is NOT set) it will try to
33
+ # download that file into a temp file using Vagrants Downloaders.
34
+ # If remote downloads are prohibited (the config option +:no_remote+ IS set)
35
+ # a +VagrantVbguest::IsoPathAutodetectionError+ will be thrown
36
+ #
37
+ # @return [String] A absolute path to the GuestAdditions iso file.
38
+ # This might be a temp-file, e.g. when downloaded from web.
39
+ def additions_file
40
+ return @additions_file if @additions_file
41
+
42
+ path = options[:iso_path]
43
+ if !path || path.empty? || path == :auto
44
+ path = local_path
45
+ path = web_path if !options[:no_remote] && !path
46
+ end
47
+ raise VagrantVbguest::IsoPathAutodetectionError if !path || path.empty?
48
+
49
+ path = versionize(path)
50
+
51
+ if file_match? path
52
+ @additions_file = path
53
+ else
54
+ # :TODO: This will also raise, if the iso_url points to an invalid local path
55
+ raise VagrantVbguest::DownloadingDisabledError.new(:from => path) if options[:no_remote]
56
+ @additions_file = download path
57
+ end
58
+ end
59
+
60
+ # If needed, remove downloaded temp file
61
+ def cleanup
62
+ @download.cleanup if @download
63
+ end
64
+
65
+ protected
66
+
67
+ # fix bug when the vagrant version is higher than 1.2, by moving method Vagrant::Vagrant::File.match? here
68
+ def file_match?(uri)
69
+ extracted = ::URI.extract(uri, "file")
70
+
71
+ return true if extracted && extracted.include?(uri)
72
+
73
+ return ::File.file?(::File.expand_path(uri))
74
+ end
75
+
76
+ # Default web URI, where "additions file" can be downloaded.
77
+ #
78
+ # @return [String] A URI template containing the versions placeholder.
79
+ def web_path
80
+ raise NotImplementedError
81
+ end
82
+
83
+ # Finds the "additions file" on the host system.
84
+ # Returns +nil+ if none found.
85
+ #
86
+ # @return [String] Absolute path to the local "additions file", or +nil+ if not found.
87
+ def local_path
88
+ raise NotImplementedError
89
+ end
90
+
91
+ # replaces the veriosn placeholder with the additions
92
+ # version string
93
+ #
94
+ # @param [String] A path or URL (or any other String)
95
+ #
96
+ # @retrun [String] A copy of the passed string, with verision
97
+ # placeholder replaced
98
+ def versionize(path)
99
+ path % {:version => version}
100
+ end
101
+
102
+ # Kicks off +VagrantVbguest::Download+ to download the additions file
103
+ # into a temp file.
104
+ #
105
+ # To remove the created tempfile call +cleanup+
106
+ #
107
+ # @param [String] The path or URI to download
108
+ #
109
+ # @return [String] The path to the downloaded file
110
+ def download(path)
111
+ @download = VagrantVbguest::Download.new(path, @env.tmp_path, :ui => @env.ui)
112
+ @download.download!
113
+ @download.destination
114
+ end
115
+
116
+ end
117
+ end
118
+ end