[lxc-devel] [lxd/master] Prevent deleting or renaming the default profile

monstermunchkin on Github lxc-bot at linuxcontainers.org
Mon Jul 16 16:48:01 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 321 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180716/cce938ad/attachment.bin>
-------------- next part --------------
From 8f09930193ad3ab0f31f79b1b3100be80f44ffee Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 16 Jul 2018 12:51:21 +0200
Subject: [PATCH 1/4] doc: Note that default profile cannot be deleted/renamed

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 doc/profiles.md | 2 ++
 doc/rest-api.md | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/doc/profiles.md b/doc/profiles.md
index 08d1eb9ae..9d08916e6 100644
--- a/doc/profiles.md
+++ b/doc/profiles.md
@@ -10,6 +10,8 @@ the profiles.
 
 If not present, LXD will create a `default` profile.
 
+The `default` profile cannot be renamed or removed.
+
 The `default` profile is set for any new container created which doesn't
 specify a different profiles list.
 
diff --git a/doc/rest-api.md b/doc/rest-api.md
index 3c8d2f98e..54ac383c9 100644
--- a/doc/rest-api.md
+++ b/doc/rest-api.md
@@ -2209,6 +2209,8 @@ the renamed resource.
 
 Renaming to an existing name must return the 409 (Conflict) HTTP code.
 
+Attempting to rename the `default` profile will return the 403 (Forbidden) HTTP code.
+
 ### DELETE
  * Description: remove a profile
  * Authentication: trusted
@@ -2222,6 +2224,8 @@ Input (none at present):
 
 HTTP code for this should be 202 (Accepted).
 
+Attempting to delete the `default` profile will return the 403 (Forbidden) HTTP code.
+
 ## `/1.0/storage-pools`
 ### GET
  * Description: list of storage pools

From de48fec83f715b3158a94a31f5739e2dba1d3cb7 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 16 Jul 2018 16:40:24 +0200
Subject: [PATCH 2/4] doc,shared: Add API extension for permanent default
 profile

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 doc/api-extensions.md | 3 +++
 shared/version/api.go | 1 +
 2 files changed, 4 insertions(+)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 96b8f0b67..e371ce596 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -551,3 +551,6 @@ This adds a new core.debug\_address config option to start a debugging HTTP serv
 
 That server currently includes a pprof API and replaces the old
 cpu-profile, memory-profile and print-goroutines debug options.
+
+## persistent\_default\_profile
+This prevents the `default` profile from being renamed or deleted.
diff --git a/shared/version/api.go b/shared/version/api.go
index 323e6cf5d..9a631c760 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -115,6 +115,7 @@ var APIExtensions = []string{
 	"container_protection_delete",
 	"unix_priv_drop",
 	"pprof_http",
+	"persistent_default_profile",
 }
 
 // APIExtensionsCount returns the number of available API extensions.

From 983d874199980e930d1046715937c352db3f83e2 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 16 Jul 2018 16:40:48 +0200
Subject: [PATCH 3/4] lxd: Prevent renaming/deletion of the default profile

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/profiles.go | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lxd/profiles.go b/lxd/profiles.go
index 5cb6bf963..c0d387817 100644
--- a/lxd/profiles.go
+++ b/lxd/profiles.go
@@ -9,6 +9,7 @@ import (
 	"strings"
 
 	"github.com/gorilla/mux"
+	"github.com/pkg/errors"
 
 	lxd "github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/cluster"
@@ -291,6 +292,10 @@ func profilePatch(d *Daemon, r *http.Request) Response {
 func profilePost(d *Daemon, r *http.Request) Response {
 	name := mux.Vars(r)["name"]
 
+	if name == "default" {
+		return Forbidden(errors.New("The 'default' profile cannot be renamed"))
+	}
+
 	req := api.ProfilePost{}
 	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
 		return BadRequest(err)
@@ -327,6 +332,10 @@ func profilePost(d *Daemon, r *http.Request) Response {
 func profileDelete(d *Daemon, r *http.Request) Response {
 	name := mux.Vars(r)["name"]
 
+	if name == "default" {
+		return Forbidden(errors.New("The 'default' profile cannot be deleted"))
+	}
+
 	_, err := doProfileGet(d.State(), name)
 	if err != nil {
 		return SmartError(err)

From 0e454484afb6577ce09ee4cfcdb66199f65b3153 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 16 Jul 2018 18:46:22 +0200
Subject: [PATCH 4/4] test: Test default profile renaming/deletion

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 test/includes/check.sh | 13 ++++++++++++-
 test/includes/lxd.sh   |  7 +++++++
 test/suites/basic.sh   |  4 ++++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/test/includes/check.sh b/test/includes/check.sh
index cf83b5f0b..015c98c5a 100644
--- a/test/includes/check.sh
+++ b/test/includes/check.sh
@@ -26,9 +26,20 @@ check_empty() {
 }
 
 check_empty_table() {
+    # The profiles table will never be empty since the `default` profile cannot
+    # be deleted.
+    if [ "$2" == 'profiles' ]; then
+        if [ -n "$(sqlite3 "${1}" "SELECT * FROM ${2} WHERE name != 'default';")" ]; then
+          echo "DB table ${2} is not empty, content:"
+          sqlite3 "${1}" "SELECT * FROM ${2} WHERE name != 'default';"
+          return 1
+        fi
+        return 0
+    fi
+
     if [ -n "$(sqlite3 "${1}" "SELECT * FROM ${2};")" ]; then
         echo "DB table ${2} is not empty, content:"
         sqlite3 "${1}" "SELECT * FROM ${2};"
-        false
+        return 1
     fi
 }
diff --git a/test/includes/lxd.sh b/test/includes/lxd.sh
index 826b7f978..3f589cc07 100644
--- a/test/includes/lxd.sh
+++ b/test/includes/lxd.sh
@@ -164,6 +164,13 @@ kill_lxd() {
             lxc profile delete "${profile}" --force-local || true
         done
 
+        # Delete all devices of the default profile since the profile itself
+        # cannot be deleted.
+        echo "==> Deleting all devices of the default profile"
+        for device in $(lxc profile device list default --force-local); do
+            lxc profile device remove default "${device}" --force-local || true
+        done
+
         echo "==> Deleting all storage pools"
         for storage in $(lxc storage list --force-local | tail -n+3 | grep "^| " | cut -d' ' -f2); do
             lxc storage delete "${storage}" --force-local || true
diff --git a/test/suites/basic.sh b/test/suites/basic.sh
index e7822f7dc..8b17846fe 100644
--- a/test/suites/basic.sh
+++ b/test/suites/basic.sh
@@ -477,4 +477,8 @@ test_basic_usage() {
 
   lxc stop foo --force || true
   ! lxc list | grep -q foo || false
+
+  # Test renaming/deletion of the default profile
+  lxc profile rename default foobar 2>&1 | grep -q "Error: The 'default' profile cannot be renamed"
+  lxc profile delete default 2>&1 | grep -q "Error: The 'default' profile cannot be deleted"
 }


More information about the lxc-devel mailing list