LXD API - What is the type in /1.0/events

I’m trying to implement the events api in c# in my program. But I’m unsure what can be in metadata (https://github.com/lxc/lxd/blob/master/doc/rest-api.md#10events):

        "timestamp": "2015-06-09T19:07:24.379615253-06:00",                // Current timestamp
        "type": "operation",                                               // Notification type
        "metadata": {}                                                     // Extra resource or type specific metadata

In the comment there is ‘type specific metadata’ mentioned. How can I query the type?

Maybe I don’t need the Event API because I simply want to create and start a container via my c# program. I think I need the event api due to the async instance api.

Thanks for your help.

There are currently 3 types:

For async calls, it’s indeed best to do something like we do in the Go client.
Effectively, connect to /1.0/events ahead of time and have a separate handler loop for it. Then perform your async call and use the notifications from the handler to track the process of the operation to conclusion.

This avoids races and reduces the load on LXD itself.

The alternative would be to hit up /1.0/operations/UUID/wait using the UUID from the async call. This effectively turns things into more of a sync API but results in more queries and can be racy for very short lived operations (though LXD will keep the operation endpoint valid for 5s after it completes to minimize the risk of races).

Thanks I will try to implement it according to the go client. I wasn’t successful only with the documentation :slight_smile: .

Do I have to subscribe to the event socket before I post something to the api? I have the following problem:

  1. subscribe to event api via websocket -> can’t filter on task id
  2. post call to /instance to create an instance
  3. receive task id from post call which I can use to filter the websocket events, but they are already processed

One solution I tried on paper was to filter on the instance name, but that won’t work if more than one client is interacting with the lxd service.

Another solution would be to save the whole event stream and process it after I received the task id from the post call.

You will miss the first operation update event but that’s okay because that’s the same data you’re being returned by the async call.

As soon as you get the operation uuid, use it to track all further updates until the operation hits a final state.

In the Go client that’s what you get when you do something like:

op, err := d.CreateInstance(...)
if err != nil {
    return err

err = op.Wait()
if err != nil {
    return err

In this case, the Go client knows that CreateInstance is async so it will connect to the events API if it hasn’t already. It then parses the operation response and turns it into an operation object which has a Wait() property. Calling Wait() adds a handler to the event listener filtering for that particular operation and will return when it’s reached a final state.

To be fair, this is rather complex logic that’s pretty easy to get wrong.
If you’re looking for a quick first step, ignore the events API, get the UUID from the operation you’re returned back and hit /1.0/operations/UUID/wait to get a blocking call.

It’s slightly racy but unless your server fails to respond within 5s, you should be fine.