[lxc-devel] [lxd/master] Various MAAS related fixes

stgraber on Github lxc-bot at linuxcontainers.org
Sat Jul 27 18:15:54 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 344 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190727/dbdcd999/attachment.bin>
-------------- next part --------------
From f4017a88c3674405dc18e6837fba4e4aaeaa0025 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 14:06:46 -0400
Subject: [PATCH 1/4] lxd/containers: Delete on creation failure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container_lxc.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index d0e78bc3ae..3026818e15 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -514,6 +514,7 @@ func containerLXCCreate(s *state.State, args db.ContainerArgs) (container, error
 
 			err = c.deviceAdd(k, m)
 			if err != nil {
+				c.Delete()
 				return nil, err
 			}
 		}

From 6c46fe9617fad623612abc52110a0c6f218d3426 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 14:07:26 -0400
Subject: [PATCH 2/4] lxd/maas: Do more configuration validation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/maas/controller.go | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/lxd/maas/controller.go b/lxd/maas/controller.go
index 3e9661eff5..ecc5f1d43d 100644
--- a/lxd/maas/controller.go
+++ b/lxd/maas/controller.go
@@ -147,6 +147,22 @@ func (c *Controller) CreateContainer(name string, interfaces []ContainerInterfac
 		return err
 	}
 
+	// Validation
+	if len(interfaces) < 1 {
+		return fmt.Errorf("Empty list of MAAS interface provided")
+	}
+
+	for _, iface := range interfaces {
+		if len(iface.Subnets) != 1 {
+			return fmt.Errorf("Bad subnet provided for interface '%s'", iface.Name)
+		}
+
+		_, ok := subnets[iface.Subnets[0].Name]
+		if !ok {
+			return fmt.Errorf("Subnet '%s' doesn't exist in MAAS", interfaces[0].Subnets[0].Name)
+		}
+	}
+
 	// Create the device and first interface
 	device, err := c.machine.CreateDevice(gomaasapi.CreateMachineDeviceArgs{
 		Hostname:      name,
@@ -244,6 +260,22 @@ func (c *Controller) UpdateContainer(name string, interfaces []ContainerInterfac
 		return err
 	}
 
+	// Validation
+	if len(interfaces) < 1 {
+		return fmt.Errorf("Empty list of MAAS interface provided")
+	}
+
+	for _, iface := range interfaces {
+		if len(iface.Subnets) != 1 {
+			return fmt.Errorf("Bad subnet provided for interface '%s'", iface.Name)
+		}
+
+		_, ok := subnets[iface.Subnets[0].Name]
+		if !ok {
+			return fmt.Errorf("Subnet '%s' doesn't exist in MAAS", interfaces[0].Subnets[0].Name)
+		}
+	}
+
 	// Iterate over existing interfaces, drop all removed ones and update existing ones
 	existingInterfaces := map[string]gomaasapi.Interface{}
 	for _, entry := range device.InterfaceSet() {

From 0013abbcc595872f5d16aec58dd0558e0bbde25e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 14:07:47 -0400
Subject: [PATCH 3/4] lxd/response: Fix SmartError
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Was mis-identifying unknown errors for no error.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/response.go | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lxd/response.go b/lxd/response.go
index b78ab96544..973782a614 100644
--- a/lxd/response.go
+++ b/lxd/response.go
@@ -518,9 +518,11 @@ func PreconditionFailed(err error) Response {
  * SmartError returns the right error message based on err.
  */
 func SmartError(err error) Response {
-	switch errors.Cause(err) {
-	case nil:
+	if err == nil {
 		return EmptySyncResponse
+	}
+
+	switch errors.Cause(err) {
 	case os.ErrNotExist, sql.ErrNoRows, db.ErrNoSuchObject:
 		return NotFound(nil)
 	case os.ErrPermission:

From 1567f00153ee80f7c360dcb0d562f60f215d3be8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 14:08:50 -0400
Subject: [PATCH 4/4] lxd/containers: Rework MAAS calls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fixes:
 - Device remove/add
 - Use project prefix
 - Slow creation of non-MAAS containers

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container_lxc.go | 97 ++++++++++++++++++++++----------------------
 1 file changed, 49 insertions(+), 48 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 3026818e15..33305f7991 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -499,7 +499,7 @@ func containerLXCCreate(s *state.State, args db.ContainerArgs) (container, error
 
 	if !c.IsSnapshot() {
 		// Update MAAS
-		err = c.maasUpdate(false)
+		err = c.maasUpdate(nil)
 		if err != nil {
 			c.Delete()
 			logger.Error("Failed creating container", ctxMap)
@@ -4535,7 +4535,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
 	}
 
 	if !c.IsSnapshot() && updateMAAS {
-		err = c.maasUpdate(true)
+		err = c.maasUpdate(oldExpandedDevices)
 		if err != nil {
 			return err
 		}
@@ -8351,9 +8351,9 @@ func (c *containerLXC) updateProgress(progress string) {
 }
 
 // Internal MAAS handling
-func (c *containerLXC) maasInterfaces() ([]maas.ContainerInterface, error) {
+func (c *containerLXC) maasInterfaces(devices map[string]map[string]string) ([]maas.ContainerInterface, error) {
 	interfaces := []maas.ContainerInterface{}
-	for k, m := range c.expandedDevices {
+	for k, m := range devices {
 		if m["type"] != "nic" {
 			continue
 		}
@@ -8401,21 +8401,8 @@ func (c *containerLXC) maasInterfaces() ([]maas.ContainerInterface, error) {
 	return interfaces, nil
 }
 
-func (c *containerLXC) maasConnected() bool {
-	for _, m := range c.expandedDevices {
-		if m["type"] != "nic" {
-			continue
-		}
-
-		if m["maas.subnet.ipv4"] != "" || m["maas.subnet.ipv6"] != "" {
-			return true
-		}
-	}
-
-	return false
-}
-
-func (c *containerLXC) maasUpdate(force bool) error {
+func (c *containerLXC) maasUpdate(oldDevices map[string]map[string]string) error {
+	// Check if MAAS is configured
 	maasURL, err := cluster.ConfigGetString(c.state.Cluster, "maas.api.url")
 	if err != nil {
 		return err
@@ -8425,39 +8412,43 @@ func (c *containerLXC) maasUpdate(force bool) error {
 		return nil
 	}
 
-	if c.state.MAAS == nil {
-		return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
+	// Check if there's something that uses MAAS
+	interfaces, err := c.maasInterfaces(c.expandedDevices)
+	if err != nil {
+		return err
 	}
 
-	if !c.maasConnected() {
-		if force {
-			exists, err := c.state.MAAS.DefinedContainer(c.name)
-			if err != nil {
-				return err
-			}
-
-			if exists {
-				return c.state.MAAS.DeleteContainer(c.name)
-			}
+	var oldInterfaces []maas.ContainerInterface
+	if oldDevices != nil {
+		oldInterfaces, err = c.maasInterfaces(oldDevices)
+		if err != nil {
+			return err
 		}
+	}
+
+	if len(interfaces) == 0 && len(oldInterfaces) == 0 {
 		return nil
 	}
 
-	interfaces, err := c.maasInterfaces()
-	if err != nil {
-		return err
+	// See if we're connected to MAAS
+	if c.state.MAAS == nil {
+		return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
 	}
 
-	exists, err := c.state.MAAS.DefinedContainer(c.name)
+	exists, err := c.state.MAAS.DefinedContainer(project.Prefix(c.project, c.name))
 	if err != nil {
 		return err
 	}
 
 	if exists {
-		return c.state.MAAS.UpdateContainer(c.name, interfaces)
+		if len(interfaces) == 0 && len(oldInterfaces) > 0 {
+			return c.state.MAAS.DeleteContainer(project.Prefix(c.project, c.name))
+		}
+
+		return c.state.MAAS.UpdateContainer(project.Prefix(c.project, c.name), interfaces)
 	}
 
-	return c.state.MAAS.CreateContainer(c.name, interfaces)
+	return c.state.MAAS.CreateContainer(project.Prefix(c.project, c.name), interfaces)
 }
 
 func (c *containerLXC) maasRename(newName string) error {
@@ -8470,24 +8461,29 @@ func (c *containerLXC) maasRename(newName string) error {
 		return nil
 	}
 
-	if c.state.MAAS == nil {
-		return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
+	interfaces, err := c.maasInterfaces(c.expandedDevices)
+	if err != nil {
+		return err
 	}
 
-	if !c.maasConnected() {
+	if len(interfaces) == 0 {
 		return nil
 	}
 
-	exists, err := c.state.MAAS.DefinedContainer(c.name)
+	if c.state.MAAS == nil {
+		return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
+	}
+
+	exists, err := c.state.MAAS.DefinedContainer(project.Prefix(c.project, c.name))
 	if err != nil {
 		return err
 	}
 
 	if !exists {
-		return c.maasUpdate(false)
+		return c.maasUpdate(nil)
 	}
 
-	return c.state.MAAS.RenameContainer(c.name, newName)
+	return c.state.MAAS.RenameContainer(project.Prefix(c.project, c.name), project.Prefix(c.project, newName))
 }
 
 func (c *containerLXC) maasDelete() error {
@@ -8500,15 +8496,20 @@ func (c *containerLXC) maasDelete() error {
 		return nil
 	}
 
-	if c.state.MAAS == nil {
-		return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
+	interfaces, err := c.maasInterfaces(c.expandedDevices)
+	if err != nil {
+		return err
 	}
 
-	if !c.maasConnected() {
+	if len(interfaces) == 0 {
 		return nil
 	}
 
-	exists, err := c.state.MAAS.DefinedContainer(c.name)
+	if c.state.MAAS == nil {
+		return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
+	}
+
+	exists, err := c.state.MAAS.DefinedContainer(project.Prefix(c.project, c.name))
 	if err != nil {
 		return err
 	}
@@ -8517,5 +8518,5 @@ func (c *containerLXC) maasDelete() error {
 		return nil
 	}
 
-	return c.state.MAAS.DeleteContainer(c.name)
+	return c.state.MAAS.DeleteContainer(project.Prefix(c.project, c.name))
 }


More information about the lxc-devel mailing list