vagrant/plugins/providers/hyperv/driver.rb

134 lines
3.5 KiB
Ruby

require "json"
require "vagrant/util/powershell"
require_relative "plugin"
module VagrantPlugins
module HyperV
class Driver
ERROR_REGEXP = /===Begin-Error===(.+?)===End-Error===/m
OUTPUT_REGEXP = /===Begin-Output===(.+?)===End-Output===/m
attr_reader :vm_id
def initialize(id)
@vm_id = id
end
def execute(path, options)
r = execute_powershell(path, options)
if r.exit_code != 0
raise Errors::PowerShellError,
script: path,
stderr: r.stderr
end
# We only want unix-style line endings within Vagrant
r.stdout.gsub!("\r\n", "\n")
r.stderr.gsub!("\r\n", "\n")
error_match = ERROR_REGEXP.match(r.stdout)
output_match = OUTPUT_REGEXP.match(r.stdout)
if error_match
data = JSON.parse(error_match[1])
# We have some error data.
raise Errors::PowerShellError,
script: path,
stderr: data["error"]
end
# Nothing
return nil if !output_match
return JSON.parse(output_match[1])
end
def get_current_state
execute('get_vm_status.ps1', { VmId: vm_id })
end
def delete_vm
execute('delete_vm.ps1', { VmId: vm_id })
end
def read_guest_ip
execute('get_network_config.ps1', { VmId: vm_id })
end
def resume
execute('resume_vm.ps1', { VmId: vm_id })
end
def start
execute('start_vm.ps1', { VmId: vm_id })
end
def stop
execute('stop_vm.ps1', { VmId: vm_id })
end
def suspend
execute("suspend_vm.ps1", { VmId: vm_id })
end
def import(options)
config_type = options.delete(:vm_config_type)
if config_type === "vmcx"
execute('import_vm_vmcx.ps1', options)
else
options.delete(:data_path)
options.delete(:source_path)
options.delete(:differencing_disk)
execute('import_vm_xml.ps1', options)
end
end
def net_set_vlan(vlan_id)
execute("set_network_vlan.ps1", { VmId: vm_id, VlanId: vlan_id })
end
def net_set_mac(mac_addr)
execute("set_network_mac.ps1", { VmId: vm_id, Mac: mac_addr })
end
def create_snapshot(snapshot_name)
execute("create_snapshot.ps1", { VmId: vm_id, SnapName: (snapshot_name) } )
end
def restore_snapshot(snapshot_name)
execute("restore_snapshot.ps1", { VmId: vm_id, SnapName: (snapshot_name) } )
end
def list_snapshots()
snaps = execute("list_snapshots.ps1", { VmID: vm_id } )
snaps.map { |s| s['Name'] }
end
def delete_snapshot(snapshot_name)
execute("delete_snapshot.ps1", {VmID: vm_id, SnapName: snapshot_name})
end
protected
def execute_powershell(path, options, &block)
lib_path = Pathname.new(File.expand_path("../scripts", __FILE__))
path = lib_path.join(path).to_s.gsub("/", "\\")
options = options || {}
ps_options = []
options.each do |key, value|
ps_options << "-#{key}"
ps_options << "'#{value}'"
end
# Always have a stop error action for failures
ps_options << "-ErrorAction" << "Stop"
opts = { notify: [:stdout, :stderr, :stdin] }
Vagrant::Util::PowerShell.execute(path, *ps_options, **opts, &block)
end
end
end
end