providers/hyperv: clean up status script

This commit is contained in:
Mitchell Hashimoto 2014-02-16 11:31:33 -08:00
parent 88247797d4
commit 7c0948c81d
8 changed files with 173 additions and 158 deletions

View File

@ -28,6 +28,28 @@ module VagrantPlugins
end end
end end
def self.action_destroy
Vagrant::Action::Builder.new.tap do |b|
b.use Call, IsCreated do |env1, b1|
if !env1[:result]
b2.use MessageNotCreated
next
end
b2.use Call, DestroyConfirm do |env2, b3|
if !env2[:result]
b3.use MessageWillNotDestroy
next
end
b3.use ConfigValidate
b3.use StopInstance
b3.use DeleteVM
end
end
end
end
def self.action_halt def self.action_halt
Vagrant::Action::Builder.new.tap do |b| Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate b.use ConfigValidate

View File

@ -11,15 +11,9 @@ module VagrantPlugins
def call(env) def call(env)
if env[:machine].id if env[:machine].id
begin options = { VmId: env[:machine].id }
options = { vm_id: env[:machine].id } response = env[:machine].provider.driver.execute('get_vm_status.ps1', options)
response = env[:machine].provider.driver.execute('get_vm_status.ps1', options) env[:machine_state_id] = response["state"].downcase.to_sym
env[:machine_state_id] = response["state"].downcase.to_sym
rescue Error::SubprocessError
env[:machine].id = nil
env[:ui].info "Could not find a machine, assuming it to be deleted or terminated."
env[:machine_state_id] = :not_created
end
else else
env[:machine_state_id] = :not_created env[:machine_state_id] = :not_created
end end

View File

@ -1,24 +1,18 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------
require "log4r"
module VagrantPlugins module VagrantPlugins
module HyperV module HyperV
module Action module Action
class StopInstance class StopInstance
def initialize(app, env) def initialize(app, env)
@app = app @app = app
end
def call(env)
env[:ui].info('Stopping the Machine')
options = { vm_id: env[:machine].id }
response = env[:machine].provider.driver.execute('stop_vm.ps1', options)
@app.call(env)
end
end end
def call(env)
env[:ui].info('Stopping the Machine')
options = { vm_id: env[:machine].id }
env[:machine].provider.driver.execute('stop_vm.ps1', options)
@app.call(env)
end
end
end end
end end
end end

View File

@ -38,11 +38,16 @@ module VagrantPlugins
end end
def state def state
# Run a custom action we define called "read_state" which does state_id = nil
# what it says. It puts the state in the `:machine_state_id` state_id = :not_created if !@machine.id
# key in the environment.
env = @machine.action("read_state") if !state_id
state_id = env[:machine_state_id] # Run a custom action we define called "read_state" which does
# what it says. It puts the state in the `:machine_state_id`
# key in the environment.
env = @machine.action(:read_state)
state_id = env[:machine_state_id]
end
# Get the short and long description # Get the short and long description
short = "Machine's current state is #{state_id}" short = "Machine's current state is #{state_id}"

View File

@ -1,30 +1,25 @@
#------------------------------------------------------------------------- Param(
# Copyright (c) Microsoft Open Technologies, Inc. [Parameter(Mandatory=$true)]
# All Rights Reserved. Licensed under the MIT License. [string]$VmId
#-------------------------------------------------------------------------- )
param (
[string]$vm_id = $(throw "-vm_id is required.")
)
# Include the following modules # Include the following modules
$presentDir = Split-Path -parent $PSCommandPath $Dir = Split-Path $script:MyInvocation.MyCommand.Path
$modules = @() . ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
$modules += $presentDir + "\utils\write_messages.ps1"
forEach ($module in $modules) { . $module }
# Get the VM with the given name
try { try {
$vm = Get-VM -Id $vm_id -ErrorAction "stop" $VM = Get-VM -Id $VmId -ErrorAction "Stop"
$state = $vm.state $State = $VM.state
$status = $vm.status $Status = $VM.status
$resultHash = @{ } catch [Microsoft.HyperV.PowerShell.VirtualizationOperationFailedException] {
state = "$state" $State = "not_created"
status = "$status" $Status = $State
} }
$result = ConvertTo-Json $resultHash
Write-Output-Message $result
$resultHash = @{
state = "$State"
status = "$Status"
} }
catch { $result = ConvertTo-Json $resultHash
Write-Error-Message $_ Write-Output-Message $result
}

View File

@ -1,144 +1,138 @@
param ( Param(
[string]$vm_xml_config = $(throw "-vm_xml_config is required."), [string]$vm_xml_config = $(throw "-vm_xml_config is required."),
[string]$vhdx_path = $(throw "-vhdx_path is required.") [string]$vhdx_path = $(throw "-vhdx_path is required.")
) )
$ErrorActionPreference = "Stop"
# Include the following modules # Include the following modules
$presentDir = Split-Path -parent $PSCommandPath $Dir = Split-Path $script:MyInvocation.MyCommand.Path
$modules = @() . [System.IO.Path]::Combine($Dir, "utils\write_messages.ps1")
$modules += $presentDir + "\utils\write_messages.ps1"
forEach ($module in $modules) { . $module }
try { [xml]$vmconfig = Get-Content -Path $vm_xml_config
[xml]$vmconfig = Get-Content -Path $vm_xml_config
$vm_name = $vmconfig.configuration.properties.name.'#text' $vm_name = $vmconfig.configuration.properties.name.'#text'
$processors = $vmconfig.configuration.settings.processors.count.'#text' $processors = $vmconfig.configuration.settings.processors.count.'#text'
function Get_unique_name($name) { function GetUniqueName($name) {
Get-VM | ForEach-Object -Process { Get-VM | ForEach-Object -Process {
if ($name -eq $_.Name) { if ($name -eq $_.Name) {
$name = $name + "_1" $name = $name + "_1"
} }
} }
return $name return $name
} }
do { do {
$name = $vm_name $name = $vm_name
$vm_name = Get_unique_name $name $vm_name = GetUniqueName $name
} while ($vm_name -ne $name) } while ($vm_name -ne $name)
$memory = (Select-Xml -xml $vmconfig -XPath "//memory").node.Bank $memory = (Select-Xml -xml $vmconfig -XPath "//memory").node.Bank
if ($memory.dynamic_memory_enabled."#text" -eq "True") { if ($memory.dynamic_memory_enabled."#text" -eq "True") {
$dynamicmemory = $True $dynamicmemory = $True
} }
else { else {
$dynamicmemory = $False $dynamicmemory = $False
} }
# Memory values need to be in bytes # Memory values need to be in bytes
$MemoryMaximumBytes = ($memory.limit."#text" -as [int]) * 1MB $MemoryMaximumBytes = ($memory.limit."#text" -as [int]) * 1MB
$MemoryStartupBytes = ($memory.size."#text" -as [int]) * 1MB $MemoryStartupBytes = ($memory.size."#text" -as [int]) * 1MB
$MemoryMinimumBytes = ($memory.reservation."#text" -as [int]) * 1MB $MemoryMinimumBytes = ($memory.reservation."#text" -as [int]) * 1MB
# Get the name of the virtual switch # Get the name of the virtual switch
$switchname = (Select-Xml -xml $vmconfig -XPath "//AltSwitchName").node."#text" $switchname = (Select-Xml -xml $vmconfig -XPath "//AltSwitchName").node."#text"
# Determine boot device # Determine boot device
Switch ((Select-Xml -xml $vmconfig -XPath "//boot").node.device0."#text") { Switch ((Select-Xml -xml $vmconfig -XPath "//boot").node.device0."#text") {
"Floppy" { $bootdevice = "floppy" } "Floppy" { $bootdevice = "floppy" }
"HardDrive" { $bootdevice = "IDE" } "HardDrive" { $bootdevice = "IDE" }
"Optical" { $bootdevice = "CD" } "Optical" { $bootdevice = "CD" }
"Network" { $bootdevice = "LegacyNetworkAdapter" } "Network" { $bootdevice = "LegacyNetworkAdapter" }
"Default" { $bootdevice = "IDE" } "Default" { $bootdevice = "IDE" }
} #switch } #switch
# Define a hash map of parameter values for New-VM # Define a hash map of parameter values for New-VM
$vm_params = @{ $vm_params = @{
Name = $vm_name Name = $vm_name
NoVHD = $True NoVHD = $True
MemoryStartupBytes = $MemoryStartupBytes MemoryStartupBytes = $MemoryStartupBytes
SwitchName = $switchname SwitchName = $switchname
BootDevice = $bootdevice BootDevice = $bootdevice
ErrorAction = "Stop" ErrorAction = "Stop"
} }
# Create the VM using the values in the hash map # Create the VM using the values in the hash map
$vm = New-VM @vm_params $vm = New-VM @vm_params
$notes = (Select-Xml -xml $vmconfig -XPath "//notes").node.'#text' $notes = (Select-Xml -xml $vmconfig -XPath "//notes").node.'#text'
# Set-VM parameters to configure new VM with old values # Set-VM parameters to configure new VM with old values
$more_vm_params = @{ $more_vm_params = @{
ProcessorCount = $processors ProcessorCount = $processors
MemoryStartupBytes = $MemoryStartupBytes MemoryStartupBytes = $MemoryStartupBytes
} }
If ($dynamicmemory) { If ($dynamicmemory) {
$more_vm_params.Add("DynamicMemory",$True) $more_vm_params.Add("DynamicMemory",$True)
$more_vm_params.Add("MemoryMinimumBytes",$MemoryMinimumBytes) $more_vm_params.Add("MemoryMinimumBytes",$MemoryMinimumBytes)
$more_vm_params.Add("MemoryMaximumBytes", $MemoryMaximumBytes) $more_vm_params.Add("MemoryMaximumBytes", $MemoryMaximumBytes)
} }
else { else {
$more_vm_params.Add("StaticMemory",$True) $more_vm_params.Add("StaticMemory",$True)
} }
if ($notes) { if ($notes) {
$more_vm_params.Add("Notes",$notes) $more_vm_params.Add("Notes",$notes)
} }
# Set the values on the VM # Set the values on the VM
$vm | Set-VM @more_vm_params -Passthru $vm | Set-VM @more_vm_params -Passthru
# Add drives to the virtual machine # Add drives to the virtual machine
$controllers = Select-Xml -xml $vmconfig -xpath "//*[starts-with(name(.),'controller')]" $controllers = Select-Xml -xml $vmconfig -xpath "//*[starts-with(name(.),'controller')]"
# A regular expression pattern to pull the number from controllers # A regular expression pattern to pull the number from controllers
[regex]$rx="\d" [regex]$rx="\d"
foreach ($controller in $controllers) { foreach ($controller in $controllers) {
$node = $controller.Node $node = $controller.Node
# Check for SCSI # Check for SCSI
if ($node.ParentNode.ChannelInstanceGuid) { if ($node.ParentNode.ChannelInstanceGuid) {
$ControllerType = "SCSI" $ControllerType = "SCSI"
} }
else { else {
$ControllerType = "IDE" $ControllerType = "IDE"
} }
$drives = $node.ChildNodes | where {$_.pathname."#text"} $drives = $node.ChildNodes | where {$_.pathname."#text"}
foreach ($drive in $drives) { foreach ($drive in $drives) {
#if drive type is ISO then set DVD Drive accordingly #if drive type is ISO then set DVD Drive accordingly
$driveType = $drive.type."#text" $driveType = $drive.type."#text"
$addDriveParam = @{ $addDriveParam = @{
ControllerNumber = $rx.Match($controller.node.name).value ControllerNumber = $rx.Match($controller.node.name).value
Path = $vhdx_path Path = $vhdx_path
} }
if ($drive.pool_id."#text") { if ($drive.pool_id."#text") {
$ResourcePoolName = $drive.pool_id."#text" $ResourcePoolName = $drive.pool_id."#text"
$addDriveParam.Add("ResourcePoolname",$ResourcePoolName) $addDriveParam.Add("ResourcePoolname",$ResourcePoolName)
} }
if ($drivetype -eq 'VHD') { if ($drivetype -eq 'VHD') {
$addDriveParam.add("ControllerType",$ControllerType) $addDriveParam.add("ControllerType",$ControllerType)
$vm | Add-VMHardDiskDrive @AddDriveparam $vm | Add-VMHardDiskDrive @AddDriveparam
} }
} }
} }
$vm_id = (Get-VM $vm_name).id.guid $vm_id = (Get-VM $vm_name).id.guid
$resultHash = @{ $resultHash = @{
name = $vm_name name = $vm_name
id = $vm_id id = $vm_id
}
$result = ConvertTo-Json $resultHash
Write-Output-Message $result
}
catch {
Write-Error-Message $_
return
} }
$result = ConvertTo-Json $resultHash
Write-Output-Message $result

View File

@ -1,8 +1,3 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------
param ( param (
[string]$vm_id = $(throw "-vm_id is required.") [string]$vm_id = $(throw "-vm_id is required.")
) )

View File

@ -45,4 +45,20 @@ describe VagrantPlugins::HyperV::Provider do
expect(subject.driver).to be_kind_of(VagrantPlugins::HyperV::Driver) expect(subject.driver).to be_kind_of(VagrantPlugins::HyperV::Driver)
end end
end end
describe "#state" do
it "returns not_created if no ID" do
machine.stub(id: nil)
expect(subject.state.id).to eq(:not_created)
end
it "calls an action to determine the ID" do
machine.stub(id: "foo")
machine.should_receive(:action).with(:read_state).
and_return({ machine_state_id: :bar })
expect(subject.state.id).to eq(:bar)
end
end
end end