The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6018
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) === Ran into this was I was looking into #6014
From f4017a88c3674405dc18e6837fba4e4aaeaa0025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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)) }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel