sprotheroe / vagrant-disksize

Vagrant plugin to resize disks in VirtualBox
MIT License
479 stars 52 forks source link

Adapt VBoxManage commands to VirtualBox < 5 #12

Closed EmersonPrado closed 5 years ago

EmersonPrado commented 6 years ago

Methods clone_as_vdi, grow_vdi and get_disk_size from class Vagrant::Disksize::Action::ResizeDisk use commands VBoxManage clonemedium|modifymedium|showmediuminfo, which seem to have been introduced in VB 5.0. For VB 4.x, the exact same commands worked perfectly (I have VB 4.3.28) just by changing medium to hd. So the plugin could use either form depending on VirtualBox version.

My suggestion would be to create a string constant, like MEDIUM_STRING, containing either medium or hd, in a conditional which queries VirtualBox version. Vagrant exposes VirtualBox version in @@version variable or read_version method, from class VagrantPlugins::ProviderVirtualBox::Driver::Meta. Unfortunately, being a beginner in Ruby, I couldn't access either the variable or method correctly.

In short, something like:

module Vagrant
  module Disksize
    class Action
      class ResizeDisk
        ...
        if <whatever grabs VB version> >= '5.0'
          MEDIUM_STRING = 'medium'
        else
          MEDIUM_STRING = 'hd'
        end
        ...
        def clone_as_vdi(driver, src, dst)
          driver.execute("clone#{MEDIUM_STRING}", src[:file], dst[:file], '--format', 'VDI')
        end
        ...

If someone can hint me on calling the said method, I'd be happy to PR a fix.

EmersonPrado commented 6 years ago

Opened PR 13

odyniec commented 5 years ago

Here's a hack you can use in Vagrantfile:

VB_Meta = VagrantPlugins::ProviderVirtualBox::Driver::Meta.new()

if VB_Meta.version < '5.0'
    module DisksizeHack
        class Plugin < Vagrant.plugin('2')
            name "disksizehack"

            class Action
                def initialize(app, env)
                    @app = app

                    Vagrant::Disksize::Action::ResizeDisk.class_eval do
                        def clone_as_vdi(driver, src, dst)
                            driver.execute("clonehd", src[:file], dst[:file], '--format', 'VDI')
                        end                

                        def grow_vdi(driver, disk, size)
                            driver.execute("modifyhd", disk[:file], '--resize', size.to_s)
                        end

                        def get_disk_size(driver, disk)
                            size = nil
                            driver.execute("showhdinfo", disk[:file]).each_line do |line|
                                if line =~ /Capacity:\s+([0-9]+)\s+MB/
                                    size = $1.to_i
                                end
                            end
                            size
                        end
                    end
                end

                def call(env)
                    @app.call(env)
                end
            end

            action_hook(:disksizehack, :machine_action_up) do |hook|
                hook.before(Vagrant::Disksize::Action::ResizeDisk, DisksizeHack::Plugin::Action)
            end
        end
    end
end
sprotheroe commented 5 years ago

Accepted @EmersonPrado 's PR, with massive thanks to him, so closing this issue.