The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/4349

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Resolves #4322

Signed-off-by: Thomas Hipp <[email protected]>
From 6c21fa2b8c3142a06ec3bd157d5aeffeb76a1f25 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <[email protected]>
Date: Thu, 22 Mar 2018 12:18:59 +0100
Subject: [PATCH] *: Add lifecycle events to events API

Resolves #4322

Signed-off-by: Thomas Hipp <[email protected]>
---
 doc/api-extensions.md |  3 +++
 doc/rest-api.md       |  3 ++-
 lxc/monitor.go        |  3 +++
 lxd/container.go      |  6 ++++++
 lxd/container_lxc.go  | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 lxd/events.go         | 11 ++++++++++-
 shared/api/event.go   |  7 +++++++
 shared/version/api.go |  1 +
 8 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 04c8b9219..a8573d0a7 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -443,3 +443,6 @@ The following existing endpoints have been modified:
  * `DELETE /1.0/storage-pool/<pool>/volumes/<type>/<name>` accepts a new 
target query parameter
  * `POST /1.0/networks` accepts a new target query parameter
  * `GET /1.0/networks/<name>` accepts a new target query parameter
+
+## lifecycle
+This adds a new `lifecycle` message type to the events API.
diff --git a/doc/rest-api.md b/doc/rest-api.md
index 97cc5146f..6f5e541ed 100644
--- a/doc/rest-api.md
+++ b/doc/rest-api.md
@@ -1392,6 +1392,7 @@ The notification types are:
 
  * operation (notification about creation, updates and termination of all 
background operations)
  * logging (every log entry from the server)
+ * lifecycle (container lifecycle events)
 
 This never returns. Each notification is sent as a separate JSON dict:
 
@@ -1628,7 +1629,7 @@ GET the image as a guest, passing the secret token.
  * Authentication: trusted
  * Operation: async
  * Return: Background operation or standard error
- 
+
 This creates an operation to refresh the specified image from its origin.
 
 ## `/1.0/images/<fingerprint>/secret`
diff --git a/lxc/monitor.go b/lxc/monitor.go
index 318b42a92..c3996d84d 100644
--- a/lxc/monitor.go
+++ b/lxc/monitor.go
@@ -61,6 +61,9 @@ lxc monitor --type=logging
 
 lxc monitor --pretty --type=logging --loglevel=info
     Show a pretty log of messages with info level or higher.
+
+lxc monitor --type=lifecycle
+       Only show lifecycle events.
 `)
 }
 
diff --git a/lxd/container.go b/lxd/container.go
index d1890e1a2..9af69ed1c 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -795,6 +795,12 @@ func containerCreateAsSnapshot(s *state.State, args 
db.ContainerArgs, sourceCont
                os.RemoveAll(sourceContainer.StatePath())
        }
 
+       SendLifecycleEvent("container-snapshot-created",
+               fmt.Sprintf("/1.0/containers/%s", sourceContainer.Name()),
+               map[string]interface{}{
+                       "snapshot_name": args.Name,
+               })
+
        return c, nil
 }
 
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 2b850da3e..b244ccc72 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -439,6 +439,8 @@ func containerLXCCreate(s *state.State, args 
db.ContainerArgs) (container, error
        networkUpdateStatic(s, "")
 
        logger.Info("Created container", ctxMap)
+       SendLifecycleEvent("container-created",
+               fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
 
        return c, nil
 }
@@ -2386,6 +2388,8 @@ func (c *containerLXC) Start(stateful bool) error {
        c.restartProxyDevices()
 
        logger.Info("Started container", ctxMap)
+       SendLifecycleEvent("container-started",
+               fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
 
        return nil
 }
@@ -2550,6 +2554,8 @@ func (c *containerLXC) Stop(stateful bool) error {
 
                op.Done(nil)
                logger.Info("Stopped container", ctxMap)
+               SendLifecycleEvent("container-stopped",
+                       fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
                return nil
        } else if shared.PathExists(c.StatePath()) {
                os.RemoveAll(c.StatePath())
@@ -2595,6 +2601,9 @@ func (c *containerLXC) Stop(stateful bool) error {
        }
 
        logger.Info("Stopped container", ctxMap)
+       SendLifecycleEvent("container-stopped",
+               fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
+
        return nil
 }
 
@@ -2642,6 +2651,8 @@ func (c *containerLXC) Shutdown(timeout time.Duration) 
error {
        }
 
        logger.Info("Shut down container", ctxMap)
+       SendLifecycleEvent("container-shutdown",
+               fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
 
        return nil
 }
@@ -2786,6 +2797,8 @@ func (c *containerLXC) Freeze() error {
        }
 
        logger.Info("Froze container", ctxMap)
+       SendLifecycleEvent("container-paused",
+               fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
 
        return err
 }
@@ -2821,6 +2834,8 @@ func (c *containerLXC) Unfreeze() error {
        }
 
        logger.Info("Unfroze container", ctxMap)
+       SendLifecycleEvent("container-resumed",
+               fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
 
        return err
 }
@@ -3087,6 +3102,9 @@ func (c *containerLXC) Restore(sourceContainer container, 
stateful bool) error {
                return nil
        }
 
+       SendLifecycleEvent("container-snapshot-restored",
+               fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
+
        // Restart the container
        if wasRunning {
                logger.Info("Restored container", ctxMap)
@@ -3206,6 +3224,14 @@ func (c *containerLXC) Delete() error {
 
        logger.Info("Deleted container", ctxMap)
 
+       if c.IsSnapshot() {
+               SendLifecycleEvent("container-snapshot-deleted",
+                       fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
+       } else {
+               SendLifecycleEvent("container-deleted",
+                       fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
+       }
+
        return nil
 }
 
@@ -3326,6 +3352,14 @@ func (c *containerLXC) Rename(newName string) error {
 
        logger.Info("Renamed container", ctxMap)
 
+       if c.IsSnapshot() {
+               SendLifecycleEvent("container-snapshot-renamed",
+                       fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
+       } else {
+               SendLifecycleEvent("container-renamed",
+                       fmt.Sprintf("/1.0/containers/%s", c.name), ctxMap)
+       }
+
        return nil
 }
 
@@ -4565,6 +4599,20 @@ func (c *containerLXC) Update(args db.ContainerArgs, 
userRequested bool) error {
        // Success, update the closure to mark that the changes should be kept.
        undoChanges = false
 
+       SendLifecycleEvent("container-updated",
+               fmt.Sprintf("/1.0/containers/%s", c.name), log.Ctx{"name": 
c.name,
+                       "created":         c.creationDate,
+                       "ephemeral":       c.ephemeral,
+                       "used":            c.lastUsedDate,
+                       "description":     c.description,
+                       "architecture":    c.architecture,
+                       "expandedConfig":  c.expandedConfig,
+                       "expandedDevices": c.expandedDevices,
+                       "localConfig":     c.localConfig,
+                       "localDevices":    c.localDevices,
+                       "profiles":        c.profiles,
+               })
+
        return nil
 }
 
diff --git a/lxd/events.go b/lxd/events.go
index b1f782657..484b36896 100644
--- a/lxd/events.go
+++ b/lxd/events.go
@@ -44,6 +44,15 @@ func (h eventsHandler) Log(r *log.Record) error {
        return nil
 }
 
+func SendLifecycleEvent(action, source string,
+       context map[string]interface{}) error {
+       eventSend("lifecycle", api.EventLifecycle{
+               Action:  action,
+               Source:  source,
+               Context: context})
+       return nil
+}
+
 var eventsLock sync.Mutex
 var eventListeners map[string]*eventListener = make(map[string]*eventListener)
 
@@ -76,7 +85,7 @@ func (r *eventsServe) String() string {
 func eventsSocket(r *http.Request, w http.ResponseWriter) error {
        typeStr := r.FormValue("type")
        if typeStr == "" {
-               typeStr = "logging,operation"
+               typeStr = "logging,operation,lifecycle"
        }
 
        c, err := shared.WebsocketUpgrader.Upgrade(w, r, nil)
diff --git a/shared/api/event.go b/shared/api/event.go
index 8d755a535..f72b5005e 100644
--- a/shared/api/event.go
+++ b/shared/api/event.go
@@ -18,3 +18,10 @@ type EventLogging struct {
        Level   string            `yaml:"level" json:"level"`
        Context map[string]string `yaml:"context" json:"context"`
 }
+
+// EventLifecycle represets a lifecycle type event entry
+type EventLifecycle struct {
+       Action  string                 `yaml:"action" json:"action"`
+       Source  string                 `yaml:"source" json:"source"`
+       Context map[string]interface{} `yaml:"context" json:"context"`
+}
diff --git a/shared/version/api.go b/shared/version/api.go
index 6cc82bbd7..009f166c0 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -99,6 +99,7 @@ var APIExtensions = []string{
        "storage_api_local_volume_handling",
        "operation_description",
        "clustering",
+       "event_lifecycle",
 }
 
 // APIExtensionsCount returns the number of available API extensions.
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to