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

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) ===
First pass at #6491. I'm planning to change the user-visible bits in a separate branch.
From 97e4e2fc22c7af4660990a71493962b184c738bf Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanay...@canonical.com>
Date: Tue, 26 Nov 2019 17:00:01 +0000
Subject: [PATCH 1/2] Change the profiles_used_by_ref db view to not hard-code
 URLs

Free Ekanayaka <free.ekanay...@canonical.com>
---
 lxd/db/cluster/schema.go |  9 +++++----
 lxd/db/cluster/update.go | 27 +++++++++++++++++++++++++++
 lxd/db/db.go             | 23 +++++++++++++++++++++++
 lxd/db/profiles.go       |  2 +-
 4 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index 33fe82b2e0..27d0cb2fa8 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -389,9 +389,10 @@ CREATE VIEW profiles_used_by_ref (project,
     value) AS
   SELECT projects.name,
     profiles.name,
-    printf('/1.0/containers/%s?project=%s',
-    "instances".name,
-    instances_projects.name)
+    printf('%s/%s/%d',
+    instances_projects.name,
+    instances.name,
+    instances.type)
     FROM profiles
     JOIN projects ON projects.id=profiles.project_id
     JOIN "instances_profiles"
@@ -487,5 +488,5 @@ CREATE TABLE storage_volumes_config (
     FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE 
CASCADE
 );
 
-INSERT INTO schema (version, updated_at) VALUES (18, strftime("%s"))
+INSERT INTO schema (version, updated_at) VALUES (19, strftime("%s"))
 `
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index 461672ad67..ecfc45bf2a 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -53,6 +53,33 @@ var updates = map[int]schema.Update{
        16: updateFromV15,
        17: updateFromV16,
        18: updateFromV17,
+       19: updateFromV18,
+}
+
+// Don't hardcode resource URLs in used-by views.
+func updateFromV18(tx *sql.Tx) error {
+       stmts := `
+DROP VIEW profiles_used_by_ref;
+CREATE VIEW profiles_used_by_ref (project,
+    name,
+    value) AS
+  SELECT projects.name,
+    profiles.name,
+    printf('%s/%s/%d',
+    instances_projects.name,
+    instances.name,
+    instances.type)
+    FROM profiles
+    JOIN projects ON projects.id=profiles.project_id
+    JOIN "instances_profiles"
+      ON "instances_profiles".profile_id=profiles.id
+    JOIN "instances"
+      ON "instances".id="instances_profiles".instance_id
+    JOIN projects AS instances_projects
+      ON instances_projects.id="instances".project_id;
+`
+       _, err := tx.Exec(stmts)
+       return err
 }
 
 // Add nodes_roles table
diff --git a/lxd/db/db.go b/lxd/db/db.go
index c0f5d1f5b5..39b111a258 100644
--- a/lxd/db/db.go
+++ b/lxd/db/db.go
@@ -7,6 +7,7 @@ import (
        "fmt"
        "os"
        "path/filepath"
+       "strings"
        "sync"
        "time"
 
@@ -323,6 +324,28 @@ func ForLocalInspectionWithPreparedStmts(db *sql.DB) 
(*Cluster, error) {
        return c, nil
 }
 
+// UsedByToAPI transforms all entries in the given usedBy slice from the
+// database representation ("<project>|<name>|<type>") to an actual API
+// resource URL. Note that this applies only to containers/instances/vms. Other
+// types of UsedBy strings (such as for images and profiles) are still returned
+// as URLs natively by the underlying VIEW.
+func UsedByToAPI(usedBy []string) []string {
+       usedByURLs := make([]string, len(usedBy))
+       for i, usedBy := range usedBy {
+               if strings.HasPrefix(usedBy, "/1.0/images/") || 
strings.HasPrefix(usedBy, "/1.0/profiles/") {
+                       usedByURLs[i] = usedBy
+                       continue
+               }
+               parts := strings.Split(usedBy, "/")
+               if len(parts) != 3 {
+                       panic(fmt.Sprintf("unexpected UsedBy format: %s", 
usedBy))
+               }
+               project, name, _ := parts[0], parts[1], parts[2]
+               usedByURLs[i] = fmt.Sprintf("/1.0/containers/%s?project=%s", 
name, project)
+       }
+       return usedByURLs
+}
+
 // SetDefaultTimeout sets the default go-dqlite driver timeout.
 func (c *Cluster) SetDefaultTimeout(timeout time.Duration) {
        driver := c.db.Driver().(*driver.Driver)
diff --git a/lxd/db/profiles.go b/lxd/db/profiles.go
index 99083b511f..4e41a903f8 100644
--- a/lxd/db/profiles.go
+++ b/lxd/db/profiles.go
@@ -66,7 +66,7 @@ type Profile struct {
 func ProfileToAPI(profile *Profile) *api.Profile {
        p := &api.Profile{
                Name:   profile.Name,
-               UsedBy: profile.UsedBy,
+               UsedBy: UsedByToAPI(profile.UsedBy),
        }
        p.Description = profile.Description
        p.Config = profile.Config

From ea1af1dd662533a444477fe97418f6eff1fc75a8 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanay...@canonical.com>
Date: Tue, 26 Nov 2019 17:34:00 +0000
Subject: [PATCH 2/2] Change the projects_used_by_ref db view to not hard-code
 URLs for instances

---
 lxd/api_project.go       |  2 ++
 lxd/db/cluster/schema.go |  7 ++++---
 lxd/db/cluster/update.go | 18 ++++++++++++++++++
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/lxd/api_project.go b/lxd/api_project.go
index 27709e412c..1843f8a281 100644
--- a/lxd/api_project.go
+++ b/lxd/api_project.go
@@ -55,6 +55,7 @@ func projectsGet(d *Daemon, r *http.Request) 
response.Response {
                                        continue
                                }
 
+                               project.UsedBy = db.UsedByToAPI(project.UsedBy)
                                filtered = append(filtered, project)
                        }
 
@@ -194,6 +195,7 @@ func projectGet(d *Daemon, r *http.Request) 
response.Response {
        if err != nil {
                return response.SmartError(err)
        }
+       project.UsedBy = db.UsedByToAPI(project.UsedBy)
 
        etag := []interface{}{
                project.Description,
diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index 27d0cb2fa8..13c92eb1af 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -426,9 +426,10 @@ CREATE VIEW projects_config_ref (name,
 CREATE VIEW projects_used_by_ref (name,
     value) AS
   SELECT projects.name,
-    printf('/1.0/containers/%s?project=%s',
-    "instances".name,
-    projects.name)
+    printf('%s/%s/%d',
+    projects.name,
+    instances.name,
+    instances.type)
     FROM "instances" JOIN projects ON project_id=projects.id UNION
   SELECT projects.name,
     printf('/1.0/images/%s',
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index ecfc45bf2a..b92a97e82f 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -77,6 +77,24 @@ CREATE VIEW profiles_used_by_ref (project,
       ON "instances".id="instances_profiles".instance_id
     JOIN projects AS instances_projects
       ON instances_projects.id="instances".project_id;
+DROP VIEW projects_used_by_ref;
+CREATE VIEW projects_used_by_ref (name,
+    value) AS
+  SELECT projects.name,
+    printf('%s/%s/%d',
+    projects.name,
+    instances.name,
+    instances.type)
+    FROM "instances" JOIN projects ON project_id=projects.id UNION
+  SELECT projects.name,
+    printf('/1.0/images/%s',
+    images.fingerprint)
+    FROM images JOIN projects ON project_id=projects.id UNION
+  SELECT projects.name,
+    printf('/1.0/profiles/%s?project=%s',
+    profiles.name,
+    projects.name)
+    FROM profiles JOIN projects ON project_id=projects.id;
 `
        _, err := tx.Exec(stmts)
        return err
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to