[lxc-devel] [lxd/master] Network: Removes GetNetwork() and adds fixes errored networks from preventing LXD start
tomponline on Github
lxc-bot at linuxcontainers.org
Mon Jul 20 13:55:44 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 745 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200720/e31a1823/attachment.bin>
-------------- next part --------------
From c6da02f90e41f3d1d12c4c11c337b5ab53630547 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:32:33 +0100
Subject: [PATCH 01/16] shared/api/network: Adds network status constants
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
shared/api/network.go | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/shared/api/network.go b/shared/api/network.go
index c7280f59d3..12b126dc33 100644
--- a/shared/api/network.go
+++ b/shared/api/network.go
@@ -27,6 +27,18 @@ type NetworkPut struct {
Description string `json:"description" yaml:"description"`
}
+// NetworkStatusPending network is pending creation on other cluster nodes.
+const NetworkStatusPending = "Pending"
+
+// NetworkStatusCreated network is fully created.
+const NetworkStatusCreated = "Created"
+
+// NetworkStatusErrored network is in error status.
+const NetworkStatusErrored = "Errored"
+
+// NetworkStatusUnknown network is in unknown status.
+const NetworkStatusUnknown = "Unknown"
+
// Network represents a LXD network
type Network struct {
NetworkPut `yaml:",inline"`
From 67d96396b4919b5da796220045f1975f792a99a6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:30:47 +0100
Subject: [PATCH 02/16] lxd/networks: API constant usage in networkDelete
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/networks.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/networks.go b/lxd/networks.go
index 4e114e2b41..7b8b7202cc 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -474,7 +474,7 @@ func networkDelete(d *Daemon, r *http.Request) response.Response {
if err != nil {
return response.SmartError(err)
}
- if dbNetwork.Status == "Pending" {
+ if dbNetwork.Status == api.NetworkStatusPending {
err := d.cluster.DeleteNetwork(name)
if err != nil {
return response.SmartError(err)
From e30110322ef29ae21d7cc37ba641f144bdd548e7 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:27:51 +0100
Subject: [PATCH 03/16] lxd/network/network/load: Adds status
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/network/network_load.go | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lxd/network/network_load.go b/lxd/network/network_load.go
index 132e6933c5..6abb8430d4 100644
--- a/lxd/network/network_load.go
+++ b/lxd/network/network_load.go
@@ -11,7 +11,7 @@ var drivers = map[string]func() Network{
// LoadByName loads the network info from the database by name.
func LoadByName(s *state.State, name string) (Network, error) {
- id, netInfo, err := s.Cluster.GetNetwork(name)
+ id, netInfo, err := s.Cluster.GetNetworkInAnyState(name)
if err != nil {
return nil, err
}
@@ -22,7 +22,7 @@ func LoadByName(s *state.State, name string) (Network, error) {
}
n := driverFunc()
- n.init(s, id, name, netInfo.Type, netInfo.Description, netInfo.Config)
+ n.init(s, id, name, netInfo.Type, netInfo.Description, netInfo.Config, netInfo.Status)
return n, nil
}
@@ -40,7 +40,7 @@ func Validate(name string, netType string, config map[string]string) error {
}
n := driverFunc()
- n.init(nil, 0, name, netType, "", config)
+ n.init(nil, 0, name, netType, "", config, "Unknown")
return n.Validate(config)
}
@@ -52,7 +52,7 @@ func FillConfig(req *api.NetworksPost) error {
}
n := driverFunc()
- n.init(nil, 0, req.Name, req.Type, req.Description, req.Config)
+ n.init(nil, 0, req.Name, req.Type, req.Description, req.Config, "Unknown")
err := n.fillConfig(req)
if err != nil {
From 186f8efb00a9591fdbdc67e87c0f1bb7f0162114 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:27:33 +0100
Subject: [PATCH 04/16] lxd/network/network/interface: Adds status function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/network/network_interface.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lxd/network/network_interface.go b/lxd/network/network_interface.go
index 9c2fd7424b..2691d424f9 100644
--- a/lxd/network/network_interface.go
+++ b/lxd/network/network_interface.go
@@ -9,13 +9,14 @@ import (
// Network represents a LXD network.
type Network interface {
// Load.
- init(state *state.State, id int64, name string, netType string, description string, config map[string]string)
+ init(state *state.State, id int64, name string, netType string, description string, config map[string]string, status string)
fillConfig(*api.NetworksPost) error
// Config.
Validate(config map[string]string) error
Name() string
Type() string
+ Status() string
Config() map[string]string
IsUsed() bool
HasDHCPv4() bool
From 14235e71bcfe8a454b88b45c2d794843b59b639e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:26:57 +0100
Subject: [PATCH 05/16] lxd/network/driver/common: Adds status field and
function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/network/driver_common.go | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/lxd/network/driver_common.go b/lxd/network/driver_common.go
index 7b0c4e3c91..1cff49e438 100644
--- a/lxd/network/driver_common.go
+++ b/lxd/network/driver_common.go
@@ -34,10 +34,11 @@ type common struct {
netType string
description string
config map[string]string
+ status string
}
// init initialise internal variables.
-func (n *common) init(state *state.State, id int64, name string, netType string, description string, config map[string]string) {
+func (n *common) init(state *state.State, id int64, name string, netType string, description string, config map[string]string, status string) {
n.logger = logging.AddContext(logger.Log, log.Ctx{"driver": netType, "network": name})
n.id = id
n.name = name
@@ -45,6 +46,7 @@ func (n *common) init(state *state.State, id int64, name string, netType string,
n.config = config
n.state = state
n.description = description
+ n.status = status
}
// fillConfig fills requested config with any default values, by default this is a no-op.
@@ -101,6 +103,11 @@ func (n *common) Name() string {
return n.name
}
+// Status returns the network status.
+func (n *common) Status() string {
+ return n.status
+}
+
// Type returns the network type.
func (n *common) Type() string {
return n.netType
@@ -292,7 +299,7 @@ func (n *common) rename(newName string) error {
}
// Reinitialise internal name variable and logger context with new name.
- n.init(n.state, n.id, newName, n.netType, n.description, n.config)
+ n.init(n.state, n.id, newName, n.netType, n.description, n.config, n.status)
return nil
}
From b64ec9ad725c241699b8e73ae3f4b0166ffd88b7 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:24:55 +0100
Subject: [PATCH 06/16] lxd/network/driver/bridge: Don't allow starting a
pending network
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/network/driver_bridge.go | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go
index 3a1612029d..b302b3e79f 100644
--- a/lxd/network/driver_bridge.go
+++ b/lxd/network/driver_bridge.go
@@ -347,6 +347,10 @@ func (n *bridge) setup(oldConfig map[string]string) error {
n.logger.Debug("Setting up network")
+ if n.status == api.NetworkStatusPending {
+ return fmt.Errorf("Cannot start pending network")
+ }
+
// Create directory
if !shared.PathExists(shared.VarPath("networks", n.name)) {
err := os.MkdirAll(shared.VarPath("networks", n.name), 0711)
From f61ed2ca4c44513946bcdb71de6595ab34871c91 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:23:42 +0100
Subject: [PATCH 07/16] lxd/device/nic/bridged: Usage of
d.state.Cluster.GetNetworkInAnyState in rebuildDnsmasqEntry
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/nic_bridged.go | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go
index 622deda0ed..43fb8acb1f 100644
--- a/lxd/device/nic_bridged.go
+++ b/lxd/device/nic_bridged.go
@@ -456,8 +456,7 @@ func (d *nicBridged) Remove() error {
return nil
}
-// rebuildDnsmasqEntry rebuilds the dnsmasq host entry if connected to an LXD managed network
-// and reloads dnsmasq.
+// rebuildDnsmasqEntry rebuilds the dnsmasq host entry if connected to an LXD managed network and reloads dnsmasq.
func (d *nicBridged) rebuildDnsmasqEntry() error {
// Rebuild dnsmasq config if a bridged device has changed and parent is a managed network.
if !shared.PathExists(shared.VarPath("networks", d.config["parent"], "dnsmasq.pid")) {
@@ -467,7 +466,7 @@ func (d *nicBridged) rebuildDnsmasqEntry() error {
dnsmasq.ConfigMutex.Lock()
defer dnsmasq.ConfigMutex.Unlock()
- _, dbInfo, err := d.state.Cluster.GetNetwork(d.config["parent"])
+ _, dbInfo, err := d.state.Cluster.GetNetworkInAnyState(d.config["parent"])
if err != nil {
return err
}
From 5fff6355cc39b652c4f69b7d70fdf679182f4ea8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:22:36 +0100
Subject: [PATCH 08/16] lxd/api/cluster: Usage of api.NetworkStatusPending
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/api_cluster.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/api_cluster.go b/lxd/api_cluster.go
index d8cfb0a74c..15e2ed39b2 100644
--- a/lxd/api_cluster.go
+++ b/lxd/api_cluster.go
@@ -761,7 +761,7 @@ func clusterInitMember(d, client lxd.InstanceServer, memberConfig []api.ClusterM
// configs provided by the user.
for _, network := range networks {
// Skip not-managed or pending networks
- if !network.Managed || network.Status == "Pending" {
+ if !network.Managed || network.Status == api.NetworkStatusPending {
continue
}
From 4e78f3859762531a611a76b42c1bdf58a7538538 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:22:07 +0100
Subject: [PATCH 09/16] lxd/db/networks: Usage of api package's NetworkStatus
constants in getNetwork
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/db/networks.go | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index 558c788f9b..1208fa23b4 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -357,13 +357,13 @@ func (c *Cluster) getNetwork(name string, onlyCreated bool) (int64, *api.Network
switch state {
case networkPending:
- network.Status = "Pending"
+ network.Status = api.NetworkStatusPending
case networkCreated:
- network.Status = "Created"
+ network.Status = api.NetworkStatusCreated
case networkErrored:
- network.Status = "Errored"
+ network.Status = api.NetworkStatusErrored
default:
- network.Status = "Unknown"
+ network.Status = api.NetworkStatusUnknown
}
switch netType {
From 08544a246ae9b0e967e7aef3644bfe4a0ed44d9b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:21:54 +0100
Subject: [PATCH 10/16] lxd/db/networks: Removes unused GetNetwork
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/db/networks.go | 7 -------
1 file changed, 7 deletions(-)
diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index 1208fa23b4..8f941f9ee8 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -305,13 +305,6 @@ const (
NetworkTypeBridge NetworkType = iota // Network type bridge.
)
-// GetNetwork returns the network with the given name.
-//
-// The network must be in the created stated, not pending.
-func (c *Cluster) GetNetwork(name string) (int64, *api.Network, error) {
- return c.getNetwork(name, true)
-}
-
// GetNetworkInAnyState returns the network with the given name.
//
// The network can be in any state.
From 2636beef7ed96820b4e8b2d2f049a78d826c5e8e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:21:44 +0100
Subject: [PATCH 11/16] lxd/db/networks: GetNonPendingNetworks comment
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/db/networks.go | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index 8f941f9ee8..a46be7af84 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -257,8 +257,7 @@ func (c *Cluster) GetNetworks() ([]string, error) {
return c.networks("")
}
-// GetNonPendingNetworks returns the names of all networks that are not
-// pending.
+// GetNonPendingNetworks returns the names of all networks that are not pending.
func (c *Cluster) GetNonPendingNetworks() ([]string, error) {
return c.networks("NOT state=?", networkPending)
}
From 5d0e75954926d9ec950717a2c3791702fb231aaa Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:20:54 +0100
Subject: [PATCH 12/16] lxd/db/networks: Allow pending nodes to be added to
errored networks in CreatePendingNetwork
Allows potentially fixing the errored status.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/db/networks.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index a46be7af84..675e0f03b4 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -189,9 +189,9 @@ func (c *ClusterTx) CreatePendingNetwork(node, name string, netType NetworkType,
return err
}
} else {
- // Check that the existing network is in the pending state.
- if network.state != networkPending {
- return fmt.Errorf("network is not in pending state")
+ // Check that the existing network is in the pending state.
+ if network.state != networkPending && network.state != networkErrored {
+ return fmt.Errorf("Network is not in pending or errored state")
}
}
From 964d4da7ca6c56784f46f875beab9ec9d9be2699 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:20:33 +0100
Subject: [PATCH 13/16] lxd/db/networks: CreatePendingNetwork comments and line
spacing
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/db/networks.go | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index 675e0f03b4..5965f60e46 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -147,11 +147,9 @@ WHERE networks.id = ? AND networks.state = ?
return configs, nil
}
-// CreatePendingNetwork creates a new pending network on the node with
-// the given name.
+// CreatePendingNetwork creates a new pending network on the node with the given name.
func (c *ClusterTx) CreatePendingNetwork(node, name string, netType NetworkType, conf map[string]string) error {
- // First check if a network with the given name exists, and, if
- // so, that it's in the pending state.
+ // First check if a network with the given name exists, and, if so, that it's in the pending state.
network := struct {
id int64
state int
@@ -161,27 +159,29 @@ func (c *ClusterTx) CreatePendingNetwork(node, name string, netType NetworkType,
dest := func(i int) []interface{} {
// Sanity check that there is at most one pool with the given name.
if i != 0 {
- errConsistency = fmt.Errorf("more than one network exists with the given name")
+ errConsistency = fmt.Errorf("More than one network exists with the given name")
}
return []interface{}{&network.id, &network.state}
}
+
stmt, err := c.tx.Prepare("SELECT id, state FROM networks WHERE name=?")
if err != nil {
return err
}
defer stmt.Close()
+
err = query.SelectObjects(stmt, dest, name)
if err != nil {
return err
}
+
if errConsistency != nil {
return errConsistency
}
var networkID = network.id
if networkID == 0 {
- // No existing network with the given name was found, let's create
- // one.
+ // No existing network with the given name was found, let's create one.
columns := []string{"name", "type"}
values := []interface{}{name, netType}
networkID, err = query.UpsertObject(c.tx, "networks", columns, values)
@@ -202,8 +202,7 @@ func (c *ClusterTx) CreatePendingNetwork(node, name string, netType NetworkType,
}
// Check that no network entry for this node and network exists yet.
- count, err := query.Count(
- c.tx, "networks_nodes", "network_id=? AND node_id=?", networkID, nodeInfo.ID)
+ count, err := query.Count(c.tx, "networks_nodes", "network_id=? AND node_id=?", networkID, nodeInfo.ID)
if err != nil {
return err
}
@@ -218,6 +217,7 @@ func (c *ClusterTx) CreatePendingNetwork(node, name string, netType NetworkType,
if err != nil {
return err
}
+
err = c.CreateNetworkConfig(networkID, nodeInfo.ID, conf)
if err != nil {
return err
From c36366a87b69a38baa5b77fd10165e4d10e51ff2 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 11:22:36 +0100
Subject: [PATCH 14/16] lxd/networks/utils: Skip network load error in
networkUpdateForkdnsServersTask
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/networks_utils.go | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index 684abdc983..ecda29c599 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -14,6 +14,7 @@ import (
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/logger"
)
func readUint(path string) (uint64, error) {
@@ -77,7 +78,8 @@ func networkUpdateForkdnsServersTask(s *state.State, heartbeatData *cluster.APIH
for _, name := range networks {
n, err := network.LoadByName(s, name)
if err != nil {
- return err
+ logger.Errorf("Failed to load network %q for heartbeat", name)
+ continue
}
if n.Type() == "bridge" && n.Config()["bridge.mode"] == "fan" {
From b89d1dd3046b8f8c8cdef6bf8aa568aa04302e32 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 17 Jul 2020 15:42:16 +0100
Subject: [PATCH 15/16] lxd/device/nic/bridged: Validates network is type
bridge
Now that different NIC types support the "network" key.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/nic_bridged.go | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go
index 43fb8acb1f..9024563756 100644
--- a/lxd/device/nic_bridged.go
+++ b/lxd/device/nic_bridged.go
@@ -82,6 +82,11 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
if err != nil {
return errors.Wrapf(err, "Error loading network config for %q", d.config["network"])
}
+
+ if n.Type() != "bridge" {
+ return fmt.Errorf("Specified network must be of type bridge")
+ }
+
netConfig := n.Config()
if d.config["ipv4.address"] != "" {
@@ -128,6 +133,7 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
d.config["mtu"] = netConfig["bridge.mtu"]
}
+ // Copy certain keys verbatim from the network's settings.
inheritKeys := []string{"maas.subnet.ipv4", "maas.subnet.ipv6"}
for _, inheritKey := range inheritKeys {
if _, found := netConfig[inheritKey]; found {
From 4c9c612389f56840ab3d25eeeb916511b05446be Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 20 Jul 2020 12:23:07 +0100
Subject: [PATCH 16/16] lxc/device/nic/bridged: Only allow using non-Pending
networks
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/nic_bridged.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go
index 9024563756..eed02222de 100644
--- a/lxd/device/nic_bridged.go
+++ b/lxd/device/nic_bridged.go
@@ -28,6 +28,7 @@ import (
"github.com/lxc/lxd/lxd/revert"
"github.com/lxc/lxd/lxd/util"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/api"
log "github.com/lxc/lxd/shared/log15"
"github.com/lxc/lxd/shared/logger"
)
@@ -83,6 +84,10 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
return errors.Wrapf(err, "Error loading network config for %q", d.config["network"])
}
+ if n.Status() == api.NetworkStatusPending {
+ return fmt.Errorf("Specified network is not fully created")
+ }
+
if n.Type() != "bridge" {
return fmt.Errorf("Specified network must be of type bridge")
}
More information about the lxc-devel
mailing list