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

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) ===
Applies defaults to missing config keys on `Update()` not just when creating the initial network.

This fixes a bug where if one of the fields that is automatically populated at create time is removed via an update, the key is re-populated using new (sometimes random) values.

Includes https://github.com/lxc/lxd/pull/7689 (dont merge until after it has been and this has been rebased please).


From 665725682880dd1b318ac640b72622eca706419a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 23 Jul 2020 14:50:10 +0100
Subject: [PATCH 1/7] lxd/networks: Fixes bug in doNetworkUpdate that prevents
 removal of non-node specific keys

This was introduced when the PUT method was merged with the PATCH method.

However there is still sufficiently shared logic to justify putting in a small 
tweak to handle the different behaviour between PUT and PATCH.

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

diff --git a/lxd/networks.go b/lxd/networks.go
index 7b0b0a303e..0aca89662b 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -692,7 +692,7 @@ func networkPut(d *Daemon, r *http.Request) 
response.Response {
                }
        }
 
-       return doNetworkUpdate(d, name, req, targetNode, 
isClusterNotification(r))
+       return doNetworkUpdate(d, name, req, targetNode, 
isClusterNotification(r), r.Method)
 }
 
 func networkPatch(d *Daemon, r *http.Request) response.Response {
@@ -701,7 +701,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, name string, req api.NetworkPut, targetNode 
string, clusterNotification bool) response.Response {
+func doNetworkUpdate(d *Daemon, name string, req api.NetworkPut, targetNode 
string, clusterNotification bool, httpMethod string) response.Response {
        // Load the local node-specific network.
        n, err := network.LoadByName(d.State(), name)
        if err != nil {
@@ -712,11 +712,23 @@ func doNetworkUpdate(d *Daemon, name string, req 
api.NetworkPut, targetNode stri
                req.Config = map[string]string{}
        }
 
-       // Merge the current node-specific network config with the submitted 
config to allow validation.
-       for k, v := range n.Config() {
-               _, ok := req.Config[k]
-               if !ok {
-                       req.Config[k] = v
+       if targetNode == "" && httpMethod != http.MethodPatch {
+               // If non-node specific config being updated via "put" method, 
then merge the current
+               // node-specific network config with the submitted config to 
allow validation.
+               // This allows removal of non-node specific keys when they are 
absent from request config.
+               for k, v := range n.Config() {
+                       if shared.StringInSlice(k, 
db.NodeSpecificNetworkConfig) {
+                               req.Config[k] = v
+                       }
+               }
+       } else if httpMethod == http.MethodPatch {
+               // If config being updated via "patch" method, then merge all 
existing config with the keys that
+               // are present in the request config.
+               for k, v := range n.Config() {
+                       _, ok := req.Config[k]
+                       if !ok {
+                               req.Config[k] = v
+                       }
                }
        }
 

From 00808134dfa3361248561618b6700b101bff2a7f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 23 Jul 2020 11:03:19 +0100
Subject: [PATCH 2/7] lxd/network/driver/bridge: Consistent comment ending in
 setup()

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

diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go
index 8076cba649..d9f5c49c7b 100644
--- a/lxd/network/driver_bridge.go
+++ b/lxd/network/driver_bridge.go
@@ -357,7 +357,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                return fmt.Errorf("Cannot start pending network")
        }
 
-       // Create directory
+       // Create directory.
        if !shared.PathExists(shared.VarPath("networks", n.name)) {
                err := os.MkdirAll(shared.VarPath("networks", n.name), 0711)
                if err != nil {
@@ -365,7 +365,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                }
        }
 
-       // Create the bridge interface
+       // Create the bridge interface.
        if !n.isRunning() {
                if n.config["bridge.driver"] == "openvswitch" {
                        ovs := openvswitch.NewOVS()
@@ -385,10 +385,10 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                }
        }
 
-       // Get a list of tunnels
+       // Get a list of tunnels.
        tunnels := n.getTunnels()
 
-       // IPv6 bridge configuration
+       // IPv6 bridge configuration.
        if !shared.StringInSlice(n.config["ipv6.address"], []string{"", 
"none"}) {
                if !shared.PathExists("/proc/sys/net/ipv6") {
                        return fmt.Errorf("Network has ipv6.address but kernel 
IPv6 support is missing")
@@ -405,13 +405,13 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                }
        }
 
-       // Get a list of interfaces
+       // Get a list of interfaces.
        ifaces, err := net.Interfaces()
        if err != nil {
                return err
        }
 
-       // Cleanup any existing tunnel device
+       // Cleanup any existing tunnel device.
        for _, iface := range ifaces {
                if strings.HasPrefix(iface.Name, fmt.Sprintf("%s-", n.name)) {
                        _, err = shared.RunCommand("ip", "link", "del", "dev", 
iface.Name)
@@ -421,7 +421,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                }
        }
 
-       // Set the MTU
+       // Set the MTU.
        mtu := ""
        if n.config["bridge.mtu"] != "" {
                mtu = n.config["bridge.mtu"]
@@ -435,7 +435,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                }
        }
 
-       // Attempt to add a dummy device to the bridge to force the MTU
+       // Attempt to add a dummy device to the bridge to force the MTU.
        if mtu != "" && n.config["bridge.driver"] != "openvswitch" {
                _, err = shared.RunCommand("ip", "link", "add", "dev", 
fmt.Sprintf("%s-mtu", n.name), "mtu", mtu, "type", "dummy")
                if err == nil {
@@ -446,7 +446,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                }
        }
 
-       // Now, set a default MTU
+       // Now, set a default MTU.
        if mtu == "" {
                mtu = "1500"
        }
@@ -456,7 +456,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                return err
        }
 
-       // Set the MAC address
+       // Set the MAC address.
        if n.config["bridge.hwaddr"] != "" {
                _, err = shared.RunCommand("ip", "link", "set", "dev", n.name, 
"address", n.config["bridge.hwaddr"])
                if err != nil {
@@ -478,13 +478,13 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                }
        }
 
-       // Bring it up
+       // Bring it up.
        _, err = shared.RunCommand("ip", "link", "set", "dev", n.name, "up")
        if err != nil {
                return err
        }
 
-       // Add any listed existing external interface
+       // Add any listed existing external interface.
        if n.config["bridge.external_interfaces"] != "" {
                for _, entry := range 
strings.Split(n.config["bridge.external_interfaces"], ",") {
                        entry = strings.TrimSpace(entry)
@@ -532,7 +532,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                return err
        }
 
-       // Flush all IPv4 addresses and routes
+       // Flush all IPv4 addresses and routes.
        _, err = shared.RunCommand("ip", "-4", "addr", "flush", "dev", n.name, 
"scope", "global")
        if err != nil {
                return err
@@ -543,17 +543,17 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                return err
        }
 
-       // Configure IPv4 firewall (includes fan)
+       // Configure IPv4 firewall (includes fan).
        if n.config["bridge.mode"] == "fan" || 
!shared.StringInSlice(n.config["ipv4.address"], []string{"", "none"}) {
                if n.HasDHCPv4() && n.hasIPv4Firewall() {
-                       // Setup basic iptables overrides for DHCP/DNS
+                       // Setup basic iptables overrides for DHCP/DNS.
                        err = 
n.state.Firewall.NetworkSetupDHCPDNSAccess(n.name, 4)
                        if err != nil {
                                return err
                        }
                }
 
-               // Attempt a workaround for broken DHCP clients
+               // Attempt a workaround for broken DHCP clients.
                if n.hasIPv4Firewall() {
                        err = 
n.state.Firewall.NetworkSetupDHCPv4Checksum(n.name)
                        if err != nil {
@@ -561,7 +561,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                        }
                }
 
-               // Allow forwarding
+               // Allow forwarding.
                if n.config["bridge.mode"] == "fan" || n.config["ipv4.routing"] 
== "" || shared.IsTrue(n.config["ipv4.routing"]) {
                        err = util.SysctlSet("net/ipv4/ip_forward", "1")
                        if err != nil {
@@ -584,7 +584,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                }
        }
 
-       // Start building process using subprocess package
+       // Start building process using subprocess package.
        command := "dnsmasq"
        dnsmasqCmd := []string{"--keep-in-foreground", "--strict-order", 
"--bind-interfaces",
                "--except-interface=lo",
@@ -597,14 +597,14 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                return err
        }
 
-       // --dhcp-rapid-commit option is only supported on >2.79
+       // --dhcp-rapid-commit option is only supported on >2.79.
        minVer, _ := version.NewDottedVersion("2.79")
        if dnsmasqVersion.Compare(minVer) > 0 {
                dnsmasqCmd = append(dnsmasqCmd, "--dhcp-rapid-commit")
        }
 
        if !daemon.Debug {
-               // --quiet options are only supported on >2.67
+               // --quiet options are only supported on >2.67.
                minVer, _ := version.NewDottedVersion("2.67")
 
                if err == nil && dnsmasqVersion.Compare(minVer) > 0 {
@@ -612,15 +612,15 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                }
        }
 
-       // Configure IPv4
+       // Configure IPv4.
        if !shared.StringInSlice(n.config["ipv4.address"], []string{"", 
"none"}) {
-               // Parse the subnet
+               // Parse the subnet.
                ip, subnet, err := net.ParseCIDR(n.config["ipv4.address"])
                if err != nil {
                        return err
                }
 
-               // Update the dnsmasq config
+               // Update the dnsmasq config.
                dnsmasqCmd = append(dnsmasqCmd, 
fmt.Sprintf("--listen-address=%s", ip.String()))
                if n.HasDHCPv4() {
                        if !shared.StringInSlice("--dhcp-no-override", 
dnsmasqCmd) {
@@ -655,7 +655,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                        }
                }
 
-               // Add the address
+               // Add the address.
                _, err = shared.RunCommand("ip", "-4", "addr", "add", "dev", 
n.name, n.config["ipv4.address"])
                if err != nil {
                        return err
@@ -663,7 +663,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
 
                // Configure NAT
                if shared.IsTrue(n.config["ipv4.nat"]) {
-                       //If a SNAT source address is specified, use that, 
otherwise default to using MASQUERADE mode.
+                       //If a SNAT source address is specified, use that, 
otherwise default to MASQUERADE mode.
                        var srcIP net.IP
                        if n.config["ipv4.nat.address"] != "" {
                                srcIP = 
net.ParseIP(n.config["ipv4.nat.address"])
@@ -682,7 +682,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                        }
                }
 
-               // Add additional routes
+               // Add additional routes.
                if n.config["ipv4.routes"] != "" {
                        for _, route := range 
strings.Split(n.config["ipv4.routes"], ",") {
                                route = strings.TrimSpace(route)
@@ -715,7 +715,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                return err
        }
 
-       // Flush all IPv6 addresses and routes
+       // Flush all IPv6 addresses and routes.
        _, err = shared.RunCommand("ip", "-6", "addr", "flush", "dev", n.name, 
"scope", "global")
        if err != nil {
                return err
@@ -726,15 +726,15 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                return err
        }
 
-       // Configure IPv6
+       // Configure IPv6.
        if !shared.StringInSlice(n.config["ipv6.address"], []string{"", 
"none"}) {
-               // Enable IPv6 for the subnet
+               // Enable IPv6 for the subnet.
                err := 
util.SysctlSet(fmt.Sprintf("net/ipv6/conf/%s/disable_ipv6", n.name), "0")
                if err != nil {
                        return err
                }
 
-               // Parse the subnet
+               // Parse the subnet.
                ip, subnet, err := net.ParseCIDR(n.config["ipv6.address"])
                if err != nil {
                        return err
@@ -745,18 +745,18 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        n.logger.Warn("IPv6 networks with a prefix larger than 
64 aren't properly supported by dnsmasq")
                }
 
-               // Update the dnsmasq config
+               // Update the dnsmasq config.
                dnsmasqCmd = append(dnsmasqCmd, 
[]string{fmt.Sprintf("--listen-address=%s", ip.String()), "--enable-ra"}...)
                if n.HasDHCPv6() {
                        if n.config["ipv6.firewall"] == "" || 
shared.IsTrue(n.config["ipv6.firewall"]) {
-                               // Setup basic iptables overrides for DHCP/DNS
+                               // Setup basic iptables overrides for DHCP/DNS.
                                err = 
n.state.Firewall.NetworkSetupDHCPDNSAccess(n.name, 6)
                                if err != nil {
                                        return err
                                }
                        }
 
-                       // Build DHCP configuration
+                       // Build DHCP configuration.
                        if !shared.StringInSlice("--dhcp-no-override", 
dnsmasqCmd) {
                                dnsmasqCmd = append(dnsmasqCmd, 
[]string{"--dhcp-no-override", "--dhcp-authoritative", 
fmt.Sprintf("--dhcp-leasefile=%s", shared.VarPath("networks", n.name, 
"dnsmasq.leases")), fmt.Sprintf("--dhcp-hostsfile=%s", 
shared.VarPath("networks", n.name, "dnsmasq.hosts"))}...)
                        }
@@ -782,15 +782,15 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        dnsmasqCmd = append(dnsmasqCmd, 
[]string{"--dhcp-range", fmt.Sprintf("::,constructor:%s,ra-only", n.name)}...)
                }
 
-               // Allow forwarding
+               // Allow forwarding.
                if n.config["ipv6.routing"] == "" || 
shared.IsTrue(n.config["ipv6.routing"]) {
-                       // Get a list of proc entries
+                       // Get a list of proc entries.
                        entries, err := 
ioutil.ReadDir("/proc/sys/net/ipv6/conf/")
                        if err != nil {
                                return err
                        }
 
-                       // First set accept_ra to 2 for everything
+                       // First set accept_ra to 2 for everything.
                        for _, entry := range entries {
                                content, err := 
ioutil.ReadFile(fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/accept_ra", 
entry.Name()))
                                if err == nil && string(content) != "1\n" {
@@ -803,7 +803,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                                }
                        }
 
-                       // Then set forwarding for all of them
+                       // Then set forwarding for all of them.
                        for _, entry := range entries {
                                err = 
util.SysctlSet(fmt.Sprintf("net/ipv6/conf/%s/forwarding", entry.Name()), "1")
                                if err != nil && !os.IsNotExist(err) {
@@ -826,13 +826,13 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        }
                }
 
-               // Add the address
+               // Add the address.
                _, err = shared.RunCommand("ip", "-6", "addr", "add", "dev", 
n.name, n.config["ipv6.address"])
                if err != nil {
                        return err
                }
 
-               // Configure NAT
+               // Configure NAT.
                if shared.IsTrue(n.config["ipv6.nat"]) {
                        var srcIP net.IP
                        if n.config["ipv6.nat.address"] != "" {
@@ -852,7 +852,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                        }
                }
 
-               // Add additional routes
+               // Add additional routes.
                if n.config["ipv6.routes"] != "" {
                        for _, route := range 
strings.Split(n.config["ipv6.routes"], ",") {
                                route = strings.TrimSpace(route)
@@ -870,21 +870,21 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                }
        }
 
-       // Configure the fan
+       // Configure the fan.
        dnsClustered := false
        dnsClusteredAddress := ""
        var overlaySubnet *net.IPNet
        if n.config["bridge.mode"] == "fan" {
                tunName := fmt.Sprintf("%s-fan", n.name)
 
-               // Parse the underlay
+               // Parse the underlay.
                underlay := n.config["fan.underlay_subnet"]
                _, underlaySubnet, err := net.ParseCIDR(underlay)
                if err != nil {
                        return nil
                }
 
-               // Parse the overlay
+               // Parse the overlay.
                overlay := n.config["fan.overlay_subnet"]
                if overlay == "" {
                        overlay = "240.0.0.0/8"
@@ -895,7 +895,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                        return err
                }
 
-               // Get the address
+               // Get the address.
                fanAddress, devName, devAddr, err := 
n.fanAddress(underlaySubnet, overlaySubnet)
                if err != nil {
                        return err
@@ -906,17 +906,17 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        fanAddress = fmt.Sprintf("%s/24", addr[0])
                }
 
-               // Update the MTU based on overlay device (if available)
+               // Update the MTU based on overlay device (if available).
                fanMtuInt, err := GetDevMTU(devName)
                if err == nil {
-                       // Apply overhead
+                       // Apply overhead.
                        if n.config["fan.type"] == "ipip" {
                                fanMtuInt = fanMtuInt - 20
                        } else {
                                fanMtuInt = fanMtuInt - 50
                        }
 
-                       // Apply changes
+                       // Apply changes.
                        fanMtu := fmt.Sprintf("%d", fanMtuInt)
                        if fanMtu != mtu {
                                mtu = fanMtu
@@ -934,19 +934,19 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        }
                }
 
-               // Parse the host subnet
+               // Parse the host subnet.
                _, hostSubnet, err := net.ParseCIDR(fmt.Sprintf("%s/24", 
addr[0]))
                if err != nil {
                        return err
                }
 
-               // Add the address
+               // Add the address.
                _, err = shared.RunCommand("ip", "-4", "addr", "add", "dev", 
n.name, fanAddress)
                if err != nil {
                        return err
                }
 
-               // Update the dnsmasq config
+               // Update the dnsmasq config.
                expiry := "1h"
                if n.config["ipv4.dhcp.expiry"] != "" {
                        expiry = n.config["ipv4.dhcp.expiry"]
@@ -959,7 +959,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                        fmt.Sprintf("--dhcp-hostsfile=%s", 
shared.VarPath("networks", n.name, "dnsmasq.hosts")),
                        "--dhcp-range", fmt.Sprintf("%s,%s,%s", 
GetIP(hostSubnet, 2).String(), GetIP(hostSubnet, -2).String(), expiry)}...)
 
-               // Setup the tunnel
+               // Setup the tunnel.
                if n.config["fan.type"] == "ipip" {
                        _, err = shared.RunCommand("ip", "-4", "route", 
"flush", "dev", "tunl0")
                        if err != nil {
@@ -971,7 +971,7 @@ func (n *bridge) setup(oldConfig map[string]string) error {
                                return err
                        }
 
-                       // Fails if the map is already set
+                       // Fails if the map is already set.
                        shared.RunCommand("ip", "link", "change", "dev", 
"tunl0", "type", "ipip", "fan-map", fmt.Sprintf("%s:%s", overlay, underlay))
 
                        _, err = shared.RunCommand("ip", "route", "add", 
overlay, "dev", "tunl0", "src", addr[0])
@@ -1002,7 +1002,7 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        }
                }
 
-               // Configure NAT
+               // Configure NAT.
                if n.config["ipv4.nat"] == "" || 
shared.IsTrue(n.config["ipv4.nat"]) {
                        if n.config["ipv4.nat.order"] == "after" {
                                err = 
n.state.Firewall.NetworkSetupOutboundNAT(n.name, overlaySubnet, nil, true)
@@ -1017,7 +1017,7 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        }
                }
 
-               // Setup clustered DNS
+               // Setup clustered DNS.
                clusterAddress, err := node.ClusterAddress(n.state.Node)
                if err != nil {
                        return err
@@ -1034,7 +1034,7 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                dnsClusteredAddress = strings.Split(fanAddress, "/")[0]
        }
 
-       // Configure tunnels
+       // Configure tunnels.
        for _, tunnel := range tunnels {
                getConfig := func(key string) string {
                        return n.config[fmt.Sprintf("tunnel.%s.%s", tunnel, 
key)]
@@ -1045,10 +1045,10 @@ func (n *bridge) setup(oldConfig map[string]string) 
error {
                tunRemote := getConfig("remote")
                tunName := fmt.Sprintf("%s-%s", n.name, tunnel)
 
-               // Configure the tunnel
+               // Configure the tunnel.
                cmd := []string{"ip", "link", "add", "dev", tunName}
                if tunProtocol == "gre" {
-                       // Skip partial configs
+                       // Skip partial configs.
                        if tunProtocol == "" || tunLocal == "" || tunRemote == 
"" {
                                continue
                        }
@@ -1058,7 +1058,7 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        tunGroup := getConfig("group")
                        tunInterface := getConfig("interface")
 
-                       // Skip partial configs
+                       // Skip partial configs.
                        if tunProtocol == "" {
                                continue
                        }
@@ -1102,13 +1102,13 @@ func (n *bridge) setup(oldConfig map[string]string) 
error {
                        cmd = append(cmd, []string{"ttl", tunTTL}...)
                }
 
-               // Create the interface
+               // Create the interface.
                _, err = shared.RunCommand(cmd[0], cmd[1:]...)
                if err != nil {
                        return err
                }
 
-               // Bridge it and bring up
+               // Bridge it and bring up.
                err = AttachInterface(n.name, tunName)
                if err != nil {
                        return err
@@ -1131,7 +1131,7 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                return err
        }
 
-       // Kill any existing dnsmasq and forkdns daemon for this network
+       // Kill any existing dnsmasq and forkdns daemon for this network.
        err = dnsmasq.Kill(n.name, false)
        if err != nil {
                return err
@@ -1142,9 +1142,9 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                return err
        }
 
-       // Configure dnsmasq
+       // Configure dnsmasq.
        if n.config["bridge.mode"] == "fan" || 
!shared.StringInSlice(n.config["ipv4.address"], []string{"", "none"}) || 
!shared.StringInSlice(n.config["ipv6.address"], []string{"", "none"}) {
-               // Setup the dnsmasq domain
+               // Setup the dnsmasq domain.
                dnsDomain := n.config["dns.domain"]
                if dnsDomain == "" {
                        dnsDomain = "lxd"
@@ -1167,12 +1167,12 @@ func (n *bridge) setup(oldConfig map[string]string) 
error {
                }
                dnsmasqCmd = append(dnsmasqCmd, fmt.Sprintf("--conf-file=%s", 
shared.VarPath("networks", n.name, "dnsmasq.raw")))
 
-               // Attempt to drop privileges
+               // Attempt to drop privileges.
                if n.state.OS.UnprivUser != "" {
                        dnsmasqCmd = append(dnsmasqCmd, []string{"-u", 
n.state.OS.UnprivUser}...)
                }
 
-               // Create DHCP hosts directory
+               // Create DHCP hosts directory.
                if !shared.PathExists(shared.VarPath("networks", n.name, 
"dnsmasq.hosts")) {
                        err = os.MkdirAll(shared.VarPath("networks", n.name, 
"dnsmasq.hosts"), 0755)
                        if err != nil {
@@ -1180,13 +1180,13 @@ func (n *bridge) setup(oldConfig map[string]string) 
error {
                        }
                }
 
-               // Check for dnsmasq
+               // Check for dnsmasq.
                _, err := exec.LookPath("dnsmasq")
                if err != nil {
                        return fmt.Errorf("dnsmasq is required for LXD managed 
bridges")
                }
 
-               // Update the static leases
+               // Update the static leases.
                err = UpdateDNSMasqStatic(n.state, n.name)
                if err != nil {
                        return err
@@ -1213,7 +1213,7 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
 
                err = p.Save(shared.VarPath("networks", n.name, "dnsmasq.pid"))
                if err != nil {
-                       // Kill Process if started, but could not save the file
+                       // Kill Process if started, but could not save the file.
                        err2 := p.Stop()
                        if err != nil {
                                return fmt.Errorf("Could not kill subprocess 
while handling saving error: %s: %s", err, err2)
@@ -1222,9 +1222,9 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                        return fmt.Errorf("Failed to save subprocess details: 
%s", err)
                }
 
-               // Spawn DNS forwarder if needed (backgrounded to avoid 
deadlocks during cluster boot)
+               // Spawn DNS forwarder if needed (backgrounded to avoid 
deadlocks during cluster boot).
                if dnsClustered {
-                       // Create forkdns servers directory
+                       // Create forkdns servers directory.
                        if !shared.PathExists(shared.VarPath("networks", 
n.name, ForkdnsServersListPath)) {
                                err = os.MkdirAll(shared.VarPath("networks", 
n.name, ForkdnsServersListPath), 0755)
                                if err != nil {
@@ -1232,7 +1232,7 @@ func (n *bridge) setup(oldConfig map[string]string) error 
{
                                }
                        }
 
-                       // Create forkdns servers.conf file if doesn't exist
+                       // Create forkdns servers.conf file if doesn't exist.
                        f, err := os.OpenFile(shared.VarPath("networks", 
n.name, ForkdnsServersListPath+"/"+ForkdnsServersListFile), 
os.O_RDONLY|os.O_CREATE, 0666)
                        if err != nil {
                                return err

From 785d1230c77659d80205816f020e7d512443ab97 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 23 Jul 2020 14:48:49 +0100
Subject: [PATCH 3/7] lxd/network/network/interface: fillConfig signature

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

diff --git a/lxd/network/network_interface.go b/lxd/network/network_interface.go
index 1a558b380d..cedb68ef31 100644
--- a/lxd/network/network_interface.go
+++ b/lxd/network/network_interface.go
@@ -10,7 +10,7 @@ import (
 type Network interface {
        // Load.
        init(state *state.State, id int64, name string, netType string, 
description string, config map[string]string, status string)
-       fillConfig(*api.NetworksPost) error
+       fillConfig(config map[string]string) error
 
        // Config.
        Validate(config map[string]string) error

From 3955e2a5b2c6041c30d073c5dbb992c89b74360f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 23 Jul 2020 14:49:07 +0100
Subject: [PATCH 4/7] lxd/network/driver/common: Updates fillConfig signature

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

diff --git a/lxd/network/driver_common.go b/lxd/network/driver_common.go
index b79735c336..bc26dcaed3 100644
--- a/lxd/network/driver_common.go
+++ b/lxd/network/driver_common.go
@@ -51,7 +51,7 @@ func (n *common) init(state *state.State, id int64, name 
string, netType string,
 }
 
 // fillConfig fills requested config with any default values, by default this 
is a no-op.
-func (n *common) fillConfig(req *api.NetworksPost) error {
+func (n *common) fillConfig(config map[string]string) error {
        return nil
 }
 

From 040a26c8b528b405f55a0157601023a91e13d725 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 23 Jul 2020 14:54:12 +0100
Subject: [PATCH 5/7] lxd/network/driver/bridge: Updates fillConfig signature

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

diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go
index d9f5c49c7b..373984f194 100644
--- a/lxd/network/driver_bridge.go
+++ b/lxd/network/driver_bridge.go
@@ -44,30 +44,30 @@ type bridge struct {
 }
 
 // fillConfig fills requested config with any default values.
-func (n *bridge) fillConfig(req *api.NetworksPost) error {
+func (n *bridge) fillConfig(config map[string]string) error {
        // Set some default values where needed.
-       if req.Config["bridge.mode"] == "fan" {
-               if req.Config["fan.underlay_subnet"] == "" {
-                       req.Config["fan.underlay_subnet"] = "auto"
+       if config["bridge.mode"] == "fan" {
+               if config["fan.underlay_subnet"] == "" {
+                       config["fan.underlay_subnet"] = "auto"
                }
        } else {
-               if req.Config["ipv4.address"] == "" {
-                       req.Config["ipv4.address"] = "auto"
+               if config["ipv4.address"] == "" {
+                       config["ipv4.address"] = "auto"
                }
 
-               if req.Config["ipv4.address"] == "auto" && 
req.Config["ipv4.nat"] == "" {
-                       req.Config["ipv4.nat"] = "true"
+               if config["ipv4.address"] == "auto" && config["ipv4.nat"] == "" 
{
+                       config["ipv4.nat"] = "true"
                }
 
-               if req.Config["ipv6.address"] == "" {
+               if config["ipv6.address"] == "" {
                        content, err := 
ioutil.ReadFile("/proc/sys/net/ipv6/conf/default/disable_ipv6")
                        if err == nil && string(content) == "0\n" {
-                               req.Config["ipv6.address"] = "auto"
+                               config["ipv6.address"] = "auto"
                        }
                }
 
-               if req.Config["ipv6.address"] == "auto" && 
req.Config["ipv6.nat"] == "" {
-                       req.Config["ipv6.nat"] = "true"
+               if config["ipv6.address"] == "auto" && config["ipv6.nat"] == "" 
{
+                       config["ipv6.nat"] = "true"
                }
        }
 

From 93d4f48504ea45bcb40088c8dbc6249da94cecd8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 23 Jul 2020 14:49:25 +0100
Subject: [PATCH 6/7] lxd/network/network/load: Updates FillConfig to use new
 signature

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

diff --git a/lxd/network/network_load.go b/lxd/network/network_load.go
index 8638987cfd..0990e30662 100644
--- a/lxd/network/network_load.go
+++ b/lxd/network/network_load.go
@@ -56,7 +56,7 @@ func FillConfig(req *api.NetworksPost) error {
        n := driverFunc()
        n.init(nil, 0, req.Name, req.Type, req.Description, req.Config, 
"Unknown")
 
-       err := n.fillConfig(req)
+       err := n.fillConfig(req.Config)
        if err != nil {
                return err
        }

From ff5b56a32f7d5f22bfc8777987daad20afa6cb01 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 23 Jul 2020 14:56:56 +0100
Subject: [PATCH 7/7] lxd/network/driver/bridge: Fixes Update to regenerate
 default values if missing

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

diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go
index 373984f194..2ba456aae3 100644
--- a/lxd/network/driver_bridge.go
+++ b/lxd/network/driver_bridge.go
@@ -1343,15 +1343,14 @@ func (n *bridge) Stop() error {
 func (n *bridge) Update(newNetwork api.NetworkPut, targetNode string, 
clusterNotification bool) error {
        n.logger.Debug("Update", log.Ctx{"clusterNotification": 
clusterNotification, "newNetwork": newNetwork})
 
-       // When switching to a fan bridge, auto-detect the underlay if not 
specified.
-       if newNetwork.Config["bridge.mode"] == "fan" {
-               if newNetwork.Config["fan.underlay_subnet"] == "" {
-                       newNetwork.Config["fan.underlay_subnet"] = "auto"
-               }
+       // Populate default values if they are missing.
+       err := n.fillConfig(newNetwork.Config)
+       if err != nil {
+               return err
        }
 
        // Populate auto fields.
-       err := fillAuto(newNetwork.Config)
+       err = fillAuto(newNetwork.Config)
        if err != nil {
                return err
        }
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to