Tutorial¶
Basics¶
Using pyxs
is easy! the only class you need to import is
Client
(unless you’re up to some spooky stuff)
– it provides a simple straightforward API to XenStore content with a
bit of Python’s syntactic sugar here and there. Generally, if you just
need to fetch or update some XenStore items you can do:
>>> from pyxs import Client
>>> with Client() as c:
... c["/local/domain/0/name"] = "Domain0"
... c["/local/domain/0/name"]
'Domain0'
Note
Even though Client
does support
dict()
-like lookups, they have nothing else in common
– for instance there’s no Client.get()
currently.
Transactions¶
If you’re already familiar with XenStore features, you probably know that it has basic transaction support. Transactions allow you to operate on a separate, isolated copy of XenStore tree and merge your changes back atomically on commit. Keep in mind, however, that changes made inside a transaction aren’t available to other XenStore clients unless you commit them. Here’s an example:
>>> c = Client()
>>> with c.transaction() as t:
... t["/foo/bar"] = "baz"
... t.transaction_end(commit=True)
...
>>> c["/foo/bar"]
'baz'
The second line inside with
statement is completely optional,
since the default behaviour is to commit everything on context manager
exit. You can also abort the current transaction by calling
transaction_end()
with commit=False
.
Events¶
When a new path is created or an existing path is modified, XenStore
fires an event, notifying all watchers that a change has been made. To
watch a path, you have to call watch()
with a path you want to watch and a token, unique for that path
within the active transaction. After that, incoming events can be
fetched by calling wait()
:
>>> with Client() as c:
... c.watch("/foo/bar", "a unique token")
... c.wait()
Event("/foo/bar", "a unique token")
XenStore also has a notion of special paths, which are reserved for special occasions:
Path Description @introduceDomain Fired when a new domain is introduced to XenStore – you can also introduce domains yourself with a introduce_domain()
call, but in most of the cases,xenstored
will do that for you.@releaseDomain Fired when XenStore is no longer communicating with a domain, see release_domain()
.
Events for both special and ordinary paths are simple two element
tuples, where the first element is always event target – a path
which triggered the event and second is a token, you’ve passed to
watch()
. A nasty consequence of this is that
you can’t get domid of the domain, which triggered
@introduceDomain
or @releaseDomain
from the received event.