examples/event-test.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
Hello, event-test.py is bad at handling newer livecycle events. Attached are two patches to improve that. Philipp Hahn (2): event-test.py: Sync list of domain lifecycle events event-test.py: Future proof lifecycle event handling examples/event-test.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) -- 2.11.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 09/20/2018 08:10 AM, Philipp Hahn wrote: > Hello, > > event-test.py is bad at handling newer livecycle events. > Attached are two patches to improve that. > > Philipp Hahn (2): > event-test.py: Sync list of domain lifecycle events > event-test.py: Future proof lifecycle event handling > > examples/event-test.py | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) > Philipp, ACK to the first patch, no doubt about that. However, the second one - I'm torn. One one hand it makes the code more future proof, on the other - seeing a traceback (which is easy to spot) might inspire users to post patches (because we are obviously not doing a good job in keeping event-test.py in sync with libvirt). What do you think? Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Am 21.09.18 um 13:14 schrieb Michal Privoznik: > On 09/20/2018 08:10 AM, Philipp Hahn wrote: >> event-test.py is bad at handling newer livecycle events. >> Attached are two patches to improve that. >> >> Philipp Hahn (2): >> event-test.py: Sync list of domain lifecycle events >> event-test.py: Future proof lifecycle event handling >> >> examples/event-test.py | 18 ++++++++++++------ >> 1 file changed, 12 insertions(+), 6 deletions(-) > > ACK to the first patch, no doubt about that. However, the second one - > I'm torn. One one hand it makes the code more future proof, on the other > - seeing a traceback (which is easy to spot) might inspire users to post > patches (because we are obviously not doing a good job in keeping > event-test.py in sync with libvirt). What do you think? Yes, I can understand it, but each time I use event-test.py (spaced months apart) I get the next crash. So I really would like it to be more future poof. If the number is annoying enough, any interested user is free so send a patch to improve it. As the pattern of printing some details is quiet common in that script, I did a v2 and added a somehow hacky class 'Description' to simplify writing those descriptive texts. Please have a look at the following series as an alternative. I also found some other issues I fixed along the way. Philipp Hahn (22): event-test.py: Handle closed connection event-test.py: Remove extra parenthesis event-test.py: Remove dead assignment event-test.py: Add missing globale statement event-test.py: Use __file__ event-test.py: Merge livecycle callbacks event-test.py: Simplify event ID lists event-test.py: Add class for event descriptions event-test.py: Convert LIVECYCLE events event-test.py: Convert BLOCKJOB events event-test.py: Convert WATCHDOG events event-test.py: Convert ERROR events event-test.py: Convert AGENT events event-test.py: Convert GRAPHICS events event-test.py: Convert DISK events event-test.py: Convert TRAY events event-test.py: Convert NETWORK events event-test.py: Convert STORAGE events event-test.py: Convert DEVICE events event-test.py: Convert SECRET events event-test.py: Convert CONNECTION events event-test.py: Fix blanks examples/event-test.py | 446 +++++++++++++++++++++++++++++-------------------- 1 file changed, 262 insertions(+), 184 deletions(-) -- 2.11.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 09/21/2018 03:34 PM, Philipp Hahn wrote: > Am 21.09.18 um 13:14 schrieb Michal Privoznik: >> On 09/20/2018 08:10 AM, Philipp Hahn wrote: >>> event-test.py is bad at handling newer livecycle events. >>> Attached are two patches to improve that. >>> >>> Philipp Hahn (2): >>> event-test.py: Sync list of domain lifecycle events >>> event-test.py: Future proof lifecycle event handling >>> >>> examples/event-test.py | 18 ++++++++++++------ >>> 1 file changed, 12 insertions(+), 6 deletions(-) >> >> ACK to the first patch, no doubt about that. However, the second one - >> I'm torn. One one hand it makes the code more future proof, on the other >> - seeing a traceback (which is easy to spot) might inspire users to post >> patches (because we are obviously not doing a good job in keeping >> event-test.py in sync with libvirt). What do you think? > > Yes, I can understand it, but each time I use event-test.py (spaced months > apart) I get the next crash. So I really would like it to be more future poof. > If the number is annoying enough, any interested user is free so send a patch > to improve it. > > As the pattern of printing some details is quiet common in that script, I did a > v2 and added a somehow hacky class 'Description' to simplify writing those > descriptive texts. Please have a look at the following series as an alternative. > > I also found some other issues I fixed along the way. > > Philipp Hahn (22): > event-test.py: Handle closed connection > event-test.py: Remove extra parenthesis > event-test.py: Remove dead assignment > event-test.py: Add missing globale statement > event-test.py: Use __file__ > event-test.py: Merge livecycle callbacks > event-test.py: Simplify event ID lists > event-test.py: Add class for event descriptions > event-test.py: Convert LIVECYCLE events > event-test.py: Convert BLOCKJOB events > event-test.py: Convert WATCHDOG events > event-test.py: Convert ERROR events > event-test.py: Convert AGENT events > event-test.py: Convert GRAPHICS events > event-test.py: Convert DISK events > event-test.py: Convert TRAY events > event-test.py: Convert NETWORK events > event-test.py: Convert STORAGE events > event-test.py: Convert DEVICE events > event-test.py: Convert SECRET events > event-test.py: Convert CONNECTION events > event-test.py: Fix blanks > > examples/event-test.py | 446 +++++++++++++++++++++++++++++-------------------- > 1 file changed, 262 insertions(+), 184 deletions(-) > Yup, this looks very good. So I'll merge 1/2 from the original v1 and all 22 patches from this v2. ACK Thanks, Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
If libvirtd terminates while event-test.py has an open connection to it,
it will crash with the following traceback:
> myConnectionCloseCallback: qemu:///session: Error
> Exception in thread libvirtEventLoop:
> Traceback (most recent call last):
> File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
> self.run()
> File "/usr/lib/python2.7/threading.py", line 754, in run
> self.__target(*self.__args, **self.__kwargs)
> File "examples/event-test.py", line 424, in virEventLoopPollRun
> eventLoop.run_loop()
> File "examples/event-test.py", line 242, in run_loop
> self.run_once()
> File "examples/event-test.py", line 187, in run_once
> libvirt.virEventInvokeFreeCallback(opaque)
> AttributeError: 'module' object has no attribute 'virEventInvokeFreeCallback'
>
> libvirt: XML-RPC error : internal error: client socket is closed
> Traceback (most recent call last):
> File "examples/event-test.py", line 872, in <module>
> main()
> File "examples/event-test.py", line 854, in main
> vc.secretEventDeregisterAny(id)
> File "/usr/lib/python2.7/dist-packages/libvirt.py", line 4987, in secretEventDeregisterAny
> if ret == -1: raise libvirtError ('virConnectSecretEventDeregisterAny() failed', conn=self)
> libvirt.libvirtError: internal error: client socket is closed
> Closing qemu:///session
Skip unregistering the event callbacks and closing the connection if the
connection is already broken / closed.
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 04310e1..c17d2bb 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -716,7 +716,8 @@ def main():
old_exitfunc = getattr(sys, 'exitfunc', None)
def exit():
print("Closing " + vc.getURI())
- vc.close()
+ if run:
+ vc.close()
if (old_exitfunc): old_exitfunc()
sys.exitfunc = exit
@@ -777,6 +778,11 @@ def main():
count = count + 1
time.sleep(1)
+ # If the connection was closed, we cannot unregister anything.
+ # Just abort now.
+ if not run:
+ return
+
vc.domainEventDeregister(myDomainEventCallback1)
for id in seccallbacks:
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index c17d2bb..a7c7054 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -224,7 +224,7 @@ class virEventLoopPoll:
want = t.get_last_fired() + interval
# Deduct 20ms, since scheduler timeslice
# means we could be ever so slightly early
- if now >= (want-20):
+ if now >= want - 20:
debug("Dispatch timer %d now %s want %s" % (t.get_id(), str(now), str(want)))
t.set_last_fired(now)
t.dispatch()
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
variable is unused
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index a7c7054..1f34930 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -207,7 +207,7 @@ class virEventLoopPoll:
# the data just continue
if fd == self.pipetrick[0]:
self.pendingWakeup = False
- data = os.read(fd, 1)
+ os.read(fd, 1)
continue
h = self.get_handle_by_fd(fd)
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to fix loop termination on exit.
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/examples/event-test.py b/examples/event-test.py
index 1f34930..646ce50 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -663,6 +663,7 @@ def myConnectionCloseCallback(conn, reason, opaque):
"Error", "End-of-file", "Keepalive", "Client",
)
print("myConnectionCloseCallback: %s: %s" % (conn.getURI(), reasonStrings[reason]))
+ global run
run = False
def usage():
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
instead of sys.argv[0]
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 646ce50..ab1da4a 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -667,7 +667,7 @@ def myConnectionCloseCallback(conn, reason, opaque):
run = False
def usage():
- print("usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]")
+ print("usage: %s [-hdl] [uri]" % (os.path.basename(__file__),))
print(" uri will default to qemu:///system")
print(" --help, -h Print this help message")
print(" --debug, -d Print debug output")
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Registering the same function twice using the old domainEventRegister()
interface would not work, as the function reference is used for
un-registering.
But it is not a problem with the new interface domainEventRegisterAn(),
as that returns a unique ID.
While at it also demonstrate the 'opaque' mechanism.
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index ab1da4a..2dcdee3 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -499,15 +499,11 @@ def agentLifecycleReasonToString(reason):
agentReasons = ( "unknown", "domain started", "channel event", )
return agentReasons[reason]
-def myDomainEventCallback1 (conn, dom, event, detail, opaque):
- print("myDomainEventCallback1 EVENT: Domain %s(%s) %s %s" % (dom.name(), dom.ID(),
- domEventToString(event),
- domDetailToString(event, detail)))
-def myDomainEventCallback2 (conn, dom, event, detail, opaque):
- print("myDomainEventCallback2 EVENT: Domain %s(%s) %s %s" % (dom.name(), dom.ID(),
- domEventToString(event),
- domDetailToString(event, detail)))
+def myDomainEventCallback(conn, dom, event, detail, opaque):
+ print("myDomainEventCallback%d EVENT: Domain %s(%s) %s %s" % (
+ opaque, dom.name(), dom.ID(), domEventToString(event), domDetailToString(event, detail)))
+
def myDomainEventRebootCallback(conn, dom, opaque):
print("myDomainEventRebootCallback: Domain %s(%s)" % (dom.name(), dom.ID()))
@@ -725,9 +721,9 @@ def main():
vc.registerCloseCallback(myConnectionCloseCallback, None)
#Add 2 lifecycle callbacks to prove this works with more than just one
- vc.domainEventRegister(myDomainEventCallback1,None)
+ vc.domainEventRegister(myDomainEventCallback, 1)
domcallbacks = []
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback2, None))
+ domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback, 2))
domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_REBOOT, myDomainEventRebootCallback, None))
domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE, myDomainEventRTCChangeCallback, None))
domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG, myDomainEventWatchdogCallback, None))
@@ -784,7 +780,7 @@ def main():
if not run:
return
- vc.domainEventDeregister(myDomainEventCallback1)
+ vc.domainEventDeregister(myDomainEventCallback)
for id in seccallbacks:
vc.secretEventDeregisterAny(id)
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
by directly building the list with the IDs instead of appending them
explicitly.
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 87 ++++++++++++++++++++++++++------------------------
1 file changed, 46 insertions(+), 41 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 2dcdee3..91a7cb7 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -722,47 +722,52 @@ def main():
#Add 2 lifecycle callbacks to prove this works with more than just one
vc.domainEventRegister(myDomainEventCallback, 1)
- domcallbacks = []
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback, 2))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_REBOOT, myDomainEventRebootCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE, myDomainEventRTCChangeCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG, myDomainEventWatchdogCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR, myDomainEventIOErrorCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS, myDomainEventGraphicsCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON, myDomainEventIOErrorReasonCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_CONTROL_ERROR, myDomainEventControlErrorCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB, myDomainEventBlockJobCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DISK_CHANGE, myDomainEventDiskChangeCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, myDomainEventTrayChangeCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, myDomainEventBalloonChangeCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK, myDomainEventPMSuspendDiskCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, myDomainEventDeviceRemovedCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2, myDomainEventBlockJob2Callback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_TUNABLE, myDomainEventTunableCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE, myDomainEventAgentLifecycleCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_ADDED, myDomainEventDeviceAddedCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION, myDomainEventMigrationIteration, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_JOB_COMPLETED, myDomainEventJobCompletedCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED, myDomainEventDeviceRemovalFailedCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_METADATA_CHANGE, myDomainEventMetadataChangeCallback, None))
- domcallbacks.append(vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD, myDomainEventBlockThresholdCallback, None))
-
- netcallbacks = []
- netcallbacks.append(vc.networkEventRegisterAny(None, libvirt.VIR_NETWORK_EVENT_ID_LIFECYCLE, myNetworkEventLifecycleCallback, None))
-
- poolcallbacks = []
- poolcallbacks.append(vc.storagePoolEventRegisterAny(None, libvirt.VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE, myStoragePoolEventLifecycleCallback, None))
- poolcallbacks.append(vc.storagePoolEventRegisterAny(None, libvirt.VIR_STORAGE_POOL_EVENT_ID_REFRESH, myStoragePoolEventRefreshCallback, None))
-
- devcallbacks = []
- devcallbacks.append(vc.nodeDeviceEventRegisterAny(None, libvirt.VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE, myNodeDeviceEventLifecycleCallback, None))
- devcallbacks.append(vc.nodeDeviceEventRegisterAny(None, libvirt.VIR_NODE_DEVICE_EVENT_ID_UPDATE, myNodeDeviceEventUpdateCallback, None))
-
- seccallbacks = []
- seccallbacks.append(vc.secretEventRegisterAny(None, libvirt.VIR_SECRET_EVENT_ID_LIFECYCLE, mySecretEventLifecycleCallback, None))
- seccallbacks.append(vc.secretEventRegisterAny(None, libvirt.VIR_SECRET_EVENT_ID_VALUE_CHANGED, mySecretEventValueChanged, None))
+ domcallbacks = [
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback, 2),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_REBOOT, myDomainEventRebootCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE, myDomainEventRTCChangeCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG, myDomainEventWatchdogCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR, myDomainEventIOErrorCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS, myDomainEventGraphicsCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON, myDomainEventIOErrorReasonCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_CONTROL_ERROR, myDomainEventControlErrorCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB, myDomainEventBlockJobCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DISK_CHANGE, myDomainEventDiskChangeCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, myDomainEventTrayChangeCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, myDomainEventBalloonChangeCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK, myDomainEventPMSuspendDiskCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, myDomainEventDeviceRemovedCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2, myDomainEventBlockJob2Callback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_TUNABLE, myDomainEventTunableCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE, myDomainEventAgentLifecycleCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_ADDED, myDomainEventDeviceAddedCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION, myDomainEventMigrationIteration, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_JOB_COMPLETED, myDomainEventJobCompletedCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED, myDomainEventDeviceRemovalFailedCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_METADATA_CHANGE, myDomainEventMetadataChangeCallback, None),
+ vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD, myDomainEventBlockThresholdCallback, None),
+ ]
+
+ netcallbacks = [
+ vc.networkEventRegisterAny(None, libvirt.VIR_NETWORK_EVENT_ID_LIFECYCLE, myNetworkEventLifecycleCallback, None),
+ ]
+
+ poolcallbacks = [
+ vc.storagePoolEventRegisterAny(None, libvirt.VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE, myStoragePoolEventLifecycleCallback, None),
+ vc.storagePoolEventRegisterAny(None, libvirt.VIR_STORAGE_POOL_EVENT_ID_REFRESH, myStoragePoolEventRefreshCallback, None),
+ ]
+
+ devcallbacks = [
+ vc.nodeDeviceEventRegisterAny(None, libvirt.VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE, myNodeDeviceEventLifecycleCallback, None),
+ vc.nodeDeviceEventRegisterAny(None, libvirt.VIR_NODE_DEVICE_EVENT_ID_UPDATE, myNodeDeviceEventUpdateCallback, None),
+ ]
+
+ seccallbacks = [
+ vc.secretEventRegisterAny(None, libvirt.VIR_SECRET_EVENT_ID_LIFECYCLE, mySecretEventLifecycleCallback, None),
+ vc.secretEventRegisterAny(None, libvirt.VIR_SECRET_EVENT_ID_VALUE_CHANGED, mySecretEventValueChanged, None),
+ ]
vc.setKeepAlive(5, 3)
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/examples/event-test.py b/examples/event-test.py
index 91a7cb7..d2d2c60 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -456,6 +456,31 @@ def virEventLoopNativeStart():
##########################################################################
# Everything that now follows is a simple demo of domain lifecycle events
##########################################################################
+class Description(object):
+ __slots__ = ('desc', 'args')
+
+ def __init__(self, *args, **kwargs):
+ self.desc = kwargs.get('desc')
+ self.args = args
+
+ def __str__(self): # type: () -> str
+ return self.desc
+
+ def __getitem__(self, item): # type: (int) -> str
+ try:
+ data = self.args[item]
+ except IndexError:
+ return self.__class__(desc=str(item))
+
+ if isinstance(data, str):
+ return self.__class__(desc=data)
+ elif isinstance(data, (list, tuple)):
+ desc, args = data
+ return self.__class__(*args, desc=desc)
+
+ raise TypeError(args)
+
+
def domEventToString(event):
domEventStrings = ( "Defined",
"Undefined",
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 42 ++++++++++++++----------------------------
1 file changed, 14 insertions(+), 28 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index d2d2c60..493828f 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -481,32 +481,18 @@ class Description(object):
raise TypeError(args)
-def domEventToString(event):
- domEventStrings = ( "Defined",
- "Undefined",
- "Started",
- "Suspended",
- "Resumed",
- "Stopped",
- "Shutdown",
- "PMSuspended",
- "Crashed",
- )
- return domEventStrings[event]
-
-def domDetailToString(event, detail):
- domEventStrings = (
- ( "Added", "Updated", "Renamed", "Snapshot" ),
- ( "Removed", "Renamed", ),
- ( "Booted", "Migrated", "Restored", "Snapshot", "Wakeup" ),
- ( "Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot", "API error", "Postcopy", "Postcopy failed" ),
- ( "Unpaused", "Migrated", "Snapshot", "Postcopy" ),
- ( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"),
- ( "Finished", "On guest request", "On host request"),
- ( "Memory", "Disk" ),
- ( "Panicked", ),
- )
- return domEventStrings[event][detail]
+DOM_EVENTS = Description(
+ ("Defined", ("Added", "Updated", "Renamed", "Snapshot")),
+ ("Undefined", ("Removed", "Renamed")),
+ ("Started", ("Booted", "Migrated", "Restored", "Snapshot", "Wakeup")),
+ ("Suspended", ("Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot", "API error", "Postcopy", "Postcopy failed")),
+ ("Resumed", ("Unpaused", "Migrated", "Snapshot", "Postcopy")),
+ ("Stopped", ("Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot")),
+ ("Shutdown", ("Finished", "On guest request", "On host request")),
+ ("PMSuspended", ("Memory", "Disk")),
+ ("Crashed", ("Panicked",)),
+)
+
def blockJobTypeToString(type):
blockJobTypes = ( "unknown", "Pull", "Copy", "Commit", "ActiveCommit", )
@@ -526,8 +512,8 @@ def agentLifecycleReasonToString(reason):
def myDomainEventCallback(conn, dom, event, detail, opaque):
- print("myDomainEventCallback%d EVENT: Domain %s(%s) %s %s" % (
- opaque, dom.name(), dom.ID(), domEventToString(event), domDetailToString(event, detail)))
+ print("myDomainEventCallback%s EVENT: Domain %s(%s) %s %s" % (
+ opaque, dom.name(), dom.ID(), DOM_EVENTS[event], DOM_EVENTS[event][detail]))
def myDomainEventRebootCallback(conn, dom, opaque):
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 493828f..46a8db8 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -492,15 +492,8 @@ DOM_EVENTS = Description(
("PMSuspended", ("Memory", "Disk")),
("Crashed", ("Panicked",)),
)
-
-
-def blockJobTypeToString(type):
- blockJobTypes = ( "unknown", "Pull", "Copy", "Commit", "ActiveCommit", )
- return blockJobTypes[type]
-
-def blockJobStatusToString(status):
- blockJobStatus = ( "Completed", "Failed", "Canceled", "Ready", )
- return blockJobStatus[status]
+BLOCK_JOB_TYPES = Description("unknown", "Pull", "Copy", "Commit", "ActiveCommit")
+BLOCK_JOB_STATUS = Description("Completed", "Failed", "Canceled", "Ready")
def agentLifecycleStateToString(state):
agentStates = ( "unknown", "connected", "disconnected", )
@@ -533,8 +526,13 @@ def myDomainEventGraphicsCallback(conn, dom, phase, localAddr, remoteAddr, authS
print("myDomainEventGraphicsCallback: Domain %s(%s) %d %s" % (dom.name(), dom.ID(), phase, authScheme))
def myDomainEventControlErrorCallback(conn, dom, opaque):
print("myDomainEventControlErrorCallback: Domain %s(%s)" % (dom.name(), dom.ID()))
+
+
def myDomainEventBlockJobCallback(conn, dom, disk, type, status, opaque):
- print("myDomainEventBlockJobCallback: Domain %s(%s) %s on disk %s %s" % (dom.name(), dom.ID(), blockJobTypeToString(type), disk, blockJobStatusToString(status)))
+ print("myDomainEventBlockJobCallback: Domain %s(%s) %s on disk %s %s" % (
+ dom.name(), dom.ID(), BLOCK_JOB_TYPES[type], disk, BLOCK_JOB_STATUS[status]))
+
+
def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, reason, opaque):
print("myDomainEventDiskChangeCallback: Domain %s(%s) disk change oldSrcPath: %s newSrcPath: %s devAlias: %s reason: %s" % (
dom.name(), dom.ID(), oldSrcPath, newSrcPath, devAlias, reason))
@@ -555,8 +553,13 @@ def myDomainEventPMSuspendDiskCallback(conn, dom, reason, opaque):
def myDomainEventDeviceRemovedCallback(conn, dom, dev, opaque):
print("myDomainEventDeviceRemovedCallback: Domain %s(%s) device removed: %s" % (
dom.name(), dom.ID(), dev))
+
+
def myDomainEventBlockJob2Callback(conn, dom, disk, type, status, opaque):
- print("myDomainEventBlockJob2Callback: Domain %s(%s) %s on disk %s %s" % (dom.name(), dom.ID(), blockJobTypeToString(type), disk, blockJobStatusToString(status)))
+ print("myDomainEventBlockJob2Callback: Domain %s(%s) %s on disk %s %s" % (
+ dom.name(), dom.ID(), BLOCK_JOB_TYPES[type], disk, BLOCK_JOB_STATUS[status]))
+
+
def myDomainEventTunableCallback(conn, dom, params, opaque):
print("myDomainEventTunableCallback: Domain %s(%s) %s" % (dom.name(), dom.ID(), params))
def myDomainEventAgentLifecycleCallback(conn, dom, state, reason, opaque):
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 46a8db8..004a263 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -494,6 +494,7 @@ DOM_EVENTS = Description(
)
BLOCK_JOB_TYPES = Description("unknown", "Pull", "Copy", "Commit", "ActiveCommit")
BLOCK_JOB_STATUS = Description("Completed", "Failed", "Canceled", "Ready")
+WATCHDOG_ACTIONS = Description("none", "Pause", "Reset", "Poweroff", "Shutdown", "Debug", "Inject NMI")
def agentLifecycleStateToString(state):
agentStates = ( "unknown", "connected", "disconnected", )
@@ -515,8 +516,11 @@ def myDomainEventRebootCallback(conn, dom, opaque):
def myDomainEventRTCChangeCallback(conn, dom, utcoffset, opaque):
print("myDomainEventRTCChangeCallback: Domain %s(%s) %d" % (dom.name(), dom.ID(), utcoffset))
+
def myDomainEventWatchdogCallback(conn, dom, action, opaque):
- print("myDomainEventWatchdogCallback: Domain %s(%s) %d" % (dom.name(), dom.ID(), action))
+ print("myDomainEventWatchdogCallback: Domain %s(%s) %s" % (
+ dom.name(), dom.ID(), WATCHDOG_ACTIONS[action]))
+
def myDomainEventIOErrorCallback(conn, dom, srcpath, devalias, action, opaque):
print("myDomainEventIOErrorCallback: Domain %s(%s) %s %s %d" % (dom.name(), dom.ID(), srcpath, devalias, action))
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 004a263..4a801b7 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -495,6 +495,7 @@ DOM_EVENTS = Description(
BLOCK_JOB_TYPES = Description("unknown", "Pull", "Copy", "Commit", "ActiveCommit")
BLOCK_JOB_STATUS = Description("Completed", "Failed", "Canceled", "Ready")
WATCHDOG_ACTIONS = Description("none", "Pause", "Reset", "Poweroff", "Shutdown", "Debug", "Inject NMI")
+ERROR_EVENTS = Description("None", "Pause", "Report")
def agentLifecycleStateToString(state):
agentStates = ( "unknown", "connected", "disconnected", )
@@ -524,8 +525,13 @@ def myDomainEventWatchdogCallback(conn, dom, action, opaque):
def myDomainEventIOErrorCallback(conn, dom, srcpath, devalias, action, opaque):
print("myDomainEventIOErrorCallback: Domain %s(%s) %s %s %d" % (dom.name(), dom.ID(), srcpath, devalias, action))
+
+
def myDomainEventIOErrorReasonCallback(conn, dom, srcpath, devalias, action, reason, opaque):
- print("myDomainEventIOErrorReasonCallback: Domain %s(%s) %s %s %d %s" % (dom.name(), dom.ID(), srcpath, devalias, action, reason))
+ print("myDomainEventIOErrorReasonCallback: Domain %s(%s) %s %s %d %s" % (
+ dom.name(), dom.ID(), srcpath, devalias, action, ERROR_EVENTS[reason]))
+
+
def myDomainEventGraphicsCallback(conn, dom, phase, localAddr, remoteAddr, authScheme, subject, opaque):
print("myDomainEventGraphicsCallback: Domain %s(%s) %d %s" % (dom.name(), dom.ID(), phase, authScheme))
def myDomainEventControlErrorCallback(conn, dom, opaque):
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 4a801b7..b559ede 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -496,14 +496,8 @@ BLOCK_JOB_TYPES = Description("unknown", "Pull", "Copy", "Commit", "ActiveCommit
BLOCK_JOB_STATUS = Description("Completed", "Failed", "Canceled", "Ready")
WATCHDOG_ACTIONS = Description("none", "Pause", "Reset", "Poweroff", "Shutdown", "Debug", "Inject NMI")
ERROR_EVENTS = Description("None", "Pause", "Report")
-
-def agentLifecycleStateToString(state):
- agentStates = ( "unknown", "connected", "disconnected", )
- return agentStates[state]
-
-def agentLifecycleReasonToString(reason):
- agentReasons = ( "unknown", "domain started", "channel event", )
- return agentReasons[reason]
+AGENT_STATES = Description("unknown", "connected", "disconnected")
+AGENT_REASONS = Description("unknown", "domain started", "channel event")
def myDomainEventCallback(conn, dom, event, detail, opaque):
@@ -572,8 +566,13 @@ def myDomainEventBlockJob2Callback(conn, dom, disk, type, status, opaque):
def myDomainEventTunableCallback(conn, dom, params, opaque):
print("myDomainEventTunableCallback: Domain %s(%s) %s" % (dom.name(), dom.ID(), params))
+
+
def myDomainEventAgentLifecycleCallback(conn, dom, state, reason, opaque):
- print("myDomainEventAgentLifecycleCallback: Domain %s(%s) %s %s" % (dom.name(), dom.ID(), agentLifecycleStateToString(state), agentLifecycleReasonToString(reason)))
+ print("myDomainEventAgentLifecycleCallback: Domain %s(%s) %s %s" % (
+ dom.name(), dom.ID(), AGENT_STATES[state], AGENT_REASONS[reason]))
+
+
def myDomainEventDeviceAddedCallback(conn, dom, dev, opaque):
print("myDomainEventDeviceAddedCallback: Domain %s(%s) device added: %s" % (
dom.name(), dom.ID(), dev))
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index b559ede..d8ba8c9 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -498,6 +498,7 @@ WATCHDOG_ACTIONS = Description("none", "Pause", "Reset", "Poweroff", "Shutdown",
ERROR_EVENTS = Description("None", "Pause", "Report")
AGENT_STATES = Description("unknown", "connected", "disconnected")
AGENT_REASONS = Description("unknown", "domain started", "channel event")
+GRAPHICS_PHASES = Description("Connect", "Initialize", "Disconnect")
def myDomainEventCallback(conn, dom, event, detail, opaque):
@@ -527,7 +528,10 @@ def myDomainEventIOErrorReasonCallback(conn, dom, srcpath, devalias, action, rea
def myDomainEventGraphicsCallback(conn, dom, phase, localAddr, remoteAddr, authScheme, subject, opaque):
- print("myDomainEventGraphicsCallback: Domain %s(%s) %d %s" % (dom.name(), dom.ID(), phase, authScheme))
+ print("myDomainEventGraphicsCallback: Domain %s(%s) %s %s" % (
+ dom.name(), dom.ID(), GRAPHICS_PHASES[phase], authScheme))
+
+
def myDomainEventControlErrorCallback(conn, dom, opaque):
print("myDomainEventControlErrorCallback: Domain %s(%s)" % (dom.name(), dom.ID()))
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index d8ba8c9..218103d 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -499,6 +499,7 @@ ERROR_EVENTS = Description("None", "Pause", "Report")
AGENT_STATES = Description("unknown", "connected", "disconnected")
AGENT_REASONS = Description("unknown", "domain started", "channel event")
GRAPHICS_PHASES = Description("Connect", "Initialize", "Disconnect")
+DISK_EVENTS = Description("Change missing on start", "Drop missing on start")
def myDomainEventCallback(conn, dom, event, detail, opaque):
@@ -543,7 +544,9 @@ def myDomainEventBlockJobCallback(conn, dom, disk, type, status, opaque):
def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias, reason, opaque):
print("myDomainEventDiskChangeCallback: Domain %s(%s) disk change oldSrcPath: %s newSrcPath: %s devAlias: %s reason: %s" % (
- dom.name(), dom.ID(), oldSrcPath, newSrcPath, devAlias, reason))
+ dom.name(), dom.ID(), oldSrcPath, newSrcPath, devAlias, DISK_EVENTS[reason]))
+
+
def myDomainEventTrayChangeCallback(conn, dom, devAlias, reason, opaque):
print("myDomainEventTrayChangeCallback: Domain %s(%s) tray change devAlias: %s reason: %s" % (
dom.name(), dom.ID(), devAlias, reason))
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 218103d..5426ecd 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -500,6 +500,7 @@ AGENT_STATES = Description("unknown", "connected", "disconnected")
AGENT_REASONS = Description("unknown", "domain started", "channel event")
GRAPHICS_PHASES = Description("Connect", "Initialize", "Disconnect")
DISK_EVENTS = Description("Change missing on start", "Drop missing on start")
+TRAY_EVENTS = Description("Opened", "Closed")
def myDomainEventCallback(conn, dom, event, detail, opaque):
@@ -549,7 +550,9 @@ def myDomainEventDiskChangeCallback(conn, dom, oldSrcPath, newSrcPath, devAlias,
def myDomainEventTrayChangeCallback(conn, dom, devAlias, reason, opaque):
print("myDomainEventTrayChangeCallback: Domain %s(%s) tray change devAlias: %s reason: %s" % (
- dom.name(), dom.ID(), devAlias, reason))
+ dom.name(), dom.ID(), devAlias, TRAY_EVENTS[reason]))
+
+
def myDomainEventPMWakeupCallback(conn, dom, reason, opaque):
print("myDomainEventPMWakeupCallback: Domain %s(%s) system pmwakeup" % (
dom.name(), dom.ID()))
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 29 ++++++++++-------------------
1 file changed, 10 insertions(+), 19 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 5426ecd..2436827 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -604,27 +604,18 @@ def myDomainEventBlockThresholdCallback(conn, dom, dev, path, threshold, excess,
##########################################################################
# Network events
##########################################################################
-def netEventToString(event):
- netEventStrings = ( "Defined",
- "Undefined",
- "Started",
- "Stopped",
- )
- return netEventStrings[event]
-
-def netDetailToString(event, detail):
- netEventStrings = (
- ( "Added", ),
- ( "Removed", ),
- ( "Started", ),
- ( "Stopped", ),
- )
- return netEventStrings[event][detail]
+NET_EVENTS = Description(
+ ("Defined", ("Added",)),
+ ("Undefined", ("Removed",)),
+ ("Started", ("Started",)),
+ ("Stopped", ("Stopped",)),
+)
+
def myNetworkEventLifecycleCallback(conn, net, event, detail, opaque):
- print("myNetworkEventLifecycleCallback: Network %s %s %s" % (net.name(),
- netEventToString(event),
- netDetailToString(event, detail)))
+ print("myNetworkEventLifecycleCallback: Network %s %s %s" % (
+ net.name(), NET_EVENTS[event], NET_EVENTS[event][detail]))
+
##########################################################################
# Storage pool events
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 2436827..499f434 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -620,20 +620,20 @@ def myNetworkEventLifecycleCallback(conn, net, event, detail, opaque):
##########################################################################
# Storage pool events
##########################################################################
-def storageEventToString(event):
- storageEventStrings = ( "Defined",
- "Undefined",
- "Started",
- "Stopped",
- "Created",
- "Deleted",
- )
- return storageEventStrings[event]
+STORAGE_EVENTS = Description(
+ ("Defined", ()),
+ ("Undefined", ()),
+ ("Started", ()),
+ ("Stopped", ()),
+ ("Created", ()),
+ ("Deleted", ()),
+)
+
def myStoragePoolEventLifecycleCallback(conn, pool, event, detail, opaque):
- print("myStoragePoolEventLifecycleCallback: Storage pool %s %s %d" % (pool.name(),
- storageEventToString(event),
- detail))
+ print("myStoragePoolEventLifecycleCallback: Storage pool %s %s %s" % (
+ pool.name(), STORAGE_EVENTS[event], STORAGE_EVENTS[event][detail]))
+
def myStoragePoolEventRefreshCallback(conn, pool, opaque):
print("myStoragePoolEventRefreshCallback: Storage pool %s" % pool.name())
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 499f434..0a1d06d 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -641,16 +641,16 @@ def myStoragePoolEventRefreshCallback(conn, pool, opaque):
##########################################################################
# Node device events
##########################################################################
-def nodeDeviceEventToString(event):
- nodeDeviceEventStrings = ( "Created",
- "Deleted",
- )
- return nodeDeviceEventStrings[event]
+DEVICE_EVENTS = Description(
+ ("Created", ()),
+ ("Deleted", ()),
+)
+
def myNodeDeviceEventLifecycleCallback(conn, dev, event, detail, opaque):
- print("myNodeDeviceEventLifecycleCallback: Node device %s %s %d" % (dev.name(),
- nodeDeviceEventToString(event),
- detail))
+ print("myNodeDeviceEventLifecycleCallback: Node device %s %s %s" % (
+ dev.name(), DEVICE_EVENTS[event], DEVICE_EVENTS[event][detail]))
+
def myNodeDeviceEventUpdateCallback(conn, dev, opaque):
print("myNodeDeviceEventUpdateCallback: Node device %s" % dev.name())
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 0a1d06d..5e3b884 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -658,16 +658,16 @@ def myNodeDeviceEventUpdateCallback(conn, dev, opaque):
##########################################################################
# Secret events
##########################################################################
-def secretEventToString(event):
- secretEventStrings = ( "Defined",
- "Undefined",
- )
- return secretEventStrings[event]
+SECRET_EVENTS = Description(
+ ("Defined", ()),
+ ("Undefined", ()),
+)
+
def mySecretEventLifecycleCallback(conn, secret, event, detail, opaque):
- print("mySecretEventLifecycleCallback: Secret %s %s %d" % (secret.UUIDString(),
- secretEventToString(event),
- detail))
+ print("mySecretEventLifecycleCallback: Secret %s %s %s" % (
+ secret.UUIDString(), SECRET_EVENTS[event], SECRET_EVENTS[event][detail]))
+
def mySecretEventValueChanged(conn, secret, opaque):
print("mySecretEventValueChanged: Secret %s" % secret.UUIDString())
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
to use new Description class
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 5e3b884..1e94838 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -677,15 +677,16 @@ def mySecretEventValueChanged(conn, secret, opaque):
##########################################################################
run = True
+CONNECTION_EVENTS = Description("Error", "End-of-file", "Keepalive", "Client")
+
def myConnectionCloseCallback(conn, reason, opaque):
- reasonStrings = (
- "Error", "End-of-file", "Keepalive", "Client",
- )
- print("myConnectionCloseCallback: %s: %s" % (conn.getURI(), reasonStrings[reason]))
+ print("myConnectionCloseCallback: %s: %s" % (
+ conn.getURI(), CONNECTION_EVENTS[reason]))
global run
run = False
+
def usage():
print("usage: %s [-hdl] [uri]" % (os.path.basename(__file__),))
print(" uri will default to qemu:///system")
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Closer to pep8
Signed-off-by: Philipp Hahn <hahn@univention.de>
---
examples/event-test.py | 97 ++++++++++++++++++++++++++++++++++++--------------
1 file changed, 71 insertions(+), 26 deletions(-)
diff --git a/examples/event-test.py b/examples/event-test.py
index 1e94838..540bf9b 100755
--- a/examples/event-test.py
+++ b/examples/event-test.py
@@ -30,11 +30,14 @@ import threading
event_impl = "poll"
do_debug = False
+
+
def debug(msg):
global do_debug
if do_debug:
print(msg)
+
#
# This general purpose event loop will support waiting for file handle
# I/O and errors events, as well as scheduling repeatable timers with
@@ -100,7 +103,6 @@ class virEventLoopPoll:
self.cb(self.timer,
self.opaque)
-
def __init__(self):
self.poll = select.poll()
self.pipetrick = os.pipe()
@@ -126,10 +128,9 @@ class virEventLoopPoll:
# with the event loop for input events. When we need to force
# the main thread out of a poll() sleep, we simple write a
# single byte of data to the other end of the pipe.
- debug("Self pipe watch %d write %d" %(self.pipetrick[0], self.pipetrick[1]))
+ debug("Self pipe watch %d write %d" % (self.pipetrick[0], self.pipetrick[1]))
self.poll.register(self.pipetrick[0], select.POLLIN)
-
# Calculate when the next timeout is due to occur, returning
# the absolute timestamp for the next timeout, or 0 if there is
# no timeout due
@@ -159,7 +160,6 @@ class virEventLoopPoll:
return h
return None
-
# This is the heart of the event loop, performing one single
# iteration. It asks when the next timeout is due, and then
# calculates the maximum amount of time it is able to sleep
@@ -235,7 +235,6 @@ class virEventLoopPoll:
finally:
self.runningPoll = False
-
# Actually run the event loop forever
def run_loop(self):
self.quit = False
@@ -247,7 +246,6 @@ class virEventLoopPoll:
self.pendingWakeup = True
os.write(self.pipetrick[1], 'c'.encode("UTF-8"))
-
# Registers a new file handle 'fd', monitoring for 'events' (libvirt
# event constants), firing the callback cb() when an event occurs.
# Returns a unique integer identier for this handle, that should be
@@ -301,7 +299,7 @@ class virEventLoopPoll:
h.set_interval(interval)
self.interrupt()
- debug("Update timer %d interval %d" % (timerID, interval))
+ debug("Update timer %d interval %d" % (timerID, interval))
break
# Stop monitoring for events on the file handle
@@ -383,26 +381,32 @@ def virEventAddHandleImpl(fd, events, cb, opaque):
global eventLoop
return eventLoop.add_handle(fd, events, cb, opaque)
+
def virEventUpdateHandleImpl(handleID, events):
global eventLoop
return eventLoop.update_handle(handleID, events)
+
def virEventRemoveHandleImpl(handleID):
global eventLoop
return eventLoop.remove_handle(handleID)
+
def virEventAddTimerImpl(interval, cb, opaque):
global eventLoop
return eventLoop.add_timer(interval, cb, opaque)
+
def virEventUpdateTimerImpl(timerID, interval):
global eventLoop
return eventLoop.update_timer(timerID, interval)
+
def virEventRemoveTimerImpl(timerID):
global eventLoop
return eventLoop.remove_timer(timerID)
+
# This tells libvirt what event loop implementation it
# should use
def virEventLoopPollRegister():
@@ -413,20 +417,24 @@ def virEventLoopPollRegister():
virEventUpdateTimerImpl,
virEventRemoveTimerImpl)
+
# Directly run the event loop in the current thread
def virEventLoopPollRun():
global eventLoop
eventLoop.run_loop()
+
def virEventLoopAIORun(loop):
import asyncio
asyncio.set_event_loop(loop)
loop.run_forever()
+
def virEventLoopNativeRun():
while True:
libvirt.virEventRunDefaultImpl()
+
# Spawn a background thread to run the event loop
def virEventLoopPollStart():
global eventLoopThread
@@ -435,6 +443,7 @@ def virEventLoopPollStart():
eventLoopThread.setDaemon(True)
eventLoopThread.start()
+
def virEventLoopAIOStart():
global eventLoopThread
import libvirtaio
@@ -445,6 +454,7 @@ def virEventLoopAIOStart():
eventLoopThread.setDaemon(True)
eventLoopThread.start()
+
def virEventLoopNativeStart():
global eventLoopThread
libvirt.virEventRegisterDefaultImpl()
@@ -509,10 +519,13 @@ def myDomainEventCallback(conn, dom, event, detail, opaque):
def myDomainEventRebootCallback(conn, dom, opaque):
- print("myDomainEventRebootCallback: Domain %s(%s)" % (dom.name(), dom.ID()))
+ print("myDomainEventRebootCallback: Domain %s(%s)" % (
+ dom.name(), dom.ID()))
+
def myDomainEventRTCChangeCallback(conn, dom, utcoffset, opaque):
- print("myDomainEventRTCChangeCallback: Domain %s(%s) %d" % (dom.name(), dom.ID(), utcoffset))
+ print("myDomainEventRTCChangeCallback: Domain %s(%s) %d" % (
+ dom.name(), dom.ID(), utcoffset))
def myDomainEventWatchdogCallback(conn, dom, action, opaque):
@@ -521,7 +534,8 @@ def myDomainEventWatchdogCallback(conn, dom, action, opaque):
def myDomainEventIOErrorCallback(conn, dom, srcpath, devalias, action, opaque):
- print("myDomainEventIOErrorCallback: Domain %s(%s) %s %s %d" % (dom.name(), dom.ID(), srcpath, devalias, action))
+ print("myDomainEventIOErrorCallback: Domain %s(%s) %s %s %d" % (
+ dom.name(), dom.ID(), srcpath, devalias, action))
def myDomainEventIOErrorReasonCallback(conn, dom, srcpath, devalias, action, reason, opaque):
@@ -535,7 +549,8 @@ def myDomainEventGraphicsCallback(conn, dom, phase, localAddr, remoteAddr, authS
def myDomainEventControlErrorCallback(conn, dom, opaque):
- print("myDomainEventControlErrorCallback: Domain %s(%s)" % (dom.name(), dom.ID()))
+ print("myDomainEventControlErrorCallback: Domain %s(%s)" % (
+ dom.name(), dom.ID()))
def myDomainEventBlockJobCallback(conn, dom, disk, type, status, opaque):
@@ -555,18 +570,27 @@ def myDomainEventTrayChangeCallback(conn, dom, devAlias, reason, opaque):
def myDomainEventPMWakeupCallback(conn, dom, reason, opaque):
print("myDomainEventPMWakeupCallback: Domain %s(%s) system pmwakeup" % (
- dom.name(), dom.ID()))
+ dom.name(), dom.ID()))
+
+
def myDomainEventPMSuspendCallback(conn, dom, reason, opaque):
print("myDomainEventPMSuspendCallback: Domain %s(%s) system pmsuspend" % (
- dom.name(), dom.ID()))
+ dom.name(), dom.ID()))
+
+
def myDomainEventBalloonChangeCallback(conn, dom, actual, opaque):
- print("myDomainEventBalloonChangeCallback: Domain %s(%s) %d" % (dom.name(), dom.ID(), actual))
+ print("myDomainEventBalloonChangeCallback: Domain %s(%s) %d" % (
+ dom.name(), dom.ID(), actual))
+
+
def myDomainEventPMSuspendDiskCallback(conn, dom, reason, opaque):
print("myDomainEventPMSuspendDiskCallback: Domain %s(%s) system pmsuspend_disk" % (
- dom.name(), dom.ID()))
+ dom.name(), dom.ID()))
+
+
def myDomainEventDeviceRemovedCallback(conn, dom, dev, opaque):
print("myDomainEventDeviceRemovedCallback: Domain %s(%s) device removed: %s" % (
- dom.name(), dom.ID(), dev))
+ dom.name(), dom.ID(), dev))
def myDomainEventBlockJob2Callback(conn, dom, disk, type, status, opaque):
@@ -575,7 +599,8 @@ def myDomainEventBlockJob2Callback(conn, dom, disk, type, status, opaque):
def myDomainEventTunableCallback(conn, dom, params, opaque):
- print("myDomainEventTunableCallback: Domain %s(%s) %s" % (dom.name(), dom.ID(), params))
+ print("myDomainEventTunableCallback: Domain %s(%s) %s" % (
+ dom.name(), dom.ID(), params))
def myDomainEventAgentLifecycleCallback(conn, dom, state, reason, opaque):
@@ -585,21 +610,33 @@ def myDomainEventAgentLifecycleCallback(conn, dom, state, reason, opaque):
def myDomainEventDeviceAddedCallback(conn, dom, dev, opaque):
print("myDomainEventDeviceAddedCallback: Domain %s(%s) device added: %s" % (
- dom.name(), dom.ID(), dev))
+ dom.name(), dom.ID(), dev))
+
+
def myDomainEventMigrationIteration(conn, dom, iteration, opaque):
print("myDomainEventMigrationIteration: Domain %s(%s) started migration iteration %d" % (
- dom.name(), dom.ID(), iteration))
+ dom.name(), dom.ID(), iteration))
+
+
def myDomainEventJobCompletedCallback(conn, dom, params, opaque):
- print("myDomainEventJobCompletedCallback: Domain %s(%s) %s" % (dom.name(), dom.ID(), params))
+ print("myDomainEventJobCompletedCallback: Domain %s(%s) %s" % (
+ dom.name(), dom.ID(), params))
+
+
def myDomainEventDeviceRemovalFailedCallback(conn, dom, dev, opaque):
print("myDomainEventDeviceRemovalFailedCallback: Domain %s(%s) failed to remove device: %s" % (
- dom.name(), dom.ID(), dev))
+ dom.name(), dom.ID(), dev))
+
+
def myDomainEventMetadataChangeCallback(conn, dom, mtype, nsuri, opaque):
print("myDomainEventMetadataChangeCallback: Domain %s(%s) changed metadata mtype=%d nsuri=%s" % (
- dom.name(), dom.ID(), mtype, nsuri))
+ dom.name(), dom.ID(), mtype, nsuri))
+
+
def myDomainEventBlockThresholdCallback(conn, dom, dev, path, threshold, excess, opaque):
print("myDomainEventBlockThresholdCallback: Domain %s(%s) block device %s(%s) threshold %d exceeded by %d" % (
- dom.name(), dom.ID(), dev, path, threshold, excess))
+ dom.name(), dom.ID(), dev, path, threshold, excess))
+
##########################################################################
# Network events
@@ -638,6 +675,7 @@ def myStoragePoolEventLifecycleCallback(conn, pool, event, detail, opaque):
def myStoragePoolEventRefreshCallback(conn, pool, opaque):
print("myStoragePoolEventRefreshCallback: Storage pool %s" % pool.name())
+
##########################################################################
# Node device events
##########################################################################
@@ -655,6 +693,7 @@ def myNodeDeviceEventLifecycleCallback(conn, dev, event, detail, opaque):
def myNodeDeviceEventUpdateCallback(conn, dev, opaque):
print("myNodeDeviceEventUpdateCallback: Node device %s" % dev.name())
+
##########################################################################
# Secret events
##########################################################################
@@ -672,6 +711,7 @@ def mySecretEventLifecycleCallback(conn, secret, event, detail, opaque):
def mySecretEventValueChanged(conn, secret, opaque):
print("mySecretEventValueChanged: Secret %s" % secret.UUIDString())
+
##########################################################################
# Set up and run the program
##########################################################################
@@ -695,12 +735,13 @@ def usage():
print(" --loop=TYPE, -l Choose event-loop-implementation (native, poll, asyncio)")
print(" --timeout=SECS Quit after SECS seconds running")
+
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "hdl:", ["help", "debug", "loop=", "timeout="])
except getopt.GetoptError as err:
# print help information and exit:
- print(str(err)) # will print something like "option -a not recognized"
+ print(str(err)) # will print something like "option -a not recognized"
usage()
sys.exit(2)
timeout = None
@@ -736,16 +777,19 @@ def main():
# Close connection on exit (to test cleanup paths)
old_exitfunc = getattr(sys, 'exitfunc', None)
+
def exit():
print("Closing " + vc.getURI())
if run:
vc.close()
- if (old_exitfunc): old_exitfunc()
+ if (old_exitfunc):
+ old_exitfunc()
+
sys.exitfunc = exit
vc.registerCloseCallback(myConnectionCloseCallback, None)
- #Add 2 lifecycle callbacks to prove this works with more than just one
+ # Add 2 lifecycle callbacks to prove this works with more than just one
vc.domainEventRegister(myDomainEventCallback, 1)
domcallbacks = [
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback, 2),
@@ -829,5 +873,6 @@ def main():
# Allow delayed event loop cleanup to run, just for sake of testing
time.sleep(2)
+
if __name__ == "__main__":
main()
--
2.11.0
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Hello, Am 20.09.18 um 08:10 schrieb Philipp Hahn: > event-test.py is bad at handling newer livecycle events. > Attached are two patches to improve that. > > Philipp Hahn (2): > event-test.py: Sync list of domain lifecycle events > event-test.py: Future proof lifecycle event handling > > examples/event-test.py | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) While looking at the events reported by said script I noticed that there are no events for creating / deleting snapshot, at leat when the VM is inactive. For an active VM Qemu reports several events: VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT Also there is no event generated when doing "virsh change-media" for an inactive domain; I would have expected an VIR_DOMAIN_EVENT_DEFINED_UPDATED event. For an active domain you get the libvirt.VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN / CLOSE events. My current work-around is to do polling, but I want to get rid of that. Did I miss something or is it okay to add events for tha? Thanks in advance. Philipp -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Fri, Sep 21, 2018 at 08:39:20 +0200, Philipp Hahn wrote: > Hello, > > Am 20.09.18 um 08:10 schrieb Philipp Hahn: > > event-test.py is bad at handling newer livecycle events. > > Attached are two patches to improve that. > > > > Philipp Hahn (2): > > event-test.py: Sync list of domain lifecycle events > > event-test.py: Future proof lifecycle event handling > > > > examples/event-test.py | 18 ++++++++++++------ > > 1 file changed, 12 insertions(+), 6 deletions(-) > > While looking at the events reported by said script I noticed that there > are no events for creating / deleting snapshot, at leat when the VM is > inactive. For an active VM Qemu reports several events: > VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT > VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT > VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT > VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT > VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT > > Also there is no event generated when doing "virsh change-media" for an > inactive domain; I would have expected an > VIR_DOMAIN_EVENT_DEFINED_UPDATED event. > For an active domain you get the > libvirt.VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN / CLOSE events. > > My current work-around is to do polling, but I want to get rid of that. > Did I miss something or is it okay to add events for tha? The UPDATED event would make sense for both online/offline VMs, but it wasn't implemented there yet. Tray change events for offline VMs obviously don't make sense. Also for offline VMs the media change always succeeded if the API was successful. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2024 Red Hat, Inc.