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

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) ===
Related to https://github.com/lxc/lxd/pull/8205

Includes https://github.com/lxc/lxd/pull/8211
From 891610b075f0851d272056b83d95468033b845fc Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 3 Dec 2020 16:41:50 +0000
Subject: [PATCH 01/10] lxd/cluster/request/clienttype: Moves client type
 constants and helper into own package

To avoid import loops with storage package in the future.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/cluster/request/clienttype.go | 33 +++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 lxd/cluster/request/clienttype.go

diff --git a/lxd/cluster/request/clienttype.go 
b/lxd/cluster/request/clienttype.go
new file mode 100644
index 0000000000..9e7264a229
--- /dev/null
+++ b/lxd/cluster/request/clienttype.go
@@ -0,0 +1,33 @@
+package request
+
+// UserAgentNotifier used to distinguish between a regular client request and 
an internal cluster request when
+// notifying other nodes of a cluster change.
+const UserAgentNotifier = "lxd-cluster-notifier"
+
+// UserAgentJoiner used to distinguish between a regular client request and an 
internal cluster request when
+// joining a node to a cluster.
+const UserAgentJoiner = "lxd-cluster-joiner"
+
+// ClientType indicates which sort of client type is being used.
+type ClientType string
+
+// ClientTypeNotifier cluster notification client.
+const ClientTypeNotifier ClientType = "notifier"
+
+// ClientTypeJoiner cluster joiner client.
+const ClientTypeJoiner ClientType = "joiner"
+
+// ClientTypeNormal normal client.
+const ClientTypeNormal ClientType = "normal"
+
+// UserAgentClientType converts user agent to client type.
+func UserAgentClientType(userAgent string) ClientType {
+       switch userAgent {
+       case UserAgentNotifier:
+               return ClientTypeNotifier
+       case UserAgentJoiner:
+               return ClientTypeJoiner
+       }
+
+       return ClientTypeNormal
+}

From d51ea4d971021fa0cd17fc219a5a2acf2c50348b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 3 Dec 2020 16:43:07 +0000
Subject: [PATCH 02/10] lxd/cluster/connect: Removes client type constants and
 helper

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/cluster/connect.go | 32 --------------------------------
 1 file changed, 32 deletions(-)

diff --git a/lxd/cluster/connect.go b/lxd/cluster/connect.go
index 3667dfe56d..1d6619e8bc 100644
--- a/lxd/cluster/connect.go
+++ b/lxd/cluster/connect.go
@@ -20,38 +20,6 @@ import (
        "github.com/lxc/lxd/shared/version"
 )
 
-// UserAgentNotifier used to distinguish between a regular client request and 
an internal cluster request when
-// notifying other nodes of a cluster change.
-const UserAgentNotifier = "lxd-cluster-notifier"
-
-// UserAgentJoiner used to distinguish between a regular client request and an 
internal cluster request when
-// joining a node to a cluster.
-const UserAgentJoiner = "lxd-cluster-joiner"
-
-// ClientType indicates which sort of client type is being used.
-type ClientType string
-
-// ClientTypeNotifier cluster notification client.
-const ClientTypeNotifier ClientType = "notifier"
-
-// ClientTypeJoiner cluster joiner client.
-const ClientTypeJoiner ClientType = "joiner"
-
-// ClientTypeNormal normal client.
-const ClientTypeNormal ClientType = "normal"
-
-// UserAgentClientType converts user agent to client type.
-func UserAgentClientType(userAgent string) ClientType {
-       switch userAgent {
-       case UserAgentNotifier:
-               return ClientTypeNotifier
-       case UserAgentJoiner:
-               return ClientTypeJoiner
-       }
-
-       return ClientTypeNormal
-}
-
 // Connect is a convenience around lxd.ConnectLXD that configures the client
 // with the correct parameters for node-to-node communication.
 //

From 340d1e4ec170b57a693ee6a2c9fbd6a48669aae5 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 3 Dec 2020 16:43:42 +0000
Subject: [PATCH 03/10] lxd: Updates use of ClientType now moved to
 cluster/request package

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/api.go                       |  3 ++-
 lxd/api_cluster.go               |  3 ++-
 lxd/cluster/connect.go           |  3 ++-
 lxd/network/driver_bridge.go     |  7 ++++---
 lxd/network/driver_common.go     | 15 ++++++++-------
 lxd/network/driver_macvlan.go    |  6 +++---
 lxd/network/driver_ovn.go        | 15 ++++++++-------
 lxd/network/driver_physical.go   | 12 ++++++------
 lxd/network/driver_sriov.go      |  6 +++---
 lxd/network/network_interface.go |  7 ++++---
 lxd/networks.go                  | 17 +++++++++--------
 11 files changed, 51 insertions(+), 43 deletions(-)

diff --git a/lxd/api.go b/lxd/api.go
index 2bdcba49d2..617046d451 100644
--- a/lxd/api.go
+++ b/lxd/api.go
@@ -9,6 +9,7 @@ import (
 
        "github.com/gorilla/mux"
        "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/project"
        "github.com/lxc/lxd/lxd/response"
@@ -118,7 +119,7 @@ func setCORSHeaders(rw http.ResponseWriter, req 
*http.Request, config *cluster.C
 // notifying us of some user-initiated API request that needs some action to be
 // taken on this node as well.
 func isClusterNotification(r *http.Request) bool {
-       return r.Header.Get("User-Agent") == cluster.UserAgentNotifier
+       return r.Header.Get("User-Agent") == request.UserAgentNotifier
 }
 
 // projectParam returns the project query parameter from the given request or 
"default" if parameter is not set.
diff --git a/lxd/api_cluster.go b/lxd/api_cluster.go
index 2430b22800..93470053bf 100644
--- a/lxd/api_cluster.go
+++ b/lxd/api_cluster.go
@@ -16,6 +16,7 @@ import (
 
        lxd "github.com/lxc/lxd/client"
        "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/node"
        "github.com/lxc/lxd/lxd/operations"
@@ -388,7 +389,7 @@ func clusterPutJoin(d *Daemon, req api.ClusterPut) 
response.Response {
                // As ServerAddress field is required to be set it means that 
we're using the new join API
                // introduced with the 'clustering_join' extension.
                // Connect to ourselves to initialize storage pools and 
networks using the API.
-               localClient, err := lxd.ConnectLXDUnix(d.UnixSocket(), 
&lxd.ConnectionArgs{UserAgent: cluster.UserAgentJoiner})
+               localClient, err := lxd.ConnectLXDUnix(d.UnixSocket(), 
&lxd.ConnectionArgs{UserAgent: request.UserAgentJoiner})
                if err != nil {
                        return errors.Wrap(err, "Failed to connect to local 
LXD")
                }
diff --git a/lxd/cluster/connect.go b/lxd/cluster/connect.go
index 1d6619e8bc..3836675c71 100644
--- a/lxd/cluster/connect.go
+++ b/lxd/cluster/connect.go
@@ -11,6 +11,7 @@ import (
        "github.com/pkg/errors"
 
        lxd "github.com/lxc/lxd/client"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/instance/instancetype"
        "github.com/lxc/lxd/lxd/state"
@@ -56,7 +57,7 @@ func Connect(address string, cert *shared.CertInfo, notify 
bool) (lxd.InstanceSe
                UserAgent:     version.UserAgent,
        }
        if notify {
-               args.UserAgent = UserAgentNotifier
+               args.UserAgent = request.UserAgentNotifier
        }
 
        url := fmt.Sprintf("https://%s";, address)
diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go
index a4d8654f5c..693fdb23e6 100644
--- a/lxd/network/driver_bridge.go
+++ b/lxd/network/driver_bridge.go
@@ -20,6 +20,7 @@ import (
 
        "github.com/lxc/lxd/lxd/apparmor"
        "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/daemon"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/dnsmasq"
@@ -416,7 +417,7 @@ func (n *bridge) Validate(config map[string]string) error {
 }
 
 // Create checks whether the bridge interface name is used already.
-func (n *bridge) Create(clientType cluster.ClientType) error {
+func (n *bridge) Create(clientType request.ClientType) error {
        n.logger.Debug("Create", log.Ctx{"clientType": clientType, "config": 
n.config})
 
        if InterfaceExists(n.name) {
@@ -432,7 +433,7 @@ func (n *bridge) isRunning() bool {
 }
 
 // Delete deletes a network.
-func (n *bridge) Delete(clientType cluster.ClientType) error {
+func (n *bridge) Delete(clientType request.ClientType) error {
        n.logger.Debug("Delete", log.Ctx{"clientType": clientType})
 
        // Bring the local network down if created on this node.
@@ -1542,7 +1543,7 @@ func (n *bridge) Stop() error {
 
 // Update updates the network. Accepts notification boolean indicating if this 
update request is coming from a
 // cluster notification, in which case do not update the database, just apply 
local changes needed.
-func (n *bridge) Update(newNetwork api.NetworkPut, targetNode string, 
clientType cluster.ClientType) error {
+func (n *bridge) Update(newNetwork api.NetworkPut, targetNode string, 
clientType request.ClientType) error {
        n.logger.Debug("Update", log.Ctx{"clientType": clientType, 
"newNetwork": newNetwork})
 
        err := n.populateAutoConfig(newNetwork.Config)
diff --git a/lxd/network/driver_common.go b/lxd/network/driver_common.go
index beb5e67feb..03f4b9ab7d 100644
--- a/lxd/network/driver_common.go
+++ b/lxd/network/driver_common.go
@@ -11,6 +11,7 @@ import (
 
        lxd "github.com/lxc/lxd/client"
        "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/project"
        "github.com/lxc/lxd/lxd/state"
@@ -227,7 +228,7 @@ func (n *common) DHCPv6Ranges() []shared.IPRange {
 }
 
 // update the internal config variables, and if not cluster notification, 
notifies all nodes and updates database.
-func (n *common) update(applyNetwork api.NetworkPut, targetNode string, 
clientType cluster.ClientType) error {
+func (n *common) update(applyNetwork api.NetworkPut, targetNode string, 
clientType request.ClientType) error {
        // Update internal config before database has been updated (so that if 
update is a notification we apply
        // the config being supplied and not that in the database).
        n.description = applyNetwork.Description
@@ -235,7 +236,7 @@ func (n *common) update(applyNetwork api.NetworkPut, 
targetNode string, clientTy
 
        // If this update isn't coming via a cluster notification itself, then 
notify all nodes of change and then
        // update the database.
-       if clientType != cluster.ClientTypeNotifier {
+       if clientType != request.ClientTypeNotifier {
                if targetNode == "" {
                        // Notify all other nodes to update the network if no 
target specified.
                        notifier, err := cluster.NewNotifier(n.state, 
n.state.Endpoints.NetworkCert(), cluster.NotifyAll)
@@ -323,8 +324,8 @@ func (n *common) configChanged(newNetwork api.NetworkPut) 
(bool, []string, api.N
 }
 
 // create just sends the needed lifecycle event.
-func (n *common) create(clientType cluster.ClientType) error {
-       if clientType == cluster.ClientTypeNormal {
+func (n *common) create(clientType request.ClientType) error {
+       if clientType == request.ClientTypeNormal {
                n.lifecycle("created", nil)
        }
 
@@ -361,9 +362,9 @@ func (n *common) rename(newName string) error {
 }
 
 // delete the network from the database if clusterNotification is false.
-func (n *common) delete(clientType cluster.ClientType) error {
+func (n *common) delete(clientType request.ClientType) error {
        // Only delete database record if not cluster notification.
-       if clientType != cluster.ClientTypeNotifier {
+       if clientType != request.ClientTypeNotifier {
                // Notify all other nodes. If any node is down, an error will 
be returned.
                notifier, err := cluster.NewNotifier(n.state, 
n.state.Endpoints.NetworkCert(), cluster.NotifyAll)
                if err != nil {
@@ -394,7 +395,7 @@ func (n *common) delete(clientType cluster.ClientType) 
error {
 }
 
 // Create is a no-op.
-func (n *common) Create(clientType cluster.ClientType) error {
+func (n *common) Create(clientType request.ClientType) error {
        n.logger.Debug("Create", log.Ctx{"clientType": clientType, "config": 
n.config})
 
        return n.create(clientType)
diff --git a/lxd/network/driver_macvlan.go b/lxd/network/driver_macvlan.go
index ef87f882d3..60eac1a092 100644
--- a/lxd/network/driver_macvlan.go
+++ b/lxd/network/driver_macvlan.go
@@ -1,7 +1,7 @@
 package network
 
 import (
-       "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/revert"
        "github.com/lxc/lxd/shared/api"
@@ -43,7 +43,7 @@ func (n *macvlan) Validate(config map[string]string) error {
 }
 
 // Delete deletes a network.
-func (n *macvlan) Delete(clientType cluster.ClientType) error {
+func (n *macvlan) Delete(clientType request.ClientType) error {
        n.logger.Debug("Delete", log.Ctx{"clientType": clientType})
        return n.common.delete(clientType)
 }
@@ -77,7 +77,7 @@ func (n *macvlan) Stop() error {
 
 // Update updates the network. Accepts notification boolean indicating if this 
update request is coming from a
 // cluster notification, in which case do not update the database, just apply 
local changes needed.
-func (n *macvlan) Update(newNetwork api.NetworkPut, targetNode string, 
clientType cluster.ClientType) error {
+func (n *macvlan) Update(newNetwork api.NetworkPut, targetNode string, 
clientType request.ClientType) error {
        n.logger.Debug("Update", log.Ctx{"clientType": clientType, 
"newNetwork": newNetwork})
 
        dbUpdateNeeeded, _, oldNetwork, err := 
n.common.configChanged(newNetwork)
diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index d18e28f1ba..0bcd6965e1 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -16,6 +16,7 @@ import (
        "github.com/pkg/errors"
 
        "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        deviceConfig "github.com/lxc/lxd/lxd/device/config"
        "github.com/lxc/lxd/lxd/instance"
@@ -1260,11 +1261,11 @@ func (n *ovn) populateAutoConfig(config 
map[string]string) error {
 }
 
 // Create sets up network in OVN Northbound database.
-func (n *ovn) Create(clientType cluster.ClientType) error {
+func (n *ovn) Create(clientType request.ClientType) error {
        n.logger.Debug("Create", log.Ctx{"clientType": clientType, "config": 
n.config})
 
        // We only need to setup the OVN Northbound database once, not on every 
clustered node.
-       if clientType == cluster.ClientTypeNormal {
+       if clientType == request.ClientTypeNormal {
                err := n.setup(false)
                if err != nil {
                        return err
@@ -1765,7 +1766,7 @@ func (n *ovn) deleteChassisGroupEntry() error {
 }
 
 // Delete deletes a network.
-func (n *ovn) Delete(clientType cluster.ClientType) error {
+func (n *ovn) Delete(clientType request.ClientType) error {
        n.logger.Debug("Delete", log.Ctx{"clientType": clientType})
 
        if n.LocalStatus() == api.NetworkStatusCreated {
@@ -1774,7 +1775,7 @@ func (n *ovn) Delete(clientType cluster.ClientType) error 
{
                        return err
                }
 
-               if clientType == cluster.ClientTypeNormal {
+               if clientType == request.ClientTypeNormal {
                        client, err := n.getClient()
                        if err != nil {
                                return err
@@ -1884,7 +1885,7 @@ func (n *ovn) Stop() error {
 
 // Update updates the network. Accepts notification boolean indicating if this 
update request is coming from a
 // cluster notification, in which case do not update the database, just apply 
local changes needed.
-func (n *ovn) Update(newNetwork api.NetworkPut, targetNode string, clientType 
cluster.ClientType) error {
+func (n *ovn) Update(newNetwork api.NetworkPut, targetNode string, clientType 
request.ClientType) error {
        n.logger.Debug("Update", log.Ctx{"clientType": clientType, 
"newNetwork": newNetwork})
 
        err := n.populateAutoConfig(newNetwork.Config)
@@ -1915,7 +1916,7 @@ func (n *ovn) Update(newNetwork api.NetworkPut, 
targetNode string, clientType cl
                n.common.update(oldNetwork, targetNode, clientType)
 
                // Reset any change that was made to logical network.
-               if clientType == cluster.ClientTypeNormal {
+               if clientType == request.ClientTypeNormal {
                        n.setup(true)
                }
 
@@ -1941,7 +1942,7 @@ func (n *ovn) Update(newNetwork api.NetworkPut, 
targetNode string, clientType cl
        }
 
        // Re-setup the logical network after config applied if needed.
-       if len(changedKeys) > 0 && clientType == cluster.ClientTypeNormal {
+       if len(changedKeys) > 0 && clientType == request.ClientTypeNormal {
                err = n.setup(true)
                if err != nil {
                        return err
diff --git a/lxd/network/driver_physical.go b/lxd/network/driver_physical.go
index 2b37403005..b8bcdca501 100644
--- a/lxd/network/driver_physical.go
+++ b/lxd/network/driver_physical.go
@@ -6,7 +6,7 @@ import (
 
        "github.com/pkg/errors"
 
-       "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/project"
        "github.com/lxc/lxd/lxd/revert"
@@ -97,11 +97,11 @@ func (n *physical) checkParentUse(ourConfig 
map[string]string) (bool, error) {
 
 // Create checks whether the referenced parent interface is used by other 
networks or instance devices, as we
 // need to have exclusive access to the interface.
-func (n *physical) Create(clientType cluster.ClientType) error {
+func (n *physical) Create(clientType request.ClientType) error {
        n.logger.Debug("Create", log.Ctx{"clientType": clientType, "config": 
n.config})
 
        // We only need to check in the database once, not on every clustered 
node.
-       if clientType == cluster.ClientTypeNormal {
+       if clientType == request.ClientTypeNormal {
                inUse, err := n.checkParentUse(n.config)
                if err != nil {
                        return err
@@ -115,7 +115,7 @@ func (n *physical) Create(clientType cluster.ClientType) 
error {
 }
 
 // Delete deletes a network.
-func (n *physical) Delete(clientType cluster.ClientType) error {
+func (n *physical) Delete(clientType request.ClientType) error {
        n.logger.Debug("Delete", log.Ctx{"clientType": clientType})
 
        if n.LocalStatus() == api.NetworkStatusCreated {
@@ -217,7 +217,7 @@ func (n *physical) Stop() error {
 
 // Update updates the network. Accepts notification boolean indicating if this 
update request is coming from a
 // cluster notification, in which case do not update the database, just apply 
local changes needed.
-func (n *physical) Update(newNetwork api.NetworkPut, targetNode string, 
clientType cluster.ClientType) error {
+func (n *physical) Update(newNetwork api.NetworkPut, targetNode string, 
clientType request.ClientType) error {
        n.logger.Debug("Update", log.Ctx{"clientType": clientType, 
"newNetwork": newNetwork})
 
        dbUpdateNeeeded, changedKeys, oldNetwork, err := 
n.common.configChanged(newNetwork)
@@ -240,7 +240,7 @@ func (n *physical) Update(newNetwork api.NetworkPut, 
targetNode string, clientTy
        hostNameChanged := shared.StringInSlice("vlan", changedKeys) || 
shared.StringInSlice("parent", changedKeys)
 
        // We only need to check in the database once, not on every clustered 
node.
-       if clientType == cluster.ClientTypeNormal {
+       if clientType == request.ClientTypeNormal {
                if hostNameChanged {
                        isUsed, err := n.IsUsed()
                        if isUsed || err != nil {
diff --git a/lxd/network/driver_sriov.go b/lxd/network/driver_sriov.go
index 21044302d2..988e1ea1cc 100644
--- a/lxd/network/driver_sriov.go
+++ b/lxd/network/driver_sriov.go
@@ -1,7 +1,7 @@
 package network
 
 import (
-       "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/revert"
        "github.com/lxc/lxd/shared/api"
@@ -43,7 +43,7 @@ func (n *sriov) Validate(config map[string]string) error {
 }
 
 // Delete deletes a network.
-func (n *sriov) Delete(clientType cluster.ClientType) error {
+func (n *sriov) Delete(clientType request.ClientType) error {
        n.logger.Debug("Delete", log.Ctx{"clientType": clientType})
        return n.common.delete(clientType)
 }
@@ -77,7 +77,7 @@ func (n *sriov) Stop() error {
 
 // Update updates the network. Accepts notification boolean indicating if this 
update request is coming from a
 // cluster notification, in which case do not update the database, just apply 
local changes needed.
-func (n *sriov) Update(newNetwork api.NetworkPut, targetNode string, 
clientType cluster.ClientType) error {
+func (n *sriov) Update(newNetwork api.NetworkPut, targetNode string, 
clientType request.ClientType) error {
        n.logger.Debug("Update", log.Ctx{"clientType": clientType, 
"newNetwork": newNetwork})
 
        dbUpdateNeeeded, _, oldNetwork, err := 
n.common.configChanged(newNetwork)
diff --git a/lxd/network/network_interface.go b/lxd/network/network_interface.go
index 43a2f09dab..021cd88198 100644
--- a/lxd/network/network_interface.go
+++ b/lxd/network/network_interface.go
@@ -4,6 +4,7 @@ import (
        "net"
 
        "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/state"
        "github.com/lxc/lxd/shared"
@@ -42,11 +43,11 @@ type Network interface {
        DHCPv6Ranges() []shared.IPRange
 
        // Actions.
-       Create(clientType cluster.ClientType) error
+       Create(clientType request.ClientType) error
        Start() error
        Stop() error
        Rename(name string) error
-       Update(newNetwork api.NetworkPut, targetNode string, clientType 
cluster.ClientType) error
+       Update(newNetwork api.NetworkPut, targetNode string, clientType 
request.ClientType) error
        HandleHeartbeat(heartbeatData *cluster.APIHeartbeat) error
-       Delete(clientType cluster.ClientType) error
+       Delete(clientType request.ClientType) error
 }
diff --git a/lxd/networks.go b/lxd/networks.go
index e101054a44..e9e9464a3d 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -17,6 +17,7 @@ import (
 
        lxd "github.com/lxc/lxd/client"
        "github.com/lxc/lxd/lxd/cluster"
+       "github.com/lxc/lxd/lxd/cluster/request"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/device/nictype"
        "github.com/lxc/lxd/lxd/instance"
@@ -194,7 +195,7 @@ func networksPost(d *Daemon, r *http.Request) 
response.Response {
        url := fmt.Sprintf("/%s/networks/%s", version.APIVersion, req.Name)
        resp := response.SyncResponseLocation(true, nil, url)
 
-       clientType := cluster.UserAgentClientType(r.Header.Get("User-Agent"))
+       clientType := request.UserAgentClientType(r.Header.Get("User-Agent"))
 
        if isClusterNotification(r) {
                // This is an internal request which triggers the actual 
creation of the network across all nodes
@@ -244,7 +245,7 @@ func networksPost(d *Daemon, r *http.Request) 
response.Response {
 
        if count > 1 {
                // Simulate adding pending node network config when the driver 
doesn't support per-node config.
-               if !netTypeInfo.NodeSpecificConfig && clientType != 
cluster.ClientTypeJoiner {
+               if !netTypeInfo.NodeSpecificConfig && clientType != 
request.ClientTypeJoiner {
                        revert.Add(func() {
                                d.cluster.DeleteNetwork(projectName, req.Name)
                        })
@@ -315,7 +316,7 @@ func networksPost(d *Daemon, r *http.Request) 
response.Response {
 
 // networksPostCluster checks that there is a pending network in the database 
and then attempts to setup the
 // network on each node. If all nodes are successfully setup then the 
network's state is set to created.
-func networksPostCluster(d *Daemon, projectName string, req api.NetworksPost, 
clientType cluster.ClientType, netType network.Type) error {
+func networksPostCluster(d *Daemon, projectName string, req api.NetworksPost, 
clientType request.ClientType, netType network.Type) error {
        // Check that no node-specific config key has been supplied in request.
        for key := range req.Config {
                if shared.StringInSlice(key, db.NodeSpecificNetworkConfig) {
@@ -432,7 +433,7 @@ func networksPostCluster(d *Daemon, projectName string, req 
api.NetworksPost, cl
 
 // Create the network on the system. The clusterNotification flag is used to 
indicate whether creation request
 // is coming from a cluster notification (and if so we should not delete the 
database record on error).
-func doNetworksCreate(d *Daemon, projectName string, req api.NetworksPost, 
clientType cluster.ClientType) error {
+func doNetworksCreate(d *Daemon, projectName string, req api.NetworksPost, 
clientType request.ClientType) error {
        // Start the network.
        n, err := network.LoadByName(d.State(), projectName, req.Name)
        if err != nil {
@@ -458,7 +459,7 @@ func doNetworksCreate(d *Daemon, projectName string, req 
api.NetworksPost, clien
 
        // Only start networks when not doing a cluster pre-join phase (this 
ensures that networks are only started
        // once the node has fully joined the clustered database and has 
consistent config with rest of the nodes).
-       if clientType != cluster.ClientTypeJoiner {
+       if clientType != request.ClientTypeJoiner {
                err = n.Start()
                if err != nil {
                        delErr := n.Delete(clientType)
@@ -608,7 +609,7 @@ func networkDelete(d *Daemon, r *http.Request) 
response.Response {
                return response.SmartError(err)
        }
 
-       clientType := cluster.UserAgentClientType(r.Header.Get("User-Agent"))
+       clientType := request.UserAgentClientType(r.Header.Get("User-Agent"))
 
        clusterNotification := isClusterNotification(r)
        if !clusterNotification {
@@ -790,7 +791,7 @@ func networkPut(d *Daemon, r *http.Request) 
response.Response {
                }
        }
 
-       clientType := cluster.UserAgentClientType(r.Header.Get("User-Agent"))
+       clientType := request.UserAgentClientType(r.Header.Get("User-Agent"))
 
        return doNetworkUpdate(d, projectName, n, req, targetNode, clientType, 
r.Method, clustered)
 }
@@ -801,7 +802,7 @@ func networkPatch(d *Daemon, r *http.Request) 
response.Response {
 
 // doNetworkUpdate loads the current local network config, merges with the 
requested network config, validates
 // and applies the changes. Will also notify other cluster nodes of non-node 
specific config if needed.
-func doNetworkUpdate(d *Daemon, projectName string, n network.Network, req 
api.NetworkPut, targetNode string, clientType cluster.ClientType, httpMethod 
string, clustered bool) response.Response {
+func doNetworkUpdate(d *Daemon, projectName string, n network.Network, req 
api.NetworkPut, targetNode string, clientType request.ClientType, httpMethod 
string, clustered bool) response.Response {
        if req.Config == nil {
                req.Config = map[string]string{}
        }

From 4f86131d82533db41cf678128315e3c57995a822 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 1 Dec 2020 16:40:11 +0000
Subject: [PATCH 04/10] lxd/networks: Ensure etag generation uses its own copy
 of config in networkPut

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/networks.go | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/lxd/networks.go b/lxd/networks.go
index e9e9464a3d..fa1e6ae78f 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -744,22 +744,19 @@ func networkPut(d *Daemon, r *http.Request) 
response.Response {
        }
 
        // Duplicate config for etag modification and generation.
-       curConfig := map[string]string{}
-       for k, v := range n.Config() {
-               curConfig[k] = v
-       }
+       etagConfig := util.CopyConfig(n.Config())
 
        // If no target node is specified and the daemon is clustered, we omit 
the node-specific fields so that
        // the e-tag can be generated correctly. This is because the GET 
request used to populate the request
        // will also remove node-specific keys when no target is specified.
        if targetNode == "" && clustered {
                for _, key := range db.NodeSpecificNetworkConfig {
-                       delete(curConfig, key)
+                       delete(etagConfig, key)
                }
        }
 
        // Validate the ETag.
-       etag := []interface{}{n.Name(), n.IsManaged(), n.Type(), 
n.Description(), curConfig}
+       etag := []interface{}{n.Name(), n.IsManaged(), n.Type(), 
n.Description(), etagConfig}
        err = util.EtagCheck(r, etag)
        if err != nil {
                return response.PreconditionFailed(err)
@@ -782,6 +779,8 @@ func networkPut(d *Daemon, r *http.Request) 
response.Response {
                                }
                        }
                } else {
+                       curConfig := n.Config()
+
                        // If a target is specified, then ensure only 
node-specific config keys are changed.
                        for k, v := range req.Config {
                                if !shared.StringInSlice(k, 
db.NodeSpecificNetworkConfig) && curConfig[k] != v {

From c78422d501d957258fbb1e60c2fdba1b2386b8ce Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 3 Dec 2020 14:59:43 +0000
Subject: [PATCH 05/10] lxd/network/driver: Takes NetworkStatus safety patch
 from stable-4.0 and applies to master

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/network/driver_bridge.go   | 2 +-
 lxd/network/driver_ovn.go      | 2 +-
 lxd/network/driver_physical.go | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go
index 693fdb23e6..6f469f85e8 100644
--- a/lxd/network/driver_bridge.go
+++ b/lxd/network/driver_bridge.go
@@ -437,7 +437,7 @@ func (n *bridge) Delete(clientType request.ClientType) 
error {
        n.logger.Debug("Delete", log.Ctx{"clientType": clientType})
 
        // Bring the local network down if created on this node.
-       if n.LocalStatus() == api.NetworkStatusCreated {
+       if n.LocalStatus() == api.NetworkStatusCreated || n.LocalStatus() == 
api.NetworkStatusUnknown {
                if n.isRunning() {
                        err := n.Stop()
                        if err != nil {
diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 0bcd6965e1..e222099fee 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -1769,7 +1769,7 @@ func (n *ovn) deleteChassisGroupEntry() error {
 func (n *ovn) Delete(clientType request.ClientType) error {
        n.logger.Debug("Delete", log.Ctx{"clientType": clientType})
 
-       if n.LocalStatus() == api.NetworkStatusCreated {
+       if n.LocalStatus() == api.NetworkStatusCreated || n.LocalStatus() == 
api.NetworkStatusUnknown {
                err := n.Stop()
                if err != nil {
                        return err
diff --git a/lxd/network/driver_physical.go b/lxd/network/driver_physical.go
index b8bcdca501..19d0001a57 100644
--- a/lxd/network/driver_physical.go
+++ b/lxd/network/driver_physical.go
@@ -118,7 +118,7 @@ func (n *physical) Create(clientType request.ClientType) 
error {
 func (n *physical) Delete(clientType request.ClientType) error {
        n.logger.Debug("Delete", log.Ctx{"clientType": clientType})
 
-       if n.LocalStatus() == api.NetworkStatusCreated {
+       if n.LocalStatus() == api.NetworkStatusCreated || n.LocalStatus() == 
api.NetworkStatusUnknown {
                err := n.Stop()
                if err != nil {
                        return err

From 4702ec635413b8be73df369652d3dedbf893ed1c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 3 Dec 2020 09:53:49 +0000
Subject: [PATCH 06/10] lxd/networks: Comment in networksPostCluster

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/networks.go | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lxd/networks.go b/lxd/networks.go
index fa1e6ae78f..e778ffe9f6 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -403,6 +403,8 @@ func networksPostCluster(d *Daemon, projectName string, req 
api.NetworksPost, cl
                }
 
                nodeReq := req
+
+               // Merge node specific config items into global config.
                for key, value := range configs[server.Environment.ServerName] {
                        nodeReq.Config[key] = value
                }

From 544a7c09bd05458ff3a8d5097e94058f43b96c9f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 3 Dec 2020 09:53:19 +0000
Subject: [PATCH 07/10] lxd/networks: Corrects log level in networksPostCluster

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/networks.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/networks.go b/lxd/networks.go
index e778ffe9f6..5bdd34d3d6 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -393,7 +393,7 @@ func networksPostCluster(d *Daemon, projectName string, req 
api.NetworksPost, cl
        if err != nil {
                return err
        }
-       logger.Error("Created network on local cluster member", 
log.Ctx{"project": projectName, "network": req.Name})
+       logger.Debug("Created network on local cluster member", 
log.Ctx{"project": projectName, "network": req.Name})
 
        // Notify other nodes to create the network.
        err = notifier(func(client lxd.InstanceServer) error {
@@ -413,7 +413,7 @@ func networksPostCluster(d *Daemon, projectName string, req 
api.NetworksPost, cl
                if err != nil {
                        return err
                }
-               logger.Info("Created network on cluster member", 
log.Ctx{"project": projectName, "network": req.Name, "member": 
server.Environment.ServerName})
+               logger.Debug("Created network on cluster member", 
log.Ctx{"project": projectName, "network": req.Name, "member": 
server.Environment.ServerName})
 
                return nil
        })

From 3d014cb243797d953040e6035375bd5d4716397e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 1 Dec 2020 13:53:23 +0000
Subject: [PATCH 08/10] lxd/networks: golint fix

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/networks.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/networks.go b/lxd/networks.go
index 5bdd34d3d6..c4e2e82b66 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -12,7 +12,6 @@ import (
        "sync"
 
        "github.com/gorilla/mux"
-       log "github.com/lxc/lxd/shared/log15"
        "github.com/pkg/errors"
 
        lxd "github.com/lxc/lxd/client"
@@ -31,6 +30,7 @@ import (
        "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"
        "github.com/lxc/lxd/shared/version"
 )

From ced572e2f1f04dca363af1ee9db2ed796943b15b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 1 Dec 2020 10:32:31 +0000
Subject: [PATCH 09/10] lxd/db/networks: Removes unused NetworkErrored function

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/db/networks.go | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index 34a75003a6..86d2413ea9 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -323,11 +323,6 @@ func (c *ClusterTx) NetworkCreated(project string, name 
string) error {
        return c.networkState(project, name, networkCreated)
 }
 
-// NetworkErrored sets the state of the given network to networkErrored.
-func (c *ClusterTx) NetworkErrored(project string, name string) error {
-       return c.networkState(project, name, networkErrored)
-}
-
 func (c *ClusterTx) networkState(project string, name string, state 
NetworkState) error {
        stmt := "UPDATE networks SET state=? WHERE project_id = (SELECT id FROM 
projects WHERE name = ?) AND name=?"
        result, err := c.tx.Exec(stmt, state, project, name)

From 06aadbf1bdcdaa0ad20186276e35c1bd77adba78 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Tue, 1 Dec 2020 10:29:05 +0000
Subject: [PATCH 10/10] lxd/db/networks: Updates network state comments to
 indicate node usage

Signed-off-by: Thomas Parrott <thomas.parr...@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 86d2413ea9..dece3638a6 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -455,9 +455,9 @@ type NetworkState int
 
 // Network state.
 const (
-       networkPending NetworkState = iota // Network defined but not yet 
created.
-       networkCreated                     // Network created on all nodes.
-       networkErrored                     // Network creation failed on some 
nodes
+       networkPending NetworkState = iota // Network defined but not yet 
created globally or on specific node.
+       networkCreated                     // Network created globally or on 
specific node.
+       networkErrored                     // Deprecated (should no longer 
occur).
 )
 
 // NetworkType indicates type of network.
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to