From 49daf1545b10bb17d30c44e0bf00c214436fb263 Mon Sep 17 00:00:00 2001 From: Bineesh Nadukkalam Date: Wed, 10 Jan 2024 16:46:20 +0400 Subject: [PATCH] Revert "use clonefile copy for macvm boxes" This reverts commit dbe3495cd3fbf09642cbd21f602bf8280c12d6d2. --- lib/vagrant-parallels/driver/base.rb | 55 +------------------ lib/vagrant-parallels/util/common.rb | 19 ------- .../unit/support/shared/pd_driver_examples.rb | 43 +-------------- 3 files changed, 2 insertions(+), 115 deletions(-) diff --git a/lib/vagrant-parallels/driver/base.rb b/lib/vagrant-parallels/driver/base.rb index 3f6ac2c1..e99e77d1 100644 --- a/lib/vagrant-parallels/driver/base.rb +++ b/lib/vagrant-parallels/driver/base.rb @@ -78,26 +78,7 @@ def clear_shared_folders # @return [String] UUID of the new VM. def clone_vm(src_name, options = {}) dst_name = "vagrant_temp_#{(Time.now.to_f * 1000.0).to_i}_#{rand(100000)}" - src_vm = json { execute_prlctl('list', '--json', '-i', src_name) }.first - if options[:linked] || !Util::Common.is_apfs?(src_vm.fetch('Home')) - # If linked clone is an option, or path to src is not on APFS, then do the normal clone. - prlctl_clone_vm(src_name, dst_name, options) - else - # We can use clonefile on APFS to do a fast CoW clone of the VM source and then register - copy_clone_vm(src_name, dst_name, options) - end - read_vms[dst_name] - end - - # Uses prlctl to clone an existing registered VM - # - # @param [String] src_name Name or UUID of the source VM or template. - # @param [String] dst_name Name of the destination VM. - # @param [ String>] options Options to clone virtual machine. - def prlctl_clone_vm(src_name, dst_name, options = {}) - list_args = ['list', '--json', '-i', src_name] - src_vm = json { execute_prlctl(*list_args) }.first args = ['clone', src_name, '--name', dst_name] args.concat(['--dst', options[:dst]]) if options[:dst] @@ -116,41 +97,7 @@ def prlctl_clone_vm(src_name, dst_name, options = {}) yield $1.to_i if block_given? end end - end - - # Uses cp with clonefile flag to clone an existing registered VM - # - # @param [String] src_name Name or UUID of the source VM or template. - # @param [String] dst_name Name of the destination VM. - # @param [ String>] options Options to clone virtual machine. - def copy_clone_vm(src_name, dst_name, options = {}) - list_args = ['list', '--json', '-i', src_name] - src_vm = json { execute_prlctl(*list_args) }.first - basepath = File.dirname(src_vm.fetch('Home')).delete_suffix('/') - extension = File.basename(src_vm.fetch('Home')).delete_suffix('/').split('.').last - clonepath = File.join(ENV['HOME'], "Parallels", "#{dst_name}.#{extension}") - execute('cp', '-c', '-R', '-p', src_vm.fetch('Home'), clonepath) - - # Update config.pvs with dst_name as this is what Parallels uses when registering - update_vm_name(File.join(clonepath, 'config.pvs'), dst_name) - - # Register the cloned path as a new VM - args = ['register', clonepath] - # Regenerate SourceVmUuid of the cloned VM - args << '--regenerate-src-uuid' if options[:regenerate_src_uuid] - - # Regenerate SourceVmUuid of the cloned VM - execute_prlctl(*args) - - # Don't need the box hanging around in Parallels - execute_prlctl('unregister', src_name) - end - - def update_vm_name(config_pvs_path, name) - xml = Nokogiri::XML(File.read(config_pvs_path)) - elem = xml.at_xpath('//ParallelsVirtualMachine/Identification/VmName') - elem.content = name - File.write(config_pvs_path, xml.to_xml) + read_vms[dst_name] end # Compacts the specified virtual disk image diff --git a/lib/vagrant-parallels/util/common.rb b/lib/vagrant-parallels/util/common.rb index 0eb141f2..5f3e8a0f 100644 --- a/lib/vagrant-parallels/util/common.rb +++ b/lib/vagrant-parallels/util/common.rb @@ -1,5 +1,3 @@ -require 'shellwords' - module VagrantPlugins module Parallels module Util @@ -11,23 +9,6 @@ def self.is_macvm(machine) return !machine.box.nil? && !!Dir.glob(machine.box.directory.join('*.macvm')).first end - # Determines if the box directory is on an APFS filesystem - def self.is_apfs?(path, &block) - output = {stdout: '', stderr: ''} - df_command = %w[df -T apfs] - df_command << Shellwords.escape(path) - execute(*df_command, &block).exit_code == 0 - end - - private - - def self.execute(*command, &block) - command << { notify: [:stdout, :stderr] } - - Vagrant::Util::Busy.busy(lambda {}) do - Vagrant::Util::Subprocess.execute(*command, &block) - end - end end end end diff --git a/test/unit/support/shared/pd_driver_examples.rb b/test/unit/support/shared/pd_driver_examples.rb index d673863f..ad3a3165 100644 --- a/test/unit/support/shared/pd_driver_examples.rb +++ b/test/unit/support/shared/pd_driver_examples.rb @@ -112,24 +112,7 @@ end describe 'clone_vm' do - before do - expect(subprocess).to receive(:execute).twice. - with('prlctl', 'list', '--json', '-i', an_instance_of(String), - an_instance_of(Hash)). - and_return(subprocess_result(stdout: '[{"Home": "/home/some/path"}]', exit_code: 0)) - expect(subprocess).to receive(:execute). - with('prlctl', 'list', '--all', '--no-header', '--json', '-o', 'name,uuid', {:notify=>[:stdout, :stderr]}). - and_return(subprocess_result(stdout: '[]', exit_code: 0)) - expect(subprocess).to receive(:execute). - with('prlctl', 'list', '--all', '--no-header', '--json', '-o', 'name,uuid', '--template', {:notify=>[:stdout, :stderr]}). - and_return(subprocess_result(stdout: '[]', exit_code: 0)) - end - - it 'clones VM to the new one when not on APFS' do - expect(subprocess).to receive(:execute). - with('df', '-T', 'apfs', '/home/some/path', - an_instance_of(Hash)). - and_return(subprocess_result(exit_code: 1)) + it 'clones VM to the new one' do expect(subprocess).to receive(:execute). with('prlctl', 'clone', tpl_uuid, '--name', an_instance_of(String), an_instance_of(Hash)). @@ -137,31 +120,7 @@ subject.clone_vm(tpl_uuid) end - it 'uses cp to clone VM to the new one when on APFS' do - expect(subprocess).to receive(:execute). - with('df', '-T', 'apfs', '/home/some/path', - an_instance_of(Hash)). - and_return(subprocess_result(exit_code: 0)) - expect(subprocess).to receive(:execute). - with('cp', '-c', '-R', '-p', '/home/some/path', an_instance_of(String), - an_instance_of(Hash)). - and_return(subprocess_result(exit_code: 0)) - expect(subprocess).to receive(:execute). - with('prlctl', 'register', an_instance_of(String), - an_instance_of(Hash)). - and_return(subprocess_result(exit_code: 0)) - expect(subprocess).to receive(:execute). - with('prlctl', 'unregister', tpl_uuid, an_instance_of(Hash)). - and_return(subprocess_result(exit_code: 0)) - expect(driver).to receive(:update_vm_name).and_return(true) - subject.clone_vm(tpl_uuid) - end - it 'clones VM to the exported VM' do - expect(subprocess).to receive(:execute). - with('df', '-T', 'apfs', '/home/some/path', - an_instance_of(Hash)). - and_return(subprocess_result(exit_code: 1)) expect(subprocess).to receive(:execute). with('prlctl', 'clone', uuid, '--name', an_instance_of(String), '--dst', an_instance_of(String), an_instance_of(Hash)).