Skip to content

Commit

Permalink
providers/hyperv: initial commit
Browse files Browse the repository at this point in the history
Initial work done by MS Open Tech
  • Loading branch information
mitchellh committed Feb 27, 2014
1 parent 6b17783 commit ca24d60
Show file tree
Hide file tree
Showing 36 changed files with 1,676 additions and 0 deletions.
128 changes: 128 additions & 0 deletions plugins/providers/hyperv/action.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------

require "pathname"
require "vagrant/action/builder"

module VagrantPlugins
module HyperV
module Action
# Include the built-in modules so we can use them as top-level things.
include Vagrant::Action::Builtin

def self.action_reload
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
b2.use MessageNotCreated
next
end
b2.use action_halt
b2.use Call, WaitForState, :off, 120 do |env2, b3|
if env2[:result]
b3.use action_up
else
env2[:ui].info("Machine did not reload, Check machine's status")
end
end
end
end
end

def self.action_halt
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
b2.use MessageNotCreated
next
end
b2.use StopInstance
end
end
end

def self.action_start
Vagrant::Action::Builder.new.tap do |b|
b.use StartInstance
b.use ShareFolders
b.use SyncFolders
end
end

def self.action_up
Vagrant::Action::Builder.new.tap do |b|
b.use HandleBoxUrl
b.use ConfigValidate
b.use Call, IsCreated do |env1, b1|
if env1[:result]
b1.use Call, IsStopped do |env2, b2|
if env2[:result]
b2.use action_start
else
b2.use MessageAlreadyCreated
end
end
else
b1.use Import
b1.use action_start
end
end
end
end

def self.action_read_state
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use ReadState
end
end

def self.action_ssh
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use Call, IsCreated do |env, b2|
if !env[:result]
b2.use MessageNotCreated
next
end
b2.use Call, IsStopped do |env1, b3|
if env1[:result]
b3.use MessageNotRunning
else
b3.use SSHExec
end
end
end
end
end

def self.action_read_guest_ip
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use ReadGuestIP
end
end


# The autoload farm
action_root = Pathname.new(File.expand_path("../action", __FILE__))
autoload :IsCreated, action_root.join("is_created")
autoload :IsStopped, action_root.join("is_stopped")
autoload :ReadState, action_root.join("read_state")
autoload :Import, action_root.join("import")
autoload :StartInstance, action_root.join('start_instance')
autoload :StopInstance, action_root.join('stop_instance')
autoload :MessageNotCreated, action_root.join('message_not_created')
autoload :MessageAlreadyCreated, action_root.join('message_already_created')
autoload :MessageNotRunning, action_root.join('message_not_running')
autoload :SyncFolders, action_root.join('sync_folders')
autoload :WaitForState, action_root.join('wait_for_state')
autoload :ReadGuestIP, action_root.join('read_guest_ip')
autoload :ShareFolders, action_root.join('share_folders')
end
end
end
49 changes: 49 additions & 0 deletions plugins/providers/hyperv/action/import.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------

require "log4r"
module VagrantPlugins
module HyperV
module Action
class Import
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::hyperv::connection")
end

def call(env)
box_directory = env[:machine].box.directory.to_s
path = Pathname.new(box_directory.to_s + '/Virtual Machines')
config_path = ""
path.each_child do |f|
config_path = f.to_s if f.extname.downcase == ".xml"
end

path = Pathname.new(box_directory.to_s + '/Virtual Hard Disks')
vhdx_path = ""
path.each_child do |f|
vhdx_path = f.to_s if f.extname.downcase == ".vhdx"
end

options = {
vm_xml_config: config_path.gsub("/", "\\"),
vhdx_path: vhdx_path.gsub("/", "\\")
}

env[:ui].info "Importing a Hyper-V instance"
begin
server = env[:machine].provider.driver.execute('import_vm.ps1', options)
rescue Error::SubprocessError => e
env[:ui].info e.message
return
end
env[:ui].info "Successfully imported a VM with name #{server['name']}"
env[:machine].id = server["id"]
@app.call(env)
end
end
end
end
end
22 changes: 22 additions & 0 deletions plugins/providers/hyperv/action/is_created.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------

require "log4r"
module VagrantPlugins
module HyperV
module Action
class IsCreated
def initialize(app, env)
@app = app
end

def call(env)
env[:result] = env[:machine].state.id != :not_created
@app.call(env)
end
end
end
end
end
22 changes: 22 additions & 0 deletions plugins/providers/hyperv/action/is_stopped.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------

require "log4r"
module VagrantPlugins
module HyperV
module Action
class IsStopped
def initialize(app, env)
@app = app
end

def call(env)
env[:result] = env[:machine].state.id == :off
@app.call(env)
end
end
end
end
end
22 changes: 22 additions & 0 deletions plugins/providers/hyperv/action/message_already_created.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------

require "log4r"
module VagrantPlugins
module HyperV
module Action
class MessageAlreadyCreated
def initialize(app, env)
@app = app
end

def call(env)
env[:ui].info("Machine already created")
@app.call(env)
end
end
end
end
end
22 changes: 22 additions & 0 deletions plugins/providers/hyperv/action/message_not_created.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------

require "log4r"
module VagrantPlugins
module HyperV
module Action
class MessageNotCreated
def initialize(app, env)
@app = app
end

def call(env)
env[:ui].info("Machine not created")
@app.call(env)
end
end
end
end
end
22 changes: 22 additions & 0 deletions plugins/providers/hyperv/action/message_not_running.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------

require "log4r"
module VagrantPlugins
module HyperV
module Action
class MessageNotRunning
def initialize(app, env)
@app = app
end

def call(env)
env[:ui].info("Machine is not running, Please turn it on.")
@app.call(env)
end
end
end
end
end
46 changes: 46 additions & 0 deletions plugins/providers/hyperv/action/read_guest_ip.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------
require "log4r"
require "timeout"

module VagrantPlugins
module HyperV
module Action
# This action reads the SSH info for the machine and puts it into the
# `:machine_ssh_info` key in the environment.
class ReadGuestIP
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::hyperv::connection")
end

def call(env)
env[:machine_ssh_info] = read_host_ip(env)
@app.call(env)
end

def read_host_ip(env)
return nil if env[:machine].id.nil?
# Get Network details from WMI Provider
# Wait for 120 sec By then the machine should be ready
host_ip = nil
begin
Timeout.timeout(120) do
begin
options = { vm_id: env[:machine].id }
network_info = env[:machine].provider.driver.execute('get_network_config.ps1', options)
host_ip = network_info["ip"]
sleep 10 if host_ip.empty?
end while host_ip.empty?
end
rescue Timeout::Error
@logger.info("Cannot find the IP address of the virtual machine")
end
return { host: host_ip } unless host_ip.nil?
end
end
end
end
end
36 changes: 36 additions & 0 deletions plugins/providers/hyperv/action/read_state.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#-------------------------------------------------------------------------
# Copyright (c) Microsoft Open Technologies, Inc.
# All Rights Reserved. Licensed under the MIT License.
#--------------------------------------------------------------------------
require "debugger"
require "log4r"
module VagrantPlugins
module HyperV
module Action
class ReadState
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant::hyperv::connection")
end

def call(env)
if env[:machine].id
begin
options = { vm_id: env[:machine].id }
response = env[:machine].provider.driver.execute('get_vm_status.ps1', options)
env[:machine_state_id] = response["state"].downcase.to_sym
rescue Error::SubprocessError => e
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
env[:machine_state_id] = :not_created
end
@app.call(env)
end

end
end
end
end
Loading

0 comments on commit ca24d60

Please sign in to comment.