Skip to content

Commit

Permalink
Issue #17: Commit widget for cloning a virtual machine
Browse files Browse the repository at this point in the history
  • Loading branch information
dnaeon committed Apr 29, 2015
1 parent 81ac887 commit 4eb2bad
Showing 1 changed file with 182 additions and 0 deletions.
182 changes: 182 additions & 0 deletions src/pvc/widget/virtualmachine.py
Expand Up @@ -63,6 +63,7 @@
'MigrateVirtualMachineWidget',
'VirtualMachineChangeHostWidget',
'VirtualMachineChangeDatastoreWidget',
'VirtualMachineCloneWidget',
]


Expand Down Expand Up @@ -107,6 +108,12 @@ def display(self):
on_select=MigrateVirtualMachineWidget,
on_select_args=(self.agent, self.dialog, self.obj)
),
pvc.widget.menu.MenuItem(
tag='Clone',
description='Clone Virtual Machine',
on_select=VirtualMachineCloneWidget,
on_select_args=(self.agent, self.dialog, self.obj)
),
pvc.widget.menu.MenuItem(
tag='Power',
description='Virtual Machine Power Options',
Expand Down Expand Up @@ -1747,3 +1754,178 @@ def relocation_would_succeed(self, datastore):
return False # Relocation would not succeed

return True


class VirtualMachineCloneWidget(object):
def __init__(self, agent, dialog, obj):
"""
Widget for cloning a Virtual Machine
Args:
agent (VConnector): A VConnector instance
dialog (dialog.Dialog): A Dialog instance
obj (vim.VirtualMachine): A VirtualMachine managed entity
"""
self.agent = agent
self.dialog = dialog
self.obj = obj
self.title = '{} ({})'.format(self.obj.name, self.obj.__class__.__name__)
self.display()

def display(self):
code, name = self.dialog.inputbox(
title='Clone Virtual Machine',
text='Name of the target Virtual Machine clone'
)

if code in (self.dialog.CANCEL, self.dialog.ESC):
return

datacenter = self.select_datacenter()
if not datacenter:
return

cluster = self.select_cluster(folder=datacenter)
if not cluster:
return

drs_config = cluster.configuration.drsConfig
drs_enabled = drs_config.enabled
drs_fully_automated = drs_config.defaultVmBehavior == pyVmomi.vim.cluster.DrsConfigInfo.DrsBehavior.fullyAutomated
dynamic_placement = drs_enabled and drs_fully_automated

host = None
if not dynamic_placement:
host = pvc.widget.common.choose_host(
agent=self.agent,
dialog=self.dialog,
folder=cluster
)

if not host:
self.dialog.msgbox(
title='Clone Virtual Machine',
text='No valid host selected'
)
return

if not dynamic_placement:
datastore = self.select_datastore(obj=host)
else:
datastore = self.select_datastore(obj=cluster)

if not datastore:
return

folder = datacenter.vmFolder
pool = cluster.resourcePool
relocate_spec = pyVmomi.vim.VirtualMachineRelocateSpec(
datastore=datastore,
host=host,
pool=pool
)

clone_spec = pyVmomi.vim.VirtualMachineCloneSpec(
location=relocate_spec,
powerOn=False,
template=False
)

task = self.obj.CloneVM_Task(
folder=folder,
name=name,
spec=clone_spec
)

gauge = pvc.widget.gauge.TaskGauge(
dialog=self.dialog,
task=task,
title='Clone Virtual Machine {}'.format(self.title),
text='Cloning virtual machine {} to {} ...'.format(self.obj.name, name)
)

gauge.display()

def select_datacenter(self):
"""
Select datacenter for Virtual Machine clone placement
Returns:
A vim.Datacenter managed entity upon successfuly selecting
an existing vim.Datacenter instance, None otherwise
"""
datacenter = pvc.widget.common.choose_datacenter(
agent=self.agent,
dialog=self.dialog
)

if not datacenter:
return

if not datacenter.hostFolder.childEntity:
self.dialog.msgbox(
title='Clone Virtual Machine',
text='No compute resources found in datacenter {}'.format(datacenter.name)
)
return

return datacenter

def select_cluster(self, folder):
"""
Select a cluster for Virtual Machine clone placement
Args:
folder (vim.Folder): A vim.Folder instance
Returns:
A vim.ClusterComputeResource managed entity upon successufuly
selecting an existing cluster, None otherwise
"""
cluster = pvc.widget.common.choose_cluster(
agent=self.agent,
dialog=self.dialog,
folder=folder
)

if not cluster:
return

if not cluster.host:
self.dialog.msgbox(
title='Clone Virtual Machine',
text='No valid hosts found in cluster {}'.format(cluster.name)
)
return

return cluster

def select_datastore(self, obj):
"""
Select datastore for Virtual Machine clone placement
Args:
obj (vim.ManagedEntity): A Managed Entity containing datastores
Returns:
A vim.Datastore managed entity upon successfully
selecting a datastore, None otherwise
"""
if not obj.datastore:
self.dialog.msgbox(
title='Clone Virtual Machine',
text='No datastores found on {}'.format(obj.name)
)
return

datastore = pvc.widget.common.choose_datastore(
agent=self.agent,
dialog=self.dialog,
obj=obj
)

return datastore

0 comments on commit 4eb2bad

Please sign in to comment.