-
Notifications
You must be signed in to change notification settings - Fork 0
/
simplebackup.py
161 lines (130 loc) · 6.9 KB
/
simplebackup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python
from pyVmomi import vmodl, vim
from tools import cli, tasks, service_instance, pchelper
from datetime import datetime
data = {}
nameOfSnapshot = 'Backup'
backupToDatastore = ''
def createSnapshot(vm):
print('Creating snapshot for VM:', vm.summary.config.name)
task: object = vm.CreateSnapshot_Task(name=nameOfSnapshot,
description="Automatic backup " + datetime.now().strftime(
"%Y-%m-%d %H:%M:%s"),
memory=True,
quiesce=False)
return task
def createFolderOnDatastore(fileManager, datacenter, folderName):
folderPath = backupToDatastore + " " + folderName
# Create directory in Datastore
fileManager.MakeDirectory(name=folderPath,
datacenter=datacenter,
createParentDirectories=True)
return folderPath
def copyVmFileToDatastore(fileManager, datacenter, sourceName, destinationName, force):
# Copy file
print("Copying file", sourceName, "to", destinationName)
task = fileManager.CopyDatastoreFile_Task(sourceName=sourceName,
sourceDatacenter=datacenter,
destinationName=destinationName,
destinationDatacenter=None,
force=force)
return task
def copyVmDiskToDatastore(diskManager, datacenter, sourceName, destinationName, force):
# Copy disk
print("Copying disk", sourceName, "to", destinationName)
task = diskManager.CopyVirtualDisk_Task(sourceName=sourceName,
sourceDatacenter=datacenter,
destName=destinationName,
destSpec=None,
force=force)
return task
def getSnapshotByName(snapshotList):
for snapshot in snapshotList:
if snapshot.name == nameOfSnapshot:
return snapshot
def removeSnapshot(vm):
print('Removing snapshot for VM:', vm.summary.config.name)
snapshot = getSnapshotByName(vm.snapshot.rootSnapshotList)
task: object = snapshot.snapshot.RemoveSnapshot_Task(removeChildren=True)
return task
def main():
"""
Iterate through all datacenters and list VM info.
"""
parser = cli.Parser()
parser.add_custom_argument('--backupDS', required=True, help='Datastore name to backup to.')
args = parser.get_args()
global backupToDatastore
backupToDatastore = '[' + args.backupDS + ']'
try:
si = service_instance.connect(args)
except vim.fault.InvalidLogin as il:
print(il.msg)
return -1
try:
content = si.RetrieveContent()
children = content.rootFolder.childEntity
fileMgr = content.fileManager
diskMgr = content.virtualDiskManager
# Check Backup Datastore exists
datastore = pchelper.search_for_obj(content, [vim.Datastore], args.backupDS)
if not datastore:
print("Datastore [", args.backupDS, "] cannot be found...")
return -1
for child in children: # Iterate though DataCenters
datacenter = child
data[datacenter.name] = {} # Add data Centers to data dict
clusters = datacenter.hostFolder.childEntity
for cluster in clusters: # Iterate through the clusters in the DC
# Add Clusters to data dict
data[datacenter.name][cluster.name] = {}
hosts = cluster.host # Variable to make pep8 compliance
for host in hosts: # Iterate through Hosts in the Cluster
hostname = host.summary.config.name
# Add VMs to data dict by config name
data[datacenter.name][cluster.name][hostname] = {}
vms = host.vm
vmsToBackup = open('backup.list', 'r')
for vmToBackup in vmsToBackup:
for vm in vms: # Iterate through each VM on the host
if str(vmToBackup.rstrip()) in vm.summary.config.name:
# Create folder
folderPath = createFolderOnDatastore(fileMgr,
datacenter,
datetime.now().strftime("%Y-%m-%d") +
"/" + vm.summary.config.name)
# Copy VMX file
task = copyVmFileToDatastore(fileMgr,
datacenter,
vm.config.files.vmPathName,
folderPath + "/" + vm.summary.config.name + ".vmx",
True)
tasks.wait_for_tasks(si, [task])
print('File copy finished!')
# Create Snapshot of VM
task = createSnapshot(vm)
tasks.wait_for_tasks(si, [task])
print('Snapshot creation finished!')
# Copy the Parent VMDKs
for device in vm.config.hardware.device:
# if device.__class__.__name__ == 'vim.vm.device.VirtualDisk':
if isinstance(device, vim.vm.device.VirtualDisk):
task = copyVmDiskToDatastore(diskMgr,
datacenter,
device.backing.parent.fileName,
folderPath + "/" +
device.backing.parent.fileName.rsplit('/')[1],
False)
tasks.wait_for_tasks(si, [task])
print('Disk copy finished!')
print('Backup finished!')
task = removeSnapshot(vm)
tasks.wait_for_tasks(si, [task])
print('Snapshot deletion finished!')
vmsToBackup.close()
except vmodl.MethodFault as error:
print("Caught vmodl fault : " + error.msg)
return -1
# Start program
if __name__ == "__main__":
main()