-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathvmguestlib.py
457 lines (399 loc) · 21.3 KB
/
vmguestlib.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
### This program is free software; you can redistribute it and/or
### modify it under the terms of the GNU General Public License
### as published by the Free Software Foundation; either version 2
### of the License, or (at your option) any later version.
###
### This program is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with this program; if not, write to the Free Software
### Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
### Copyright 2013-2014 Dag Wieers <dag@wieers.com>
from ctypes import *
from ctypes.util import find_library
__author__ = 'Dag Wieers <dag@wieers.com>'
__version__ = '0.1.2'
__version_info__ = tuple([ int(d) for d in __version__.split('.') ])
__license__ = 'GNU General Public License (GPL)'
# TODO: Implement support for Windows and MacOSX, improve Linux support ?
if find_library('vmGuestLib'):
vmGuestLib = CDLL(find_library('vmGuestLib'))
elif find_library('guestlib'):
vmGuestLib = CDLL(find_library('guestlib'))
#elif os.path.exists('/usr/lib/vmware-tools/lib/libvmGuestLib.so/libvmGuestLib.so'):
# vmGuestLib = CDLL('/usr/lib/vmware-tools/lib/libvmGuestLib.so/libvmGuestLib.so')
#elif os.path.exists('%PROGRAMFILES%\\VMware\\VMware Tools\\Guest SDK\\vmStatsProvider\win32\\vmGuestLib.dll'):
# vmGuestLib = CDLL('%PROGRAMFILES%\\VMware\\VMware Tools\\Guest SDK\\vmStatsProvider\win32\\vmGuestLib.dll')
else:
raise Exception, 'ERROR: Cannot find vmGuestLib library in LD_LIBRARY_PATH'
VMGUESTLIB_ERROR_SUCCESS = 0
VMGUESTLIB_ERROR_OTHER = 1
VMGUESTLIB_ERROR_NOT_RUNNING_IN_VM = 2
VMGUESTLIB_ERROR_NOT_ENABLED = 3
VMGUESTLIB_ERROR_NOT_AVAILABLE = 4
VMGUESTLIB_ERROR_NO_INFO = 5
VMGUESTLIB_ERROR_MEMORY = 6
VMGUESTLIB_ERROR_BUFFER_TOO_SMALL = 7
VMGUESTLIB_ERROR_INVALID_HANDLE = 8
VMGUESTLIB_ERROR_INVALID_ARG = 9
VMGUESTLIB_ERROR_UNSUPPORTED_VERSION = 10
VMErrors = (
'VMGUESTLIB_ERROR_SUCCESS',
'VMGUESTLIB_ERROR_OTHER',
'VMGUESTLIB_ERROR_NOT_RUNNING_IN_VM',
'VMGUESTLIB_ERROR_NOT_ENABLED',
'VMGUESTLIB_ERROR_NOT_AVAILABLE',
'VMGUESTLIB_ERROR_NO_INFO',
'VMGUESTLIB_ERROR_MEMORY',
'VMGUESTLIB_ERROR_BUFFER_TOO_SMALL',
'VMGUESTLIB_ERROR_INVALID_HANDLE',
'VMGUESTLIB_ERROR_INVALID_ARG',
'VMGUESTLIB_ERROR_UNSUPPORTED_VERSION',
)
VMErrMsgs = (
'The function has completed successfully.',
'An error has occurred. No additional information about the type of error is available.',
'The program making this call is not running on a VMware virtual machine.',
'The vSphere Guest API is not enabled on this host, so these functions cannot be used. For information about how to enable the library, see "Context Functions" on page 9.',
'The information requested is not available on this host.',
'The handle data structure does not contain any information. You must call VMGuestLib_UpdateInfo to update the data structure.',
'There is not enough memory available to complete the call.',
'The buffer is too small to accommodate the function call. For example, when you call VMGuestLib_GetResourcePoolPath, if the path buffer is too small for the resulting resource pool path, the function returns this error. To resolve this error, allocate a larger buffer.',
'The handle that you used is invalid. Make sure that you have the correct handle and that it is open. It might be necessary to create a new handle using VMGuestLib_OpenHandle.',
'One or more of the arguments passed to the function were invalid.',
'The host does not support the requested statistic.',
)
class VMGuestLibException(Exception):
'''Status code that indicates success orfailure. Each function returns a
VMGuestLibError code. For information about specific error codes, see "vSphere
Guest API Error Codes" on page 15. VMGuestLibError is an enumerated type
defined in vmGuestLib.h.'''
def __init__(self, errno):
self.errno = errno
self.GetErrorText = vmGuestLib.VMGuestLib_GetErrorText
self.GetErrorText.restype = c_char_p
self.message = self.GetErrorText(self.errno)
self.strerr = VMErrMsgs[self.errno]
def __str__(self):
return '%s\n%s' % (self.message, self.strerr)
class VMGuestLib(Structure):
def __init__(self):
# Reference to virtualmachinedata. VMGuestLibHandle is defined in vmGuestLib.h.
self.handle = self.OpenHandle()
self.UpdateInfo()
# Unique identifier for a session. The session ID changes after a virtual machine is
# migrated using VMotion, suspended and resumed, or reverted to a snapshot. Any of
# these events is likely to render any information retrieved with this API invalid. You
# can use the session ID to detect those events and react accordingly. For example, you
# can refresh and reset any state that relies on the validity of previously retrieved
# information.
# Use VMGuestLib_GetSessionId to obtain a valid session ID. A session ID is
# opaque. You cannot compare a virtual machine session ID with the session IDs from
# any other virtual machines. You must always call VMGuestLib_GetSessionId after
# calling VMGuestLib_UpdateInfo.
# VMSessionID is defined in vmSessionId.h
self.sid = self.GetSessionId()
def OpenHandle(self):
'''Gets a handle for use with other vSphere Guest API functions. The guest library
handle provides a context for accessing information about the virtual machine.
Virtual machine statistics and state data are associated with a particular guest library
handle, so using one handle does not affect the data associated with another handle.'''
if hasattr(self, 'handle'):
return self.handle
else:
handle = c_void_p()
ret = vmGuestLib.VMGuestLib_OpenHandle(byref(handle))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return handle
def CloseHandle(self):
'''Releases a handle acquired with VMGuestLib_OpenHandle'''
if hasattr(self, 'handle'):
ret = vmGuestLib.VMGuestLib_CloseHandle(self.handle)
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
del(self.handle)
def UpdateInfo(self):
'''Updates information about the virtual machine. This information is associated with
the VMGuestLibHandle.
VMGuestLib_UpdateInfo requires similar CPU resources to a system call and
therefore can affect performance. If you are concerned about performance, minimize
the number of calls to VMGuestLib_UpdateInfo.
If your program uses multiple threads, each thread must use a different handle.
Otherwise, you must implement a locking scheme around update calls. The vSphere
Guest API does not implement internal locking around access with a handle.'''
ret = vmGuestLib.VMGuestLib_UpdateInfo(self.handle)
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
def GetSessionId(self):
'''Retrieves the VMSessionID for the current session. Call this function after calling
VMGuestLib_UpdateInfo. If VMGuestLib_UpdateInfo has never been called,
VMGuestLib_GetSessionId returns VMGUESTLIB_ERROR_NO_INFO.'''
sid = c_void_p()
ret = vmGuestLib.VMGuestLib_GetSessionId(self.handle, byref(sid))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return sid
def GetCpuLimitMHz(self):
'''Retrieves the upperlimit of processor use in MHz available to the virtual
machine. For information about setting the CPU limit, see "Limits and
Reservations" on page 14.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetCpuLimitMHz(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetCpuReservationMHz(self):
'''Retrieves the minimum processing power in MHz reserved for the virtual
machine. For information about setting a CPU reservation, see "Limits and
Reservations" on page 14.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetCpuReservationMHz(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetCpuShares(self):
'''Retrieves the number of CPU shares allocated to the virtual machine. For
information about how an ESX server uses CPU shares to manage virtual
machine priority, see the vSphere Resource Management Guide.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetCpuShares(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetCpuStolenMs(self):
'''Retrieves the number of milliseconds that the virtual machine was in a
ready state (able to transition to a run state), but was not scheduled to run.'''
counter = c_uint64()
ret = vmGuestLib.VMGuestLib_GetCpuStolenMs(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetCpuUsedMs(self):
'''Retrieves the number of milliseconds during which the virtual machine
has used the CPU. This value includes the time used by the guest
operating system and the time used by virtualization code for tasks for this
virtual machine. You can combine this value with the elapsed time
(VMGuestLib_GetElapsedMs) to estimate the effective virtual machine
CPU speed. This value is a subset of elapsedMs.'''
counter = c_uint64()
ret = vmGuestLib.VMGuestLib_GetCpuUsedMs(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetElapsedMs(self):
'''Retrieves the number of milliseconds that have passed in the virtual
machine since it last started running on the server. The count of elapsed
time restarts each time the virtual machine is powered on, resumed, or
migrated using VMotion. This value counts milliseconds, regardless of
whether the virtual machine is using processing power during that time.
You can combine this value with the CPU time used by the virtual machine
(VMGuestLib_GetCpuUsedMs) to estimate the effective virtual machine
CPU speed. cpuUsedMs is a subset of this value.'''
counter = c_uint64()
ret = vmGuestLib.VMGuestLib_GetElapsedMs(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostCpuUsedMs(self):
'''Undocumented.'''
counter = c_uint64()
ret = vmGuestLib.VMGuestLib_GetHostCpuUsedMs(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostMemKernOvhdMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostMemKernOvhdMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostMemMappedMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostMemMappedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostMemPhysFreeMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostMemPhysFreeMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostMemPhysMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostMemPhysMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostMemSharedMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostMemSharedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostMemSwappedMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostMemSwappedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostMemUnmappedMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostMemUnmappedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostMemUsedMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostMemUsedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetHostNumCpuCores(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostNumCpuCores(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetHostProcessorSpeed(self):
'''Retrieves the speed of the ESX system's physical CPU in MHz.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetHostProcessorSpeed(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemActiveMB(self):
'''Retrieves the amount of memory the virtual machine is actively using its
estimated working set size.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemActiveMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemBalloonedMB(self):
'''Retrieves the amount of memory that has been reclaimed from this virtual
machine by the vSphere memory balloon driver (also referred to as the
"vmmemctl" driver).'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemBalloonedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetMemBalloonMaxMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemBalloonMaxMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetMemBalloonTargetMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemBalloonTargetMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemLimitMB(self):
'''Retrieves the upper limit of memory that is available to the virtual
machine. For information about setting a memory limit, see "Limits and
Reservations" on page 14.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemLimitMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetMemLLSwappedMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemLLSwappedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemMappedMB(self):
'''Retrieves the amount of memory that is allocated to the virtual machine.
Memory that is ballooned, swapped, or has never been accessed is
excluded.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemMappedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemOverheadMB(self):
'''Retrieves the amount of "overhead" memory associated with this virtual
machine that is currently consumed on the host system. Overhead
memory is additional memory that is reserved for data structures required
by the virtualization layer.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemOverheadMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemReservationMB(self):
'''Retrieves the minimum amount of memory that is reserved for the virtual
machine. For information about setting a memory reservation, see "Limits
and Reservations" on page 14.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemReservationMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemSharedMB(self):
'''Retrieves the amount of physical memory associated with this virtual
machine that is copy-on-write (COW) shared on the host.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemSharedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemSharedSavedMB(self):
'''Retrieves the estimated amount of physical memory on the host saved
from copy-on-write (COW) shared guest physical memory.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemSharedSavedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemShares(self):
'''Retrieves the number of memory shares allocated to the virtual machine.
For information about how an ESX server uses memory shares to manage
virtual machine priority, see the vSphere Resource Management Guide.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemShares(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemSwappedMB(self):
'''Retrieves the amount of memory that has been reclaimed from this virtual
machine by transparently swapping guest memory to disk.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemSwappedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetMemSwapTargetMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemSwapTargetMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemTargetSizeMB(self):
'''Retrieves the size of the target memory allocation for this virtual machine.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemTargetSizeMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
def GetMemUsedMB(self):
'''Retrieves the estimated amount of physical host memory currently
consumed for this virtual machine's physical memory.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemUsedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetMemZippedMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemZippedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# TODO: Undocumented routine, needs testing
def GetMemZipSavedMB(self):
'''Undocumented.'''
counter = c_uint()
ret = vmGuestLib.VMGuestLib_GetMemZipSavedMB(self.handle, byref(counter))
if ret != VMGUESTLIB_ERROR_SUCCESS: raise VMGuestLibException(ret)
return counter.value
# vim:ts=4:sw=4:et