[lxc-devel] [lxd/master] test/suites/static/analysis: Fixes ineffassign usage due to upstream changes
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8299 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) === Caused by https://github.com/gordonklaus/ineffassign/commit/664217a59c00a74b4491898ca757d3f711fff321 Signed-off-by: Thomas Parrott From ca4b23fa20e7a2219ccd191bb9419bf73584b5a3 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 4 Jan 2021 16:54:44 + Subject: [PATCH] test/suites/static/analysis: Fixes ineffassign usage due to upstream changes Caused by https://github.com/gordonklaus/ineffassign/commit/664217a59c00a74b4491898ca757d3f711fff321 Signed-off-by: Thomas Parrott --- test/suites/static_analysis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/suites/static_analysis.sh b/test/suites/static_analysis.sh index 3fd192bd1c..699a2e6d13 100644 --- a/test/suites/static_analysis.sh +++ b/test/suites/static_analysis.sh @@ -161,7 +161,7 @@ test_static_analysis() { ## ineffassign if which ineffassign >/dev/null 2>&1; then - ineffassign ./ + ineffassign ./... fi # Skip the tests which require git ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] QMP: Fix race in Disconnect
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8298 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) === Can end up calling close() on the chDisconnect channel multiple times if called concurrently. Fixes #8294 Signed-off-by: Thomas Parrott From 32fbbdcc9ddd9738b1eff6935e496d2d31ff6da1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 4 Jan 2021 14:53:24 + Subject: [PATCH] lxd/instance/drivers/qmp: Fix race in Disconnect Can end up calling close() on the chDisconnect channel multiple times if called concurrently. Fixes #8294 Signed-off-by: Thomas Parrott --- lxd/instance/drivers/qmp/monitor.go | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lxd/instance/drivers/qmp/monitor.go b/lxd/instance/drivers/qmp/monitor.go index 00d2453ad0..72950e093c 100644 --- a/lxd/instance/drivers/qmp/monitor.go +++ b/lxd/instance/drivers/qmp/monitor.go @@ -171,16 +171,17 @@ func (m *Monitor) Wait() (chan struct{}, error) { // Disconnect forces a disconnection from QEMU. func (m *Monitor) Disconnect() { + // Remove from the map. + monitorsLock.Lock() + defer monitorsLock.Unlock() + // Stop all go routines and disconnect from socket. if !m.disconnected { close(m.chDisconnect) + m.disconnected = true + m.qmp.Disconnect() } - m.disconnected = true - m.qmp.Disconnect() - // Remove from the map. - monitorsLock.Lock() - defer monitorsLock.Unlock() delete(monitors, m.path) } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Make OVN updates more nuanced and less destructive
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8276 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) === Don't tear down all OVN config and rebuild, instead try and apply only changes, so as to reduce impact on instance port config. From cba9502715754f6ae05cfa8bb4a4dae4e62c8465 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 11:45:16 + Subject: [PATCH 01/16] lxd/network/openvswitch/ovn: Adds mayExist argument to LogicalRouterAdd Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovn.go | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go index d7ad3079ee..86625846c2 100644 --- a/lxd/network/openvswitch/ovn.go +++ b/lxd/network/openvswitch/ovn.go @@ -125,8 +125,14 @@ func (o *OVN) nbctl(args ...string) (string, error) { } // LogicalRouterAdd adds a named logical router. -func (o *OVN) LogicalRouterAdd(routerName OVNRouter) error { - _, err := o.nbctl("lr-add", string(routerName)) +func (o *OVN) LogicalRouterAdd(routerName OVNRouter, mayExist bool) error { + args := []string{} + + if mayExist { + args = append(args, "--may-exist") + } + + _, err := o.nbctl(append(args, "lr-add", string(routerName))...) if err != nil { return err } From a67d1ed533580a1e7829ca9afd7a99363eba4ce4 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 11:46:13 + Subject: [PATCH 02/16] lxd/network/openvswitch/ovn: Adds mayExist argument to LogicalRouterSNATAdd Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovn.go | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go index 86625846c2..f529d39394 100644 --- a/lxd/network/openvswitch/ovn.go +++ b/lxd/network/openvswitch/ovn.go @@ -151,8 +151,14 @@ func (o OVN) LogicalRouterDelete(routerName OVNRouter) error { } // LogicalRouterSNATAdd adds an SNAT rule to a logical router to translate packets from intNet to extIP. -func (o *OVN) LogicalRouterSNATAdd(routerName OVNRouter, intNet *net.IPNet, extIP net.IP) error { - _, err := o.nbctl("lr-nat-add", string(routerName), "snat", extIP.String(), intNet.String()) +func (o *OVN) LogicalRouterSNATAdd(routerName OVNRouter, intNet *net.IPNet, extIP net.IP, mayExist bool) error { + args := []string{} + + if mayExist { + args = append(args, "--may-exist") + } + + _, err := o.nbctl(append(args, "lr-nat-add", string(routerName), "snat", extIP.String(), intNet.String())...) if err != nil { return err } From 94fdc43a5e424d0a9ec4d35e70f12af2a1a5dd65 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 11:46:41 + Subject: [PATCH 03/16] lxd/network/openvswitch/ovn: Simplifies LogicalRouterRouteAdd Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovn.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go index f529d39394..fa6a409b6c 100644 --- a/lxd/network/openvswitch/ovn.go +++ b/lxd/network/openvswitch/ovn.go @@ -204,8 +204,7 @@ func (o *OVN) LogicalRouterRouteAdd(routerName OVNRouter, destination *net.IPNet args = append(args, "--may-exist") } - args = append(args, "lr-route-add", string(routerName), destination.String(), nextHop.String()) - _, err := o.nbctl(args...) + _, err := o.nbctl(append(args, "lr-route-add", string(routerName), destination.String(), nextHop.String())...) if err != nil { return err } From e47204f3c35bc466639591ff1b13d6302e4d6a21 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 11:46:57 + Subject: [PATCH 04/16] lxd/network/openvswitch/ovn: Adds mayExist argument to LogicalRouterPortAdd Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovn.go | 24 +++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go index fa6a409b6c..f4bd7f186f 100644 --- a/lxd/network/openvswitch/ovn.go +++ b/lxd/network/openvswitch/ovn.go @@ -230,7 +230,29 @@ func (o *OVN) LogicalRouterRouteDelete(routerName OVNRouter, destination *net.IP } // LogicalRouterPortAdd adds a named logical router port to a logical router. -func (o *OVN) LogicalRouterPortAdd(routerName OVNRouter, portName OVNRouterPort, mac net.HardwareAddr, ipAddr ...*net.IPNet) error { +func (o *OVN) LogicalRouterPortAdd(routerName OVNRouter, portName OVNRouterPort, mac net.HardwareAddr, ipAddr []*net.IPNet, mayExist bool) error { + if mayExist { +
[lxc-devel] [lxd/master] Instance: Fix copying snapshot to new instance in different project
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8275 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) === Fixes https://github.com/lxc/lxd/issues/8273 Adds test for this scenario. From 954eadfa158f37860127f06422658a6d73ced0a0 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 14:02:06 + Subject: [PATCH 1/5] lxd/instances/post: Use source.Project when loading instance to get instance type in containersPost Fixes #8273 Signed-off-by: Thomas Parrott --- lxd/instances_post.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/instances_post.go b/lxd/instances_post.go index 92047db448..e10f4d79e1 100644 --- a/lxd/instances_post.go +++ b/lxd/instances_post.go @@ -838,7 +838,7 @@ func containersPost(d *Daemon, r *http.Request) response.Response { return fmt.Errorf("Must specify a source instance") } - source, err := instance.LoadInstanceDatabaseObject(tx, project, req.Source.Source) + source, err := instance.LoadInstanceDatabaseObject(tx, req.Source.Project, req.Source.Source) if err != nil { return errors.Wrap(err, "Load source instance from database") } From 48df8c87eef5e4e106d1f8f740464773541d9233 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 14:06:24 + Subject: [PATCH 2/5] lxd/instances/post: Rename project to targetProject to differentiate between source.Project in containersPost Signed-off-by: Thomas Parrott --- lxd/instances_post.go | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lxd/instances_post.go b/lxd/instances_post.go index e10f4d79e1..edc32e78ba 100644 --- a/lxd/instances_post.go +++ b/lxd/instances_post.go @@ -722,12 +722,12 @@ func createFromBackup(d *Daemon, projectName string, data io.Reader, pool string } func containersPost(d *Daemon, r *http.Request) response.Response { - project := projectParam(r) + targetProject := projectParam(r) logger.Debugf("Responding to instance create") // If we're getting binary content, process separately if r.Header.Get("Content-Type") == "application/octet-stream" { - return createFromBackup(d, project, r.Body, r.Header.Get("X-LXD-pool"), r.Header.Get("X-LXD-name")) + return createFromBackup(d, targetProject, r.Body, r.Header.Get("X-LXD-pool"), r.Header.Get("X-LXD-name")) } // Parse the request @@ -754,7 +754,7 @@ func containersPost(d *Daemon, r *http.Request) response.Response { // the selected node is the local one, this is effectively a // no-op, since GetNodeWithLeastInstances() will return an empty // string. - architectures, err := instance.SuitableArchitectures(d.State(), project, req) + architectures, err := instance.SuitableArchitectures(d.State(), targetProject, req) if err != nil { return response.BadRequest(err) } @@ -780,7 +780,7 @@ func containersPost(d *Daemon, r *http.Request) response.Response { return response.SmartError(err) } - client = client.UseProject(project) + client = client.UseProject(targetProject) client = client.UseTarget(targetNode) logger.Debugf("Forward instance post request to %s", address) @@ -790,7 +790,7 @@ func containersPost(d *Daemon, r *http.Request) response.Response { } opAPI := op.Get() - return operations.ForwardedOperationResponse(project, ) + return operations.ForwardedOperationResponse(targetProject, ) } } @@ -849,13 +849,13 @@ func containersPost(d *Daemon, r *http.Request) response.Response { } } - err := projecthelpers.AllowInstanceCreation(tx, project, req) + err := projecthelpers.AllowInstanceCreation(tx, targetProject, req) if err != nil { return err } if req.Name == "" { - names, err := tx.GetInstanceNames(project) + names, err := tx.GetInstanceNames(targetProject) if err != nil { return err } @@ -883,13 +883,13 @@ func containersPost(d *Daemon, r *http.Request) response.Response {
[lxc-devel] [lxd/master] Storage: Fix snapshot remove subsequent
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8274 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) === When setting `volume.zfs.remove_snapshots=true` on a ZFS storage pool, this fixes several issues: - The wrong snapshot was being checked for deletion suitability (resulting in not deleting any snapshots). - Once that was fixed, there was also an issue with only the storage volume and storage volume DB record of the snapshot being deleted, not the instance snapshot record as well. Leaving orphaned snapshots in `lxc info ` output and preventing deletion of instance (because snapshot volume DB record had been removed). - Because of the scope of the `err` being returned, it was likely that as a new `err` was created inside the subsequent snapshot deletion block, that the original error would be returned even on successful restore. Added `return nil` after successful restore. - Modified `DeleteInstanceSnapshot` to not fail if the storage volume DB record has already been removed (as that is the desired result anyway). Fixes https://discuss.linuxcontainers.org/t/snapshot-c1-20201218-03-cannot-be-restored-due-to-subsequent-snapshot-s-set-zfs-remove-snapshots-to-override/9742 From 35398d973bb5e87d12a40fe46449a7da849c7f7d Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 12:13:10 + Subject: [PATCH 1/3] lxd/storage/drivers/driver/zfs/volumes: Error quoting in RestoreVolume Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_zfs_volumes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage/drivers/driver_zfs_volumes.go b/lxd/storage/drivers/driver_zfs_volumes.go index 29e38998d8..cec417f814 100644 --- a/lxd/storage/drivers/driver_zfs_volumes.go +++ b/lxd/storage/drivers/driver_zfs_volumes.go @@ -1788,14 +1788,14 @@ func (d *zfs) RestoreVolume(vol Volume, snapshotName string, op *operations.Oper if strings.HasPrefix(entry, "@") { // Located an internal snapshot. - return fmt.Errorf("Snapshot '%s' cannot be restored due to subsequent internal snapshot(s) (from a copy)", snapshotName) + return fmt.Errorf("Snapshot %q cannot be restored due to subsequent internal snapshot(s) (from a copy)", snapshotName) } } // Check if snapshot removal is allowed. if len(snapshots) > 0 { if !shared.IsTrue(vol.ExpandedConfig("zfs.remove_snapshots")) { - return fmt.Errorf("Snapshot '%s' cannot be restored due to subsequent snapshot(s). Set zfs.remove_snapshots to override", snapshotName) + return fmt.Errorf("Snapshot %q cannot be restored due to subsequent snapshot(s). Set zfs.remove_snapshots to override", snapshotName) } // Setup custom error to tell the backend what to delete. From 4efdfbc4fc20fdca860f99e9ac55d0948c3bd8ca Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 12:13:35 + Subject: [PATCH 2/3] lxd/storage/backend/lxd: Don't fail in DeleteInstanceSnapshot if volume DB record already deleted Signed-off-by: Thomas Parrott --- lxd/storage/backend_lxd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 2ca935dc0c..8d3358b2ca 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -1996,9 +1996,9 @@ func (b *lxdBackend) DeleteInstanceSnapshot(inst instance.Instance, op *operatio return err } - // Remove the snapshot volume record from the database. + // Remove the snapshot volume record from the database if exists. err = b.state.Cluster.RemoveStoragePoolVolume(inst.Project(), drivers.GetSnapshotVolumeName(parentName, snapName), volDBType, b.ID()) - if err != nil { + if err != nil && err != db.ErrNoSuchObject { return err } From 841fcd1491216e470944a6c087a2e6fb61988e30 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 18 Dec 2020 12:14:16 + Subject: [PATCH 3/3] lxd/storage/backend/lxd: Fix deleting subsequent snapshots for ZFS in RestoreInstanceSnapshot Signed-off-by: Thomas Parrott --- lxd/storage/backend_lxd.go | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 8d3358b2ca..09ff3c95c5 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -2064,23 +2064,25 @@ func (b *lxdBackend) RestoreInstanceSnapshot(inst instance.Instance, src instanc // Go through all the snapshots. for _, snap := range snaps { - _, snapName, _ :=
[lxc-devel] [lxc-ci/master] bin/test-lxd-ovn: Fix tests in environments with multiple bridges
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/225 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) === Signed-off-by: Thomas Parrott From 1ae71ffa80b1dc5fd59e598ee9b67f50db69b620 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 17 Dec 2020 23:32:28 + Subject: [PATCH] bin/test-lxd-ovn: Fix tests in environments with multiple bridges Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index 1788d7f..e254c4c 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -397,7 +397,7 @@ lxc network create dummy --type=physical \ ipv6.gateway=2001:db8:1:1::1/64 \ ipv4.ovn.ranges=192.0.2.10-192.0.2.19 lxc network create ovn-virtual-network --type=ovn network=dummy -bridge link show dev dummybr0 | wc -l | grep 1 # Check we have one port connected to the uplink bridge. +bridge link show | grep dummybr0 | wc -l | grep 1 # Check we have one port connected to the uplink bridge. ovs-vsctl list-br | grep ovn | wc -l | grep 1 # Check we have one OVS bridge. ovnIPv4="$(lxc network get ovn-virtual-network volatile.network.ipv4.address)" ovnIPv6="$(lxc network get ovn-virtual-network volatile.network.ipv6.address)" @@ -405,7 +405,7 @@ ping -c1 -4 "${ovnIPv4}" # Check IPv4 connectivity over dummy bridge to OVN rout ping -c1 -6 "${ovnIPv6}" # Check IPv6 connectivity over dummy bridge to OVN router. lxc network delete ovn-virtual-network lxc network delete dummy -bridge link show dev dummybr0 | wc -l | grep 0 # Check the port is removed from the uplink bridge. +bridge link show | grep dummybr0 | wc -l | grep 0 # Check the port is removed from the uplink bridge. ovs-vsctl list-br | grep ovn | wc -l | grep 0 # Check the OVS bridge is removed. ip link delete dummybr0 # Remove dummy uplink bridge. ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Device: Improves readability of disk device validation
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8270 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) === Implements suggestion from https://github.com/lxc/lxd/pull/8161#discussion_r524643693 From 354df8872444809406ccfd14bff49401b07e52de Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 17 Dec 2020 15:08:34 + Subject: [PATCH 1/6] lxd/db/cluster/update: Modifies updateFromV43 and updateFromV42 to use IFNULL(node_id, -1) to avoid nodes with 0 ID Signed-off-by: Thomas Parrott --- lxd/db/cluster/update.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go index 614f4845a9..9dbf256818 100644 --- a/lxd/db/cluster/update.go +++ b/lxd/db/cluster/update.go @@ -88,7 +88,7 @@ var updates = map[int]schema.Update{ // This can occur when multiple create requests have been issued when setting up a clustered storage pool. func updateFromV42(tx *sql.Tx) error { // Find all duplicated config rows and return comma delimited list of affected row IDs for each dupe set. - stmt, err := tx.Prepare(`SELECT storage_pool_id, COALESCE(node_id,0), key, value, COUNT(*) AS rowCount, GROUP_CONCAT(id, ",") AS dupeRowIDs + stmt, err := tx.Prepare(`SELECT storage_pool_id, IFNULL(node_id, -1), key, value, COUNT(*) AS rowCount, GROUP_CONCAT(id, ",") AS dupeRowIDs FROM storage_pools_config GROUP BY storage_pool_id, node_id, key, value HAVING rowCount > 1 @@ -157,7 +157,7 @@ func updateFromV42(tx *sql.Tx) error { // This can occur when multiple create requests have been issued when setting up a clustered network. func updateFromV41(tx *sql.Tx) error { // Find all duplicated config rows and return comma delimited list of affected row IDs for each dupe set. - stmt, err := tx.Prepare(`SELECT network_id, COALESCE(node_id,0), key, value, COUNT(*) AS rowCount, GROUP_CONCAT(id, ",") AS dupeRowIDs + stmt, err := tx.Prepare(`SELECT network_id, IFNULL(node_id, -1), key, value, COUNT(*) AS rowCount, GROUP_CONCAT(id, ",") AS dupeRowIDs FROM networks_config GROUP BY network_id, node_id, key, value HAVING rowCount > 1 From 245c92e80fa301ee429ec700aa800d97e357ff30 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 17 Dec 2020 14:55:57 + Subject: [PATCH 2/6] lxd/db/cluster: Adds updateFromV43 patch that adds unique index to storage_pools_config and networks_config table Prevents duplicate config rows for the same node and key being inserted. Fixes #8260 Signed-off-by: Thomas Parrott --- lxd/db/cluster/schema.go | 4 +++- lxd/db/cluster/update.go | 13 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go index 897ea06d22..c0165dd17c 100644 --- a/lxd/db/cluster/schema.go +++ b/lxd/db/cluster/schema.go @@ -304,6 +304,7 @@ CREATE TABLE "networks_nodes" ( FOREIGN KEY (network_id) REFERENCES "networks" (id) ON DELETE CASCADE, FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE ); +CREATE UNIQUE INDEX networks_unique_network_id_node_id_key ON networks_config (network_id, IFNULL(node_id, -1), key); CREATE TABLE nodes ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, @@ -495,6 +496,7 @@ CREATE TABLE storage_pools_nodes ( FOREIGN KEY (storage_pool_id) REFERENCES storage_pools (id) ON DELETE CASCADE, FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE ); +CREATE UNIQUE INDEX storage_pools_unique_storage_pool_id_node_id_key ON storage_pools_config (storage_pool_id, IFNULL(node_id, -1), key); CREATE TABLE "storage_volumes" ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, @@ -591,5 +593,5 @@ CREATE TABLE storage_volumes_snapshots_config ( UNIQUE (storage_volume_snapshot_id, key) ); -INSERT INTO schema (version, updated_at) VALUES (43, strftime("%s")) +INSERT INTO schema (version, updated_at) VALUES (44, strftime("%s")) ` diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go index 9dbf256818..a64fefc1a7 100644 --- a/lxd/db/cluster/update.go +++ b/lxd/db/cluster/update.go @@ -82,6 +82,19 @@ var updates = map[int]schema.Update{ 41: updateFromV40, 42: updateFromV41, 43: updateFromV42, + 44: updateFromV43, +} + +// updateFromV43 adds a unique index to the storage_pools_config and networks_config tables. +func updateFromV43(tx *sql.Tx) error { + _, err := tx.Exec(`CREATE UNIQUE INDEX storage_pools_unique_storage_pool_id_node_id_key ON storage_pools_config (storage_pool_id, IFNULL(node_id, -1), key); + CREATE UNIQUE INDEX networks_unique_network_id_node_id_key ON
[lxc-devel] [lxd/master] DB: Adds updateFromV43 patch that adds unique index to storage_pools_config and networks_config table
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8268 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) === Prevents duplicate config rows for the same node and key being inserted. Uses `ifnull(node_id,-1)` to ensure unique index is still enforced for non-node specific config keys where node_id is NULL, and uses `-1` as the pseudo value in order to avoid issues where the node ID is genuinely `0` which @stgraber advises is potentially possible on DBs from older installations. Fixes #8260 Signed-off-by: Thomas Parrott From b1b875018f7954b51057492962b0882136665b68 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 17 Dec 2020 14:55:57 + Subject: [PATCH] lxd/db/cluster: Adds updateFromV43 patch that adds unique index to storage_pools_config and networks_config table Prevents duplicate config rows for the same node and key being inserted. Fixes #8260 Signed-off-by: Thomas Parrott --- lxd/db/cluster/schema.go | 4 +++- lxd/db/cluster/update.go | 13 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go index 897ea06d22..ca5d4d448e 100644 --- a/lxd/db/cluster/schema.go +++ b/lxd/db/cluster/schema.go @@ -276,6 +276,7 @@ CREATE VIEW instances_snapshots_devices_ref ( JOIN instances ON instances.id=instances_snapshots.instance_id JOIN projects ON projects.id=instances.project_id JOIN instances_snapshots ON instances_snapshots.id=instances_snapshots_devices.instance_snapshot_id; +CREATE UNIQUE INDEX network_id_node_id_key ON networks_config (network_id,ifnull(node_id, -1),key); CREATE TABLE "networks" ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, project_id INTEGER NOT NULL, @@ -468,6 +469,7 @@ CREATE VIEW projects_used_by_ref (name, networks.name, projects.name) FROM networks JOIN projects ON project_id=projects.id; +CREATE UNIQUE INDEX storage_pool_id_node_id_key ON storage_pools_config (storage_pool_id,ifnull(node_id, -1),key); CREATE TABLE storage_pools ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, @@ -591,5 +593,5 @@ CREATE TABLE storage_volumes_snapshots_config ( UNIQUE (storage_volume_snapshot_id, key) ); -INSERT INTO schema (version, updated_at) VALUES (43, strftime("%s")) +INSERT INTO schema (version, updated_at) VALUES (44, strftime("%s")) ` diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go index 614f4845a9..e4f13e077a 100644 --- a/lxd/db/cluster/update.go +++ b/lxd/db/cluster/update.go @@ -82,6 +82,19 @@ var updates = map[int]schema.Update{ 41: updateFromV40, 42: updateFromV41, 43: updateFromV42, + 44: updateFromV43, +} + +// updateFromV43 adds a unique index to the storage_pools_config and networks_config tables. +func updateFromV43(tx *sql.Tx) error { + _, err := tx.Exec(`CREATE UNIQUE INDEX storage_pool_id_node_id_key ON storage_pools_config (storage_pool_id,ifnull(node_id, -1),key);; + CREATE UNIQUE INDEX network_id_node_id_key ON networks_config (network_id,ifnull(node_id, -1),key);; + `) + if err != nil { + return errors.Wrapf(err, "Failed adding unique index to storage_pools_config and networks_config tables") + } + + return nil } // updateFromV42 removes any duplicated storage pool config rows that have the same value. ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/stable-4.0] Network: Don't apply update changes to node when network is pending
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8267 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) === And don't allow re-create attempts on errored networks, as we don't track per-node state and so cannot tell which nodes have successfully been setup and which ones haven't. So the only valid approach is to require the user to delete and start again. From ae88adbb97e31c12e6b5ac569ffe539372c3229c Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 17 Dec 2020 09:23:21 + Subject: [PATCH 1/2] lxd/networks: Prevent re-create attempts on errored networks This is because the stable-4.0 branch does not have per-node state and so we cannot track which nodes have been successfully setup and which are still pending. Signed-off-by: Thomas Parrott --- lxd/networks.go | 6 ++ 1 file changed, 6 insertions(+) diff --git a/lxd/networks.go b/lxd/networks.go index 03acf7aac3..cdf15b2386 100644 --- a/lxd/networks.go +++ b/lxd/networks.go @@ -203,6 +203,12 @@ func networksPost(d *Daemon, r *http.Request) response.Response { return response.InternalError(err) } + // If the network has previously had a create attempt that failed, then because we cannot track per-node + // status, we need to prevent any further create attempts and require the user to delete and re-create. + if netInfo != nil && netInfo.Status == api.NetworkStatusErrored { + return response.BadRequest(fmt.Errorf("Network is in errored state, please delete and re-create")) + } + // Check if we're clustered. count, err := cluster.Count(d.State()) if err != nil { From 642de5bf4f34b888f44f762f88a16cfeb8419ba2 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 17 Dec 2020 09:25:43 + Subject: [PATCH 2/2] lxd/network/driver/bridge: Don't apply updates to node when network is pending If no network create attempt has been attempted then we should just update the DB and await the global create attempt. Signed-off-by: Thomas Parrott --- lxd/network/driver_bridge.go | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go index 74d3e107e3..c55644cced 100644 --- a/lxd/network/driver_bridge.go +++ b/lxd/network/driver_bridge.go @@ -1497,8 +1497,10 @@ func (n *bridge) Update(newNetwork api.NetworkPut, targetNode string, clientType return nil // Nothing changed. } - if n.LocalStatus() == api.NetworkStatusPending { - // Apply DB change to local node only. + // If the network as a whole has not had any previous creation attempts, or the node itself is still + // pending, then don't apply the new settings to the node, just to the database record (ready for the + // actual global create request to be initiated). + if n.Status() == api.NetworkStatusPending || n.LocalStatus() == api.NetworkStatusPending { return n.common.update(newNetwork, targetNode, clientType) } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Don't apply node changes when network is in pending state
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8266 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) === Only apply to DB. This is a commit from the stable-4.0 branch ported to the master branch for the bridge driver, and then a subsequent commit to align the non-stable-4.0 drivers with the bridge driver. From 5409511b8014938594684d4d5625a31e6f1415ed Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 17 Dec 2020 09:25:43 + Subject: [PATCH 1/2] lxd/network/driver/bridge: Don't apply updates to node when network is pending If no network create attempt has been attempted then we should just update the DB and await the global create attempt. Signed-off-by: Thomas Parrott --- lxd/network/driver_bridge.go | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go index a733e5afc1..440b97dc35 100644 --- a/lxd/network/driver_bridge.go +++ b/lxd/network/driver_bridge.go @@ -1557,8 +1557,10 @@ func (n *bridge) Update(newNetwork api.NetworkPut, targetNode string, clientType return nil // Nothing changed. } - if n.LocalStatus() == api.NetworkStatusPending { - // Apply DB change to local node only. + // If the network as a whole has not had any previous creation attempts, or the node itself is still + // pending, then don't apply the new settings to the node, just to the database record (ready for the + // actual global create request to be initiated). + if n.Status() == api.NetworkStatusPending || n.LocalStatus() == api.NetworkStatusPending { return n.common.update(newNetwork, targetNode, clientType) } From f0a4beb75365d2e5e78ab596aa2602cc5edc5c66 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 17 Dec 2020 09:28:50 + Subject: [PATCH 2/2] lxd/network/driver: Don't apply changes to node if network is pending Aligns with 5409511b8 change for bridge driver from stable-4.0 branch. Signed-off-by: Thomas Parrott --- lxd/network/driver_macvlan.go | 6 -- lxd/network/driver_ovn.go | 6 -- lxd/network/driver_physical.go | 6 -- lxd/network/driver_sriov.go| 6 -- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lxd/network/driver_macvlan.go b/lxd/network/driver_macvlan.go index bba6d06369..7dededfd83 100644 --- a/lxd/network/driver_macvlan.go +++ b/lxd/network/driver_macvlan.go @@ -90,8 +90,10 @@ func (n *macvlan) Update(newNetwork api.NetworkPut, targetNode string, clientTyp return nil // Nothing changed. } - if n.LocalStatus() == api.NetworkStatusPending { - // Apply DB change to local node only. + // If the network as a whole has not had any previous creation attempts, or the node itself is still + // pending, then don't apply the new settings to the node, just to the database record (ready for the + // actual global create request to be initiated). + if n.Status() == api.NetworkStatusPending || n.LocalStatus() == api.NetworkStatusPending { return n.common.update(newNetwork, targetNode, clientType) } diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 3e68e6018d..db9b7366d2 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -2002,8 +2002,10 @@ func (n *ovn) Update(newNetwork api.NetworkPut, targetNode string, clientType re return nil // Nothing changed. } - if n.LocalStatus() == api.NetworkStatusPending { - // Apply DB change to local node only. + // If the network as a whole has not had any previous creation attempts, or the node itself is still + // pending, then don't apply the new settings to the node, just to the database record (ready for the + // actual global create request to be initiated). + if n.Status() == api.NetworkStatusPending || n.LocalStatus() == api.NetworkStatusPending { return n.common.update(newNetwork, targetNode, clientType) } diff --git a/lxd/network/driver_physical.go b/lxd/network/driver_physical.go index 173fbfc774..6c019c628b 100644 --- a/lxd/network/driver_physical.go +++ b/lxd/network/driver_physical.go @@ -232,8 +232,10 @@ func (n *physical) Update(newNetwork api.NetworkPut, targetNode string, clientTy return nil // Nothing changed. } - if n.LocalStatus() == api.NetworkStatusPending { - // Apply DB change to local node only. + // If the network as a whole has not had any previous creation attempts, or the node itself is still + // pending, then don't apply the new settings to the node, just to the database record (ready for the + // actual global
[lxc-devel] [lxd/master] Network: Clarify error when changing physical parent interface when in use
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8264 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) === Signed-off-by: Thomas Parrott From a6117fba820ee013e9c645f54078766b8466fe38 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 16 Dec 2020 16:54:26 + Subject: [PATCH] lxd/network/driver/physical: Clarify error when changing parent interface when in use Signed-off-by: Thomas Parrott --- lxd/network/driver_physical.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/network/driver_physical.go b/lxd/network/driver_physical.go index 51d5f16b8c..173fbfc774 100644 --- a/lxd/network/driver_physical.go +++ b/lxd/network/driver_physical.go @@ -247,7 +247,7 @@ func (n *physical) Update(newNetwork api.NetworkPut, targetNode string, clientTy if hostNameChanged { isUsed, err := n.IsUsed() if isUsed || err != nil { - return fmt.Errorf("Cannot update network host name when in use") + return fmt.Errorf("Cannot update network parent interface when in use") } inUse, err := n.checkParentUse(newNetwork.Config) ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxc-ci/master] bin/test-lxd-ovn: Adds tests for using a physical bridge uplink
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/219 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) === Signed-off-by: Thomas Parrott From 2a082c21078b1646928c5d6b19fdf32ed59e21d9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 16 Dec 2020 16:42:41 + Subject: [PATCH] bin/test-lxd-ovn: Adds tests for using a physical bridge uplink Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 45 + 1 file changed, 45 insertions(+) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index 2256cac..f1be7fa 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -385,6 +385,51 @@ lxc delete -f u2 u3 lxc network delete ovn-virtual-network lxc network delete lxdbr0 --project default +# Test physical uplinks using native bridge. +lxc project switch default +ip link add dummybr0 type bridge # Create dummy uplink bridge. +ip address add 192.0.2.1/24 dev dummybr0 +ip address add 2001:db8:1:1::1/64 dev dummybr0 +ip link set dummybr0 up +lxc network create dummy --type=physical \ +parent=dummybr0 \ +ipv4.gateway=192.0.2.1/24 \ +ipv6.gateway=2001:db8:1:1::1/64 \ +ipv4.ovn.ranges=192.0.2.10-192.0.2.19 +lxc network create ovn-virtual-network --type=ovn network=dummy +bridge link show dummybr0 | wc -l | grep 1 # Check we have one port connected to the uplink bridge. +ovs-vsctl list-br | grep ovn | wc -l | grep 1 # Check we have one OVS bridge. +ovnIPv4="$(lxc network get ovn-virtual-network volatile.network.ipv4.address)" +ovnIPv6="$(lxc network get ovn-virtual-network volatile.network.ipv6.address)" +ping -c1 -4 "${ovnIPv4}" # Check IPv4 connectivity over dummy bridge to OVN router. +ping -c1 -6 "${ovnIPv6}" # Check IPv6 connectivity over dummy bridge to OVN router. +lxc network delete ovn-virtual-network +lxc network delete dummy +bridge link show dummybr0 | wc -l | grep 0 # Check the port is removed from the uplink bridge. +ovs-vsctl list-br | grep ovn | wc -l | grep 0 # Check the OVS bridge is removed. +ip link delete dummybr0 # Remove dummy uplink bridge. + +# Test physical uplinks using OVS bridge. +ovs-vsctl add-br dummybr0 # Create dummy uplink bridge. +ip address add 192.0.2.1/24 dev dummybr0 +ip address add 2001:db8:1:1::1/64 dev dummybr0 +ip link set dummybr0 up +lxc network create dummy --type=physical \ +parent=dummybr0 \ +ipv4.gateway=192.0.2.1/24 \ +ipv6.gateway=2001:db8:1:1::1/64 \ +ipv4.ovn.ranges=192.0.2.10-192.0.2.19 +lxc network create ovn-virtual-network --type=ovn network=dummy +ovs-vsctl list-ports dummybr0 | grep patch-lxd-net | wc -l | grep 1 # Check bridge has an OVN patch port connected. +ovnIPv4="$(lxc network get ovn-virtual-network volatile.network.ipv4.address)" +ovnIPv6="$(lxc network get ovn-virtual-network volatile.network.ipv6.address)" +ping -c1 -4 "${ovnIPv4}" # Check IPv4 connectivity over dummy bridge to OVN router. +ping -c1 -6 "${ovnIPv6}" # Check IPv6 connectivity over dummy bridge to OVN router. +lxc network delete ovn-virtual-network +lxc network delete dummy +ovs-vsctl list-ports dummybr0 | grep patch-lxd-net | wc -l | grep 0 # Check bridge has no OVN patch port connected. +ovs-vsctl del-br dummybr0 # Remove dummy uplink bridge. + lxc image delete "${FINGERPRINT}" --project testovn lxc image delete "${FINGERPRINT}" --project default lxc profile device remove default root --project testovn ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] DB: Corrects comment on GetCreatedNetworks
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8263 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) === Signed-off-by: Thomas Parrott From c83abda1839a80b74b60d6a238b7e84968fd0eea Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 16 Dec 2020 15:55:53 + Subject: [PATCH] lxd/db/networks: Corrects comment on GetCreatedNetworks Signed-off-by: Thomas Parrott --- lxd/db/networks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/db/networks.go b/lxd/db/networks.go index be30549ed8..bca1e1ea4f 100644 --- a/lxd/db/networks.go +++ b/lxd/db/networks.go @@ -422,7 +422,7 @@ func (c *Cluster) GetNetworks(project string) ([]string, error) { return c.networks(project, "") } -// GetCreatedNetworks returns the names of all networks that are not in state networkCreated. +// GetCreatedNetworks returns the names of all networks that are in state networkCreated. func (c *Cluster) GetCreatedNetworks(project string) ([]string, error) { return c.networks(project, "state=?", networkCreated) } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxc-ci/master] bin/test-lxd-ovn: Check DHCP can be disabled selectively and instances can still start
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/218 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) === Signed-off-by: Thomas Parrott From b4b698ccb02d0626b48563734fe9f45a8afd095a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 16 Dec 2020 14:16:29 + Subject: [PATCH] bin/test-lxd-ovn: Check DHCP can be disabled selectively and instances can still start Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index 6d904dc..d622cae 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -272,7 +272,28 @@ lxc network set ovn-virtual-network dns.domain=testdhcp --project testovn # Look for DHCP options mentioning our testdhcp domain name, there should be two. ovn-nbctl --format=csv --no-headings --data=bare --colum=_uuid,options find dhcp_options | grep testdhcp | wc -l | grep 2 -# Check DHCP can be disabled. +# Only enable IPv6 DHCP. +lxc init images:ubuntu/20.04 u1 --project testovn +lxc network set ovn-virtual-network ipv4.dhcp=false ipv6.dhcp=true --project testovn + +# Look for DHCP options mentioning our testdhcp domain name, there should be one. +ovn-nbctl --format=csv --no-headings --data=bare --colum=_uuid,options find dhcp_options | grep testdhcp | wc -l | grep 1 + +# Check container can start with IPv4 DHCP disabled. +lxc start u1 --project testovn +lxc stop -f u1 --project testovn + +# Only enable IPv6 DHCP. +lxc network set ovn-virtual-network ipv4.dhcp=true ipv6.dhcp=false --project testovn + +# Look for DHCP options mentioning our testdhcp domain name, there should be one. +ovn-nbctl --format=csv --no-headings --data=bare --colum=_uuid,options find dhcp_options | grep testdhcp | wc -l | grep 1 + +# Check container can start with IPv6 DHCP disabled. +lxc start u1 --project testovn +lxc delete -f u1 --project testovn + +# Disable both IPv4 and IPv6 DHCP. lxc network set ovn-virtual-network ipv4.dhcp=false ipv6.dhcp=false --project testovn # Look for DHCP options mentioning our testdhcp domain name, there shouldn't be any. ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Adds support for OVN physical uplink interface to be a bridge
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8262 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) === Supports either native or OVS bridges. And then uses the existing connection functions used for managed bridge uplinks to connect OVN router to uplink. Signed-off-by: Thomas Parrott From 12ae61c323fd04f2b18a9076c88e2ca545484d93 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 16 Dec 2020 12:12:41 + Subject: [PATCH] lxd/network/driver/ovn: Adds support for physical uplink interface to be a bridge Either native or OVS. And then uses the existing connection functions used for managed bridge uplinks to connect OVN router to uplink. Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 313 +++--- 1 file changed, 188 insertions(+), 125 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 8b17895a8c..3e68e6018d 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -878,88 +878,118 @@ func (n *ovn) uplinkPortBridgeVars(uplinkNet Network) *ovnUplinkPortBridgeVars { // startUplinkPortBridge creates veth pair (if doesn't exist), creates OVS bridge (if doesn't exist) and // connects veth pair to uplink bridge and OVS bridge. func (n *ovn) startUplinkPortBridge(uplinkNet Network) error { + if uplinkNet.Config()["bridge.driver"] != "openvswitch" { + return n.startUplinkPortBridgeNative(uplinkNet, uplinkNet.Name()) + } + + return n.startUplinkPortBridgeOVS(uplinkNet, uplinkNet.Name()) +} + +// startUplinkPortBridgeNative connects an OVN logical router to an uplink native bridge. +func (n *ovn) startUplinkPortBridgeNative(uplinkNet Network, bridgeDevice string) error { // Do this after gaining lock so that on failure we revert before release locking. revert := revert.New() defer revert.Fail() - ovs := openvswitch.NewOVS() - // If uplink is a native bridge, then use a separate OVS bridge with veth pair connection to native bridge. - if uplinkNet.Config()["bridge.driver"] != "openvswitch" { - vars := n.uplinkPortBridgeVars(uplinkNet) - - // Create veth pair if needed. - if !InterfaceExists(vars.uplinkEnd) && !InterfaceExists(vars.ovsEnd) { - _, err := shared.RunCommand("ip", "link", "add", "dev", vars.uplinkEnd, "type", "veth", "peer", "name", vars.ovsEnd) - if err != nil { - return errors.Wrapf(err, "Failed to create the uplink veth interfaces %q and %q", vars.uplinkEnd, vars.ovsEnd) - } + vars := n.uplinkPortBridgeVars(uplinkNet) - revert.Add(func() { shared.RunCommand("ip", "link", "delete", vars.uplinkEnd) }) + // Create veth pair if needed. + if !InterfaceExists(vars.uplinkEnd) && !InterfaceExists(vars.ovsEnd) { + _, err := shared.RunCommand("ip", "link", "add", "dev", vars.uplinkEnd, "type", "veth", "peer", "name", vars.ovsEnd) + if err != nil { + return errors.Wrapf(err, "Failed to create the uplink veth interfaces %q and %q", vars.uplinkEnd, vars.ovsEnd) } - // Ensure that the veth interfaces inherit the uplink bridge's MTU (which the OVS bridge also inherits). - uplinkNetConfig := uplinkNet.Config() - if uplinkNetConfig["bridge.mtu"] != "" { - err := InterfaceSetMTU(vars.uplinkEnd, uplinkNetConfig["bridge.mtu"]) - if err != nil { - return err - } - - err = InterfaceSetMTU(vars.ovsEnd, uplinkNetConfig["bridge.mtu"]) - if err != nil { - return err - } - } + revert.Add(func() { shared.RunCommand("ip", "link", "delete", vars.uplinkEnd) }) + } - // Ensure correct sysctls are set on uplink veth interfaces to avoid getting IPv6 link-local addresses. - err := util.SysctlSet( - fmt.Sprintf("net/ipv6/conf/%s/disable_ipv6", vars.uplinkEnd), "1", - fmt.Sprintf("net/ipv6/conf/%s/disable_ipv6", vars.ovsEnd), "1", - fmt.Sprintf("net/ipv6/conf/%s/forwarding", vars.uplinkEnd), "0", - fmt.Sprintf("net/ipv6/conf/%s/forwarding", vars.ovsEnd), "0", - ) + // Ensure that the veth interfaces inherit the uplink bridge's MTU (which the OVS bridge also inherits). + uplinkNetConfig := uplinkNet.Config() + if uplinkNetConfig["bridge.mtu"] != "" { + err :=
[lxc-devel] [lxd/master] Tp instance nic routed cleanup
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8261 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) === Addresses https://discuss.linuxcontainers.org/t/unknown-error-17-failed-to-setup-ipv4-address-route-for-network-device/9718 From fc834648941c72b9e09d1c9cb220d8da0e060bea Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 16 Dec 2020 09:39:19 + Subject: [PATCH 1/2] lxd/device/nic/routed: Switches to network.InterfaceExists for clarity Makes error quoting consistent. Signed-off-by: Thomas Parrott --- lxd/device/nic_routed.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/device/nic_routed.go b/lxd/device/nic_routed.go index ed47d9dbd3..0a9ec6cbc0 100644 --- a/lxd/device/nic_routed.go +++ b/lxd/device/nic_routed.go @@ -81,8 +81,8 @@ func (d *nicRouted) validateEnvironment() error { return fmt.Errorf("Requires liblxc has following API extensions: network_veth_router, network_l2proxy") } - if d.config["parent"] != "" && !shared.PathExists(fmt.Sprintf("/sys/class/net/%s", d.config["parent"])) { - return fmt.Errorf("Parent device '%s' doesn't exist", d.config["parent"]) + if d.config["parent"] != "" && !network.InterfaceExists(d.config["parent"]) { + return fmt.Errorf("Parent device %q doesn't exist", d.config["parent"]) } if d.config["parent"] == "" && d.config["vlan"] != "" { @@ -119,7 +119,7 @@ func (d *nicRouted) validateEnvironment() error { // If the effective parent doesn't exist and the vlan option is specified, it means we are going to create // the VLAN parent at start, and we will configure the needed sysctls so don't need to check them yet. - if d.config["vlan"] != "" && !shared.PathExists(fmt.Sprintf("/sys/class/net/%s", effectiveParentName)) { + if d.config["vlan"] != "" && network.InterfaceExists(effectiveParentName) { return nil } From 8069dc8a371b1ce642c457be162b9838249d9f7d Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 16 Dec 2020 10:02:06 + Subject: [PATCH 2/2] lxd/device/nic/routed: Remove host side veth interface if exists in postStop Signed-off-by: Thomas Parrott --- lxd/device/nic_routed.go | 10 ++ 1 file changed, 10 insertions(+) diff --git a/lxd/device/nic_routed.go b/lxd/device/nic_routed.go index 0a9ec6cbc0..197972ad9d 100644 --- a/lxd/device/nic_routed.go +++ b/lxd/device/nic_routed.go @@ -414,8 +414,18 @@ func (d *nicRouted) postStop() error { v := d.volatileGet() + networkVethFillFromVolatile(d.config, v) + errs := []error{} + if network.InterfaceExists(d.config["host_name"]) { + // Removing host-side end of veth pair will delete the peer end too. + err := network.InterfaceRemove(d.config["host_name"]) + if err != nil { + errs = append(errs, errors.Wrapf(err, "Failed to remove interface %q", d.config["host_name"])) + } + } + // This will delete the parent interface if we created it for VLAN parent. if shared.IsTrue(v["last_state.created"]) { parentName := network.GetHostDevice(d.config["parent"], d.config["vlan"]) ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] lxd/network/driver/ovn: Detect IPv6 DHCP options correctly
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8257 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) === Signed-off-by: Thomas Parrott From 5e507626b07034e4479ed3729152b2cc2cdd7e8d Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 15 Dec 2020 19:11:31 + Subject: [PATCH] lxd/network/driver/ovn: Detect IPv6 DHCP options correctly Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 0339cd3732..8b17895a8c 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -2163,7 +2163,7 @@ func (n *ovn) InstanceDevicePortAdd(instanceUUID string, instanceName string, de return "", err } - if dhcpV4ID == "" { + if dhcpv6ID == "" { return "", fmt.Errorf("Could not find DHCPv6 options for instance port") } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Instance: Fix deadlock in instance operationlock package
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8255 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) === Calling `Reset()` from `Create()` was causing a deadlock causing `lxc stop -f` requests to hang if initiated while an `lxc stop` was in progress. From 678cfbde4804df2c7d50f73b66c03b0be4491fb6 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 15 Dec 2020 16:22:56 + Subject: [PATCH 1/3] lxd/instance/operationlock: Fixes deadlock caused by call to Reset in Create Both try to aquire lock and so can deadlock each other. By pushing to the reset channel directly from Create we avoid the deadlock. Signed-off-by: Thomas Parrott --- lxd/instance/operationlock/operationlock.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lxd/instance/operationlock/operationlock.go b/lxd/instance/operationlock/operationlock.go index faab4c5982..a3bbd74e04 100644 --- a/lxd/instance/operationlock/operationlock.go +++ b/lxd/instance/operationlock/operationlock.go @@ -37,7 +37,8 @@ func Create(instanceID int, action string, reusable bool, reuse bool) (*Instance op := instanceOperations[instanceID] if op != nil { if op.reusable && reuse { - op.Reset() + // Reset operation timeout without releasing lock or deadlocking using Reset() function. + op.chanReset <- true return op, nil } From b8d7f56488219f0dfd3cb0e6076ea9b3b506863e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 15 Dec 2020 16:23:45 + Subject: [PATCH 2/3] lxd/instance/operationlock: Store operation in instanceOperations before calling go routine As the go routine can call functions on the operation (such as op.Done) which rely on the instanceOperations map being populated it seems appropriate to ensure it has been populated with the new operation before starting the go routine. Even though the only current use of the operation inside the go routine is after 30s. Signed-off-by: Thomas Parrott --- lxd/instance/operationlock/operationlock.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/instance/operationlock/operationlock.go b/lxd/instance/operationlock/operationlock.go index a3bbd74e04..b7e6504961 100644 --- a/lxd/instance/operationlock/operationlock.go +++ b/lxd/instance/operationlock/operationlock.go @@ -52,6 +52,8 @@ func Create(instanceID int, action string, reusable bool, reuse bool) (*Instance op.chanDone = make(chan error, 0) op.chanReset = make(chan bool, 0) + instanceOperations[instanceID] = op + go func(op *InstanceOperation) { for { select { @@ -64,8 +66,6 @@ func Create(instanceID int, action string, reusable bool, reuse bool) (*Instance } }(op) - instanceOperations[instanceID] = op - return op, nil } From 18ace0e0607b0b0f15bf9dc28c6355f57bb66fde Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 15 Dec 2020 16:25:13 + Subject: [PATCH 3/3] lxd/instance/operationlock: Exit go routine started in Create when the operation is done Otherwise I have observed that go routines can hang around for up to 30s after operation is completed. Signed-off-by: Thomas Parrott --- lxd/instance/operationlock/operationlock.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxd/instance/operationlock/operationlock.go b/lxd/instance/operationlock/operationlock.go index b7e6504961..49dab48b1a 100644 --- a/lxd/instance/operationlock/operationlock.go +++ b/lxd/instance/operationlock/operationlock.go @@ -57,6 +57,8 @@ func Create(instanceID int, action string, reusable bool, reuse bool) (*Instance go func(op *InstanceOperation) { for { select { + case <-op.chanDone: + return case <-op.chanReset: continue case <-time.After(time.Second * 30): ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] VM: Don't spin when Qemu QMP event channel is closed.
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8254 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) === Fixes 8253 From 1f8d31f61d7f375b5fd8029d4d79d4ce6da8292e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 15 Dec 2020 12:41:08 + Subject: [PATCH 1/2] lxd/instance/drivers/qmp/monitor: Handle closed event channel from qmp package in run Fixes #8253 Signed-off-by: Thomas Parrott --- lxd/instance/drivers/qmp/monitor.go | 20 +++- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lxd/instance/drivers/qmp/monitor.go b/lxd/instance/drivers/qmp/monitor.go index 20c6dd4d01..ea564e6080 100644 --- a/lxd/instance/drivers/qmp/monitor.go +++ b/lxd/instance/drivers/qmp/monitor.go @@ -12,6 +12,7 @@ import ( "github.com/digitalocean/go-qemu/qmp" "github.com/lxc/lxd/shared" + "github.com/lxc/lxd/shared/logger" ) var monitors = map[string]*Monitor{} @@ -126,13 +127,22 @@ func (m *Monitor) run() error { select { case <-m.chDisconnect: return - case e := <-chEvents: - if e.Event == "" { - continue + case e, more := <-chEvents: + // Deliver non-empty events to the event handler. + if m.eventHandler != nil && e.Event != "" { + go m.eventHandler(e.Event, e.Data) } - if m.eventHandler != nil { - go m.eventHandler(e.Event, e.Data) + // Event channel is closed, lets disconnect. + if !more { + m.Disconnect() + return + } + + if e.Event == "" { + logger.Warnf("Unexpected empty event received from qmp event channel") + time.Sleep(time.Second) // Don't busy wait if we receive a lot of these. + continue } // Check if the ringbuffer was updated (non-blocking). From 2ab69cfc1fa49211b3fb3de0ed9ed29ac78c6e0a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 15 Dec 2020 12:41:56 + Subject: [PATCH 2/2] lxd/instance/drivers/driver/qemu: Logs when instance is stopped in getMonitorEventHandler And removes some references to the instance in the function returned from getMonitorEventHandler so they are not kept in memory. Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_qemu.go | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index d01f47a3f7..b6168a3f6e 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -343,9 +343,12 @@ func (d *qemu) getStoragePool() (storagePools.Pool, error) { } func (d *qemu) getMonitorEventHandler() func(event string, data map[string]interface{}) { + // Create local variables from device properties we need so as not to keep references to device around + // after we have returned the callback function. projectName := d.Project() instanceName := d.Name() state := d.state + logger := d.logger return func(event string, data map[string]interface{}) { if !shared.StringInSlice(event, []string{"SHUTDOWN"}) { @@ -354,11 +357,13 @@ func (d *qemu) getMonitorEventHandler() func(event string, data map[string]inter inst, err := instance.LoadByProjectAndName(state, projectName, instanceName) if err != nil { - d.logger.Error("Failed to load instance", log.Ctx{"err": err}) + logger.Error("Failed to load instance", log.Ctx{"err": err}) return } if event == "SHUTDOWN" { + logger.Debug("Instance stopped") + target := "stop" entry, ok := data["reason"] if ok && entry == "guest-reset" { @@ -367,7 +372,7 @@ func (d *qemu) getMonitorEventHandler() func(event string, data map[string]inter err = inst.(*qemu).onStop(target) if err != nil { - d.logger.Error("Failed to cleanly stop instance", log.Ctx{"err": err}) + logger.Error("Failed to
[lxc-devel] [lxd/master] Storage: Clustering state avoid duplicate global config when doing re-create
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8250 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) === - Restructures storage pool creation to align with network creation process. - Adds detection for duplicate storage pool config. - Adds rejection of global config when performing a storage pool re-create attempt. - Reinstates the Errored storage pool status so that we can detect re-create attempts even when no global config supplied. From f5d6d54f2b257002e100e989faeb651c9ba02cdb Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 17:19:49 + Subject: [PATCH 01/32] lxd/db/networks: Adds duplicate key detection to getNetworkConfig Signed-off-by: Thomas Parrott --- lxd/db/networks.go | 5 + 1 file changed, 5 insertions(+) diff --git a/lxd/db/networks.go b/lxd/db/networks.go index dece3638a6..e6f75119ca 100644 --- a/lxd/db/networks.go +++ b/lxd/db/networks.go @@ -670,6 +670,11 @@ func (c *Cluster) getNetworkConfig(id int64) (map[string]string, error) { key = r[0].(string) value = r[1].(string) + _, found := config[key] + if found { + return nil, fmt.Errorf("Duplicate config row found for key %q for network ID %d", key, id) + } + config[key] = value } From 849aabe23e60d7186a9f56c93606f903297da988 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 14 Dec 2020 10:06:57 + Subject: [PATCH 02/32] lxd/db/networks: Adds NetworkErrored function Signed-off-by: Thomas Parrott --- lxd/db/networks.go | 5 + 1 file changed, 5 insertions(+) diff --git a/lxd/db/networks.go b/lxd/db/networks.go index e6f75119ca..dbc6e93a14 100644 --- a/lxd/db/networks.go +++ b/lxd/db/networks.go @@ -323,6 +323,11 @@ 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 ffc6845170d5e31b6df042a052c2518b4e464c83 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 14 Dec 2020 10:07:11 + Subject: [PATCH 03/32] lxd/db/networks: Changes UpdateNetwork to not set created status We shouldn't be allowing updates on non-created networks anyway. Signed-off-by: Thomas Parrott --- lxd/db/networks.go | 10 +- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/lxd/db/networks.go b/lxd/db/networks.go index dbc6e93a14..a675b01f0c 100644 --- a/lxd/db/networks.go +++ b/lxd/db/networks.go @@ -725,7 +725,7 @@ func (c *Cluster) CreateNetwork(projectName string, name string, description str // UpdateNetwork updates the network with the given name. func (c *Cluster) UpdateNetwork(project string, name, description string, config map[string]string) error { - id, netInfo, _, err := c.GetNetworkInAnyState(project, name) + id, _, _, err := c.GetNetworkInAnyState(project, name) if err != nil { return err } @@ -736,14 +736,6 @@ func (c *Cluster) UpdateNetwork(project string, name, description string, config return err } - // Update network status if change applied successfully. - if netInfo.Status == api.NetworkStatusErrored { - err = tx.NetworkCreated(project, name) - if err != nil { - return err - } - } - return nil }) From 9f070059265055cbf509e0b75c78a04315e2fa67 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 17:20:04 + Subject: [PATCH 04/32] lxd/network/driver/ovn: Reject instance port start if cannot find DHCP options Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 8 1 file changed, 8 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 4d7a6a3851..6cd162accb 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -2151,6 +2151,10 @@ func (n *ovn) InstanceDevicePortAdd(instanceUUID string, instanceName string, de if err != nil { return "", err } + + if dhcpV4ID == "" { + return "", fmt.Errorf("Could not find DHCPv4 options for instance port") +
[lxc-devel] [lxd/master] Network: Clustering state avoid duplicate global config when doing re-create
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8244 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) === When doing a `lxc network create` for subsequent attempts after failed initial attempt, avoid creating duplicate global config by ignoring global config supplied on subsequent attempts. From 689ca1fd3da951dcc790ed8d7fdcfd5b3c3fb3f1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 17:19:49 + Subject: [PATCH 1/7] lxd/db/networks: Adds duplicate key detection to getNetworkConfig Signed-off-by: Thomas Parrott --- lxd/db/networks.go | 5 + 1 file changed, 5 insertions(+) diff --git a/lxd/db/networks.go b/lxd/db/networks.go index dece3638a6..e6f75119ca 100644 --- a/lxd/db/networks.go +++ b/lxd/db/networks.go @@ -670,6 +670,11 @@ func (c *Cluster) getNetworkConfig(id int64) (map[string]string, error) { key = r[0].(string) value = r[1].(string) + _, found := config[key] + if found { + return nil, fmt.Errorf("Duplicate config row found for key %q for network ID %d", key, id) + } + config[key] = value } From fec13a6a73b02ea609cdca005ece4538ae758615 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 17:20:04 + Subject: [PATCH 2/7] lxd/network/driver/ovn: Reject instance port start if cannot find DHCP options Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 8 1 file changed, 8 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 4d7a6a3851..6cd162accb 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -2151,6 +2151,10 @@ func (n *ovn) InstanceDevicePortAdd(instanceUUID string, instanceName string, de if err != nil { return "", err } + + if dhcpV4ID == "" { + return "", fmt.Errorf("Could not find DHCPv4 options for instance port") + } } if dhcpv6Subnet != nil { @@ -2159,6 +2163,10 @@ func (n *ovn) InstanceDevicePortAdd(instanceUUID string, instanceName string, de return "", err } + if dhcpV4ID == "" { + return "", fmt.Errorf("Could not find DHCPv6 options for instance port") + } + // If port isn't going to have fully dynamic IPs allocated by OVN, and instead only static IPv4 // addresses have been added, then add an EUI64 static IPv6 address so that the switch port has an // IPv6 address that will be used to generate a DNS record. This works around a limitation in OVN From c3c36e878ad6b02078b8dace1892527bec553e73 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 17:20:33 + Subject: [PATCH 3/7] lxd/networks: doNetworksCreate usage Signed-off-by: Thomas Parrott --- lxd/networks.go | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lxd/networks.go b/lxd/networks.go index daf238facf..cf28c7d846 100644 --- a/lxd/networks.go +++ b/lxd/networks.go @@ -198,9 +198,14 @@ func networksPost(d *Daemon, r *http.Request) response.Response { clientType := request.UserAgentClientType(r.Header.Get("User-Agent")) if isClusterNotification(r) { + n, err := network.LoadByName(d.State(), projectName, req.Name) + if err != nil { + return response.SmartError(err) + } + // This is an internal request which triggers the actual creation of the network across all nodes // after they have been previously defined. - err = doNetworksCreate(d, projectName, req, clientType) + err = doNetworksCreate(d, n, clientType) if err != nil { return response.SmartError(err) } From 319053c314e310ef561c5de381d4ed5e118b0e86 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 17:20:52 + Subject: [PATCH 4/7] lxd/networks: When auto creating pending nodes, don't pass global config into DB function in networksPost We don't want to store global config yet and this can cause duplicates. Signed-off-by: Thomas Parrott --- lxd/networks.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lxd/networks.go b/lxd/networks.go index cf28c7d846..7701b03d6c 100644 --- a/lxd/networks.go +++ b/lxd/networks.go @@ -256,7 +256,8 @@ func networksPost(d *Daemon, r *http.Request) response.Response { } for _, node := range nodes { - err =
[lxc-devel] [lxd/master] Network: Improvements to clustering node state to better handle failed startup during network create
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8242 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) === - If a network was successfully "created" (using `n.Create()`) on a local node, but then failed to start (using `n.Start()`) then it was possible for setup done in `n.Create()` to be left behind because although `n.Delete()` was called on failure, the node status was still Pending and so the tear down was not performed. - To cope with this, and to better align with storage pool state management, I've moved the DB record deletion and cluster notification logic into the API route handler function, leaving the network package's `Delete()` function to always tear down local setup. - This allows the API route handler functions to decide for themselves (using `n.LocalStatus()`) whether it is appropriate to call `n.Delete()` depending on the scenario. From bc7e0525ef8f585bbcda22d3a4bb160ae124b7e6 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 14:43:56 + Subject: [PATCH 1/8] lxd/network/network/interface: Adds Project function Signed-off-by: Thomas Parrott --- lxd/network/network_interface.go | 1 + 1 file changed, 1 insertion(+) diff --git a/lxd/network/network_interface.go b/lxd/network/network_interface.go index 021cd88198..af8c8afcbe 100644 --- a/lxd/network/network_interface.go +++ b/lxd/network/network_interface.go @@ -31,6 +31,7 @@ type Network interface { Validate(config map[string]string) error ID() int64 Name() string + Project() string Description() string Status() string LocalStatus() string From 4b48e17ab725d8bf598b1bcf75021e46ffeedb3e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 14:44:14 + Subject: [PATCH 2/8] lxd/network/driver/common: Adds Project function Signed-off-by: Thomas Parrott --- lxd/network/driver_common.go | 5 + 1 file changed, 5 insertions(+) diff --git a/lxd/network/driver_common.go b/lxd/network/driver_common.go index 03f4b9ab7d..c17bf1d8d6 100644 --- a/lxd/network/driver_common.go +++ b/lxd/network/driver_common.go @@ -130,6 +130,11 @@ func (n *common) Name() string { return n.name } +// Project returns the network project. +func (n *common) Project() string { + return n.project +} + // Description returns the network description. func (n *common) Description() string { return n.description From 40defa5130a86dedd14ec111ccd6bf0667519fc8 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 11 Dec 2020 14:44:35 + Subject: [PATCH 3/8] lxd/network/driver/common: Remove cluster notification and DB record removal from delete() function We need more control over when we generate notifications and remove DB records, so this is being moved into the API route handler function (networkDelete()). This also aligns better with storage pools, where the notifications and DB record removal is also handled by API route handler function (storagePoolDelete()). Signed-off-by: Thomas Parrott --- lxd/network/driver_common.go | 28 +--- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/lxd/network/driver_common.go b/lxd/network/driver_common.go index c17bf1d8d6..2c9138f1c1 100644 --- a/lxd/network/driver_common.go +++ b/lxd/network/driver_common.go @@ -368,34 +368,16 @@ func (n *common) rename(newName string) error { // delete the network from the database if clusterNotification is false. func (n *common) delete(clientType request.ClientType) error { - // Only delete database record if not cluster notification. - 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 { - return err - } - err = notifier(func(client lxd.InstanceServer) error { - return client.UseProject(n.project).DeleteNetwork(n.name) - }) - if err != nil { - return err - } - - // Remove the network from the database. - err = n.state.Cluster.DeleteNetwork(n.project, n.name) - if err != nil { - return err - } - - n.lifecycle("deleted", nil) - } - // Cleanup storage. if shared.PathExists(shared.VarPath("networks", n.name)) { os.RemoveAll(shared.VarPath("networks", n.name)) } + // Generate lifecycle event if not notification. + if clientType != request.ClientTypeNotifier { + n.lifecycle("deleted", nil) +
[lxc-devel] [lxd/master] Network: Only add default route and SNAT rules to OVN router after adding external router port
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8238 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) === Fixes log message "No path for static route 0.0.0.0/0; next hop n.n.n.n" when creating/editing network. Also only add default routes and SNAT rules if logical router has external IPs. Signed-off-by: Thomas Parrott From 55e2051f529070acd275e399771ffd1e719a9801 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 10 Dec 2020 16:04:38 + Subject: [PATCH] lxd/network/driver/ovn: Only add default route and SNAT rules to router after adding external router port Fixes log message "No path for static route 0.0.0.0/0; next hop n.n.n.n" when creating/editing network. Also only add default routes and SNAT rules if logical router has external IPs. Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 60 +++ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 0c01386158..7b64b778c7 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1499,36 +1499,6 @@ func (n *ovn) setup(update bool) error { // Configure logical router. - // Add default routes. - if uplinkNet.routerExtGwIPv4 != nil { - err = client.LogicalRouterRouteAdd(n.getRouterName(), {IP: net.IPv4zero, Mask: net.CIDRMask(0, 32)}, uplinkNet.routerExtGwIPv4, false) - if err != nil { - return errors.Wrapf(err, "Failed adding IPv4 default route") - } - } - - if uplinkNet.routerExtGwIPv6 != nil { - err = client.LogicalRouterRouteAdd(n.getRouterName(), {IP: net.IPv6zero, Mask: net.CIDRMask(0, 128)}, uplinkNet.routerExtGwIPv6, false) - if err != nil { - return errors.Wrapf(err, "Failed adding IPv6 default route") - } - } - - // Add SNAT rules. - if shared.IsTrue(n.config["ipv4.nat"]) && routerIntPortIPv4Net != nil && routerExtPortIPv4 != nil { - err = client.LogicalRouterSNATAdd(n.getRouterName(), routerIntPortIPv4Net, routerExtPortIPv4) - if err != nil { - return err - } - } - - if shared.IsTrue(n.config["ipv6.nat"]) && routerIntPortIPv6Net != nil && routerExtPortIPv6 != nil { - err = client.LogicalRouterSNATAdd(n.getRouterName(), routerIntPortIPv6Net, routerExtPortIPv6) - if err != nil { - return err - } - } - // Generate external router port IPs (in CIDR format). extRouterIPs := []*net.IPNet{} if routerExtPortIPv4Net != nil { @@ -1593,6 +1563,36 @@ func (n *ovn) setup(update bool) error { if err != nil { return errors.Wrapf(err, "Failed linking external switch provider port to external provider network") } + + // Add SNAT rules. + if shared.IsTrue(n.config["ipv4.nat"]) && routerIntPortIPv4Net != nil && routerExtPortIPv4 != nil { + err = client.LogicalRouterSNATAdd(n.getRouterName(), routerIntPortIPv4Net, routerExtPortIPv4) + if err != nil { + return err + } + } + + if shared.IsTrue(n.config["ipv6.nat"]) && routerIntPortIPv6Net != nil && routerExtPortIPv6 != nil { + err = client.LogicalRouterSNATAdd(n.getRouterName(), routerIntPortIPv6Net, routerExtPortIPv6) + if err != nil { + return err + } + } + + // Add default routes. + if uplinkNet.routerExtGwIPv4 != nil { + err = client.LogicalRouterRouteAdd(n.getRouterName(), {IP: net.IPv4zero, Mask: net.CIDRMask(0, 32)}, uplinkNet.routerExtGwIPv4, false) + if err != nil { + return errors.Wrapf(err, "Failed adding IPv4 default route") + } + } + + if uplinkNet.routerExtGwIPv6 != nil { + err = client.LogicalRouterRouteAdd(n.getRouterName(), {IP: net.IPv6zero, Mask: net.CIDRMask(0, 128)}, uplinkNet.routerExtGwIPv6, false) + if err != nil { + return errors.Wrapf(err, "Failed adding IPv6 default route") + } + } } // Create internal logical switch if not updating. ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Storage: Prevent modification of storage pool source property on non-pending members
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8235 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) === From e600777f0fa8f8a3ab4742da1490961e55d8f316 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 10 Dec 2020 09:53:01 + Subject: [PATCH 1/3] lxd/db/storage/pools: Comment wrapping Signed-off-by: Thomas Parrott --- lxd/db/storage_pools.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go index 378e6547c5..b38d7a62f7 100644 --- a/lxd/db/storage_pools.go +++ b/lxd/db/storage_pools.go @@ -946,8 +946,7 @@ func (c *Cluster) FillMissingStoragePoolDriver() error { return err } -// StoragePoolNodeConfigKeys lists all storage pool config keys which are -// node-specific. +// StoragePoolNodeConfigKeys lists all storage pool config keys which are node-specific. var StoragePoolNodeConfigKeys = []string{ "size", "source", From ecd88221bd7a55a4c6e8b1286714e4309744dbef Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 10 Dec 2020 09:53:15 + Subject: [PATCH 2/3] lxd/storage/backend/lxd: Prevent modification of source field on non-pending nodes Signed-off-by: Thomas Parrott --- lxd/storage/backend_lxd.go | 6 ++ 1 file changed, 6 insertions(+) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 184c6e8d6a..048d6728bd 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -223,6 +223,12 @@ func (b *lxdBackend) Update(clientType request.ClientType, newDesc string, newCo // Diff the configurations. changedConfig, userOnly := b.detectChangedConfig(b.db.Config, newConfig) + // Check if the pool source is being changed that the local state is still pending, otherwise prevent it. + _, sourceChanged := changedConfig["source"] + if sourceChanged && b.LocalStatus() != api.StoragePoolStatusPending { + return fmt.Errorf("Pool source cannot be changed when not in pending state") + } + // Apply changes to local node if not pending and non-user config changed. if len(changedConfig) != 0 && b.LocalStatus() != api.StoragePoolStatusPending && !userOnly { err = b.driver.Update(changedConfig) From 6404936c1516ebfc65614fd976ee2acaec2a4711 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 10 Dec 2020 09:53:35 + Subject: [PATCH 3/3] lxd/storage/drivers/driver/lvm: Comment typo Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_lvm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/drivers/driver_lvm.go b/lxd/storage/drivers/driver_lvm.go index 8654f0053d..a6f375a9dc 100644 --- a/lxd/storage/drivers/driver_lvm.go +++ b/lxd/storage/drivers/driver_lvm.go @@ -356,7 +356,7 @@ func (d *lvm) Delete(op *operations.Operation) error { // Thin pool exists. if err == nil { // If thin pool is empty and the total VG volume count is 1 (our thin pool - // volume) then just remote the entire volume group. + // volume) then just remove the entire volume group. if thinVolCount == 0 && lvCount == 1 { removeVg = true } else if thinVolCount == 0 && lvCount > 1 { ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxc-ci/master] bin/test-lxd-ovn: Adds routed ingress anycast tests
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/214 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) === Signed-off-by: Thomas Parrott From 4888daacd0a6fcef92f8be2460070445277eb38a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 18:20:04 + Subject: [PATCH] bin/test-lxd-ovn: Adds routed ingress anycast tests Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 28 ++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index 24d5f2c..6d904dc 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -151,13 +151,29 @@ lxc network create ovn-virtual-network --type=ovn --project testovn network=dumm ipv4.nat=false \ ipv6.nat=false -# Check network external subnet overlap. +# Check network external subnet overlap is prevented. ! lxc network create ovn-virtual-network2 --type=ovn --project default network=dummy \ ipv4.address=198.51.100.1/26 \ +ipv4.nat=false || false + +! lxc network create ovn-virtual-network2 --type=ovn --project default network=dummy \ ipv6.address=2001:db8:1:2::1/122 \ -ipv4.nat=false \ ipv6.nat=false || false +# Check network external subnet overlap check relaxation when uplink has anycast routed ingress mode enabled. +lxc network set dummy ovn.ingress_mode=routed ipv4.routes.anycast=true ipv6.routes.anycast=true --project default + +lxc network create ovn-virtual-network2 --type=ovn --project default network=dummy \ +ipv4.address=198.51.100.1/26 \ +ipv4.nat=false \ +ipv6.address=2001:db8:1:2::1/122 \ +ipv6.nat=false + +lxc network delete ovn-virtual-network2 --project default +lxc network unset dummy ovn.ingress_mode --project default +lxc network unset dummy ipv4.routes.anycast --project default +lxc network unset dummy ipv6.routes.anycast --project default + lxc init images:ubuntu/20.04 u1 --project testovn lxc config device add u1 eth0 nic network=ovn-virtual-network name=eth0 --project testovn @@ -206,7 +222,15 @@ lxc init images:ubuntu/20.04 u2 --project testovn lxc config device add u2 eth0 nic network=ovn-virtual-network name=eth0 --project testovn ! lxc config device set u2 eth0 ipv4.routes.external=198.51.100.1/32 --project testovn || false ! lxc config device set u2 eth0 ipv6.routes.external=2001:db8:1:2::1/128 --project testovn || false + +# Check NIC external route overlap check relaxation when uplink has anycast routed ingress mode enabled. +lxc network set dummy ovn.ingress_mode=routed ipv4.routes.anycast=true ipv6.routes.anycast=true --project default +lxc config device set u2 eth0 ipv4.routes.external=198.51.100.1/32 --project testovn +lxc config device set u2 eth0 ipv6.routes.external=2001:db8:1:2::1/128 --project testovn lxc delete -f u2 --project testovn +lxc network unset dummy ovn.ingress_mode --project default +lxc network unset dummy ipv4.routes.anycast --project default +lxc network unset dummy ipv6.routes.anycast --project default # Check DNAT rules get added when starting instance port with external routes. lxc start u1 --project testovn ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Adds ipv4.routes.anycast and ipv6.routes.anycast settings to physical networks
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8233 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) === Adds `ipv4.routes.anycast` and `ipv6.routes.anycast` boolean settings for `physical` networks. Defaults to false. Allows OVN networks using physical network as uplink to relax external subnet/route overlap detection when used with `ovn.ingress_mode=routed`. From 3bff5fac1e39e625ace73878bf4c182e6fb2f2dd Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 17:29:07 + Subject: [PATCH 1/6] doc/networks: Adds ipv4.routes.anycast and ipv6.routes.anycast to physical networks Signed-off-by: Thomas Parrott --- doc/networks.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/networks.md b/doc/networks.md index 8877835e70..55082dcc82 100644 --- a/doc/networks.md +++ b/doc/networks.md @@ -324,8 +324,10 @@ vlan| integer | - | - ipv4.gateway| string| standard mode | - | IPv4 address for the gateway and network (CIDR notation) ipv4.ovn.ranges | string| - | - | Comma separate list of IPv4 ranges to use for child OVN network routers (FIRST-LAST format) ipv4.routes | string| ipv4 address | - | Comma separated list of additional IPv4 CIDR subnets that can be used with child OVN networks ipv4.routes.external setting +ipv4.routes.anycast | boolean | ipv4 address | false | Allow the overlapping routes to be used on multiple networks/NIC at the same time. ipv6.gateway| string| standard mode | - | IPv6 address for the gateway and network (CIDR notation) ipv6.ovn.ranges | string| - | - | Comma separate list of IPv6 ranges to use for child OVN network routers (FIRST-LAST format) ipv6.routes | string| ipv6 address | - | Comma separated list of additional IPv6 CIDR subnets that can be used with child OVN networks ipv6.routes.external setting +ipv6.routes.anycast | boolean | ipv6 address | false | Allow the overlapping routes to be used on multiple networks/NIC at the same time. dns.nameservers | string| standard mode | - | List of DNS server IPs on physical network ovn.ingress_mode| string| standard mode | l2proxy | Sets the method that OVN NIC external IPs will be advertised on uplink network. Either `l2proxy` (proxy ARP/NDP) or `routed`. From 33ac2d80492c9efd3ab433c60dff755f607fd3e9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 17:30:09 + Subject: [PATCH 2/6] lxd/network/driver/physical: Adds ipv4.routes.anycast and ipv6.routes.anycast options Signed-off-by: Thomas Parrott --- lxd/network/driver_physical.go | 26 ++ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lxd/network/driver_physical.go b/lxd/network/driver_physical.go index 99a8be7f11..6cf8bd31e1 100644 --- a/lxd/network/driver_physical.go +++ b/lxd/network/driver_physical.go @@ -34,18 +34,20 @@ func (n *physical) DBType() db.NetworkType { // Validate network config. func (n *physical) Validate(config map[string]string) error { rules := map[string]func(value string) error{ - "parent": validate.Required(validate.IsNotEmpty, validInterfaceName), - "mtu": validate.Optional(validate.IsNetworkMTU), - "vlan": validate.Optional(validate.IsNetworkVLAN), - "maas.subnet.ipv4": validate.IsAny, - "maas.subnet.ipv6": validate.IsAny, - "ipv4.gateway": validate.Optional(validate.IsNetworkAddressCIDRV4), - "ipv6.gateway": validate.Optional(validate.IsNetworkAddressCIDRV6), - "ipv4.ovn.ranges": validate.Optional(validate.IsNetworkRangeV4List), - "ipv6.ovn.ranges": validate.Optional(validate.IsNetworkRangeV6List), - "ipv4.routes": validate.Optional(validate.IsNetworkV4List), - "ipv6.routes": validate.Optional(validate.IsNetworkV6List), - "dns.nameservers": validate.Optional(validate.IsNetworkAddressList), + "parent": validate.Required(validate.IsNotEmpty, validInterfaceName), + "mtu": validate.Optional(validate.IsNetworkMTU), + "vlan":
[lxc-devel] [lxc-ci/master] bin/test-lxd-ovn: Adds tests for DHCP disabling
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/212 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) === Depends on https://github.com/lxc/lxd/pull/8229 Signed-off-by: Thomas Parrott From b31002fe874776978df7c7cd6b51860216311506 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 15:18:49 + Subject: [PATCH] bin/test-lxd-ovn: Adds tests for DHCP disabling Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 13 + 1 file changed, 13 insertions(+) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index f5cbc92..b01a3a9 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -240,6 +240,19 @@ if [ "$natRulesBefore" -ne "$natRulesAfter" ]; then fi lxc delete -f u1 --project testovn +lxc network unset dummy ovn.ingress_mode + +# Set custom domain to allow identification of DHCP options. +lxc network set ovn-virtual-network dns.domain=testdhcp --project testovn + +# Look for DHCP options mentioning our testdhcp domain name, there should be two. +sudo ovn-nbctl --format=csv --no-headings --data=bare --colum=_uuid,options find dhcp_options | grep testdhcp | wc -l | grep 2 + +# Check DHCP can be disabled. +lxc network set ovn-virtual-network ipv4.dhcp=false ipv6.dhcp=false --project testovn + +# Look for DHCP options mentioning our testdhcp domain name, there shouldn't be any. +sudo ovn-nbctl --format=csv --no-headings --data=bare --colum=_uuid,options find dhcp_options | grep testdhcp | wc -l | grep 0 lxc network delete ovn-virtual-network --project testovn lxc image delete "${FINGERPRINT}" --project testovn ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Adds ipv4.dhcp and ipv6.dhcp settings for OVN networks
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8229 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) === Allows DHCP/RA to be disabled. From 19b1f4ea200277bbcb3519e4ec630bee769b7156 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 13:58:55 + Subject: [PATCH 1/7] lxd/network/openvswitch/ovn: Exports LogicalSwitchDHCPOptionsDelete and adds optional UUID filter for deletion Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovn.go | 29 +++-- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go index 643e6d7047..d7ad3079ee 100644 --- a/lxd/network/openvswitch/ovn.go +++ b/lxd/network/openvswitch/ovn.go @@ -325,7 +325,7 @@ func (o *OVN) LogicalSwitchDelete(switchName OVNSwitch) error { return err } - err = o.logicalSwitchDHCPOptionsDelete(switchName) + err = o.LogicalSwitchDHCPOptionsDelete(switchName) if err != nil { return err } @@ -549,8 +549,9 @@ func (o *OVN) LogicalSwitchDHCPOptionsGet(switchName OVNSwitch) ([]OVNDHCPOptsSe return dhcpOpts, nil } -// logicalSwitchDHCPOptionsDelete deletes any DHCP options defined for a switch. -func (o *OVN) logicalSwitchDHCPOptionsDelete(switchName OVNSwitch) error { +// LogicalSwitchDHCPOptionsDelete deletes any DHCP options defined for a switch. +// Optionally accepts one or more specific UUID records to delete (if they are associated to the specified switch). +func (o *OVN) LogicalSwitchDHCPOptionsDelete(switchName OVNSwitch, onlyUUID ...string) error { existingOpts, err := o.nbctl("--format=csv", "--no-headings", "--data=bare", "--colum=_uuid", "find", "dhcp_options", fmt.Sprintf("external_ids:lxd_switch=%s", string(switchName)), ) @@ -558,12 +559,28 @@ func (o *OVN) logicalSwitchDHCPOptionsDelete(switchName OVNSwitch) error { return err } + shouldDelete := func(existingUUID string) bool { + if len(onlyUUID) <= 0 { + return true // Delete all records if no UUID filter supplied. + } + + for _, uuid := range onlyUUID { + if existingUUID == uuid { + return true + } + } + + return false + } + existingOpts = strings.TrimSpace(existingOpts) if existingOpts != "" { for _, uuid := range strings.Split(existingOpts, "\n") { - _, err = o.nbctl("destroy", "dhcp_options", uuid) - if err != nil { - return err + if shouldDelete(uuid) { + _, err = o.nbctl("destroy", "dhcp_options", uuid) + if err != nil { + return err + } } } } From f893eb22808c247ac88fe0051bc53b91fc66dae8 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 14:02:45 + Subject: [PATCH 2/7] lxc/network/driver/ovn: Adds ipv4.dhcp and ipv6.dhcp boolean settings Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index dc7668e853..4723a8445f 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -180,6 +180,7 @@ func (n *ovn) Validate(config map[string]string) error { return validate.Optional(validate.IsNetworkAddressCIDRV4)(value) }, + "ipv4.dhcp": validate.Optional(validate.IsBool), "ipv6.address": func(value string) error { if validate.IsOneOf(value, []string{"none", "auto"}) == nil { return nil @@ -187,6 +188,7 @@ func (n *ovn) Validate(config map[string]string) error { return validate.Optional(validate.IsNetworkAddressCIDRV6)(value) }, + "ipv6.dhcp": validate.Optional(validate.IsBool), "ipv6.dhcp.stateful": validate.Optional(validate.IsBool), "ipv4.nat": validate.Optional(validate.IsBool), "ipv6.nat": validate.Optional(validate.IsBool), From 9067bf591633532827a2708cccdc3d779f92c7cc Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 14:08:08 + Subject: [PATCH 3/7] lxc/network/driver/ovn: Modifies setup to only activate DHCP/RA if its enabled on network Also removes old DHCP option records if DHCP is being disabled. Signed-off-by:
[lxc-devel] [lxc-ci/master] Network: Adds OVN routed ingress mode tests
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/210 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) === Depends on https://github.com/lxc/lxd/pull/8226 From 5f02b017fdb125fe27992f6808c021e2ab7ae896 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 10:53:08 + Subject: [PATCH 1/4] bin/test-lxd-ovn: Adds external routes allowed check Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index f011144..d16729d 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -177,9 +177,13 @@ lxc network set ovn-virtual-network --project testovn \ ipv4.nat=true \ ipv6.nat=true -# Check external routes are ensured to be within uplink's external routes. +# Check external routes are not too big (when using l2proxy uplink ingress mode). ! lxc config device set u1 eth0 ipv4.routes.external=198.51.100.0/24 --project testovn || false ! lxc config device set u1 eth0 ipv6.routes.external=2001:db8:1:2::/64 --project testovn || false + +# Check external routes are ensured to be within uplink's external routes. +! lxc config device set u1 eth0 ipv4.routes.external=203.0.113.0/26 --project testovn || false +! lxc config device set u1 eth0 ipv6.routes.external=2001:db8:2:2::/122 --project testovn || false lxc config device set u1 eth0 ipv4.routes.external=198.51.100.0/26 --project testovn lxc config device set u1 eth0 ipv6.routes.external=2001:db8:1:2::/122 --project testovn From 32ad6cdfae2edfb7875bd9f84448ff3d576fe13d Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 11:09:41 + Subject: [PATCH 2/4] bin/test-lxd-ovn: Typo Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index d16729d..0a50dca 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -132,7 +132,7 @@ lxc network create ovn-virtual-network network=lxdbr0 --project testovn lxc network delete ovn-virtual-network --project testovn lxc network delete lxdbr1 --project default -# Test physical uplink with external IPs +# Test physical uplink with external IPs. ip link add dummy0 type dummy lxc network create dummy --type=physical --project default \ parent=dummy0 \ From 043d77f45a43b6017f36efb0fc9e70c14648aba9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 11:09:55 + Subject: [PATCH 3/4] bin/test-lxd-ovn: Add NAT rule cleanup checks Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 22 ++ 1 file changed, 22 insertions(+) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index 0a50dca..18f2d33 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -160,6 +160,10 @@ lxc network create ovn-virtual-network --type=ovn --project testovn network=dumm lxc init images:ubuntu/20.04 u1 --project testovn lxc config device add u1 eth0 nic network=ovn-virtual-network name=eth0 --project testovn + +# Record NAT rules count before u1 started. +natRulesBefore=$(ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | wc -l) + lxc start u1 --project testovn # Test external IPs allocated and published using dnat. @@ -170,6 +174,13 @@ ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | gr ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | grep "${U1_EXT_IPV6},${U1_EXT_IPV6},dnat_and_snat" lxc stop -f u1 --project testovn +# Check NAT rules got cleaned up. +natRulesAfter=$(ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | wc -l) +if [ "$natRulesBefore" -ne "$natRulesAfter" ]; then +echo "NAT rules left over. Started with ${natRulesBefore} now have ${natRulesAfter}" +false +fi + # Test external IPs routed to OVN NIC. lxc network set ovn-virtual-network --project testovn \ ipv4.address=auto \ @@ -177,6 +188,9 @@ lxc network set ovn-virtual-network --project testovn \ ipv4.nat=true \ ipv6.nat=true +# Record NAT rules count before u1 started again. +natRulesBefore=$(ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | wc -l) + # Check external routes are not too big (when using l2proxy uplink ingress mode). ! lxc config device set u1 eth0 ipv4.routes.external=198.51.100.0/24 --project testovn || false ! lxc config device set u1 eth0 ipv6.routes.external=2001:db8:1:2::/64 --project testovn || false @@ -204,6 +218,14 @@ ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | gr ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | wc -l | grep 132 lxc delete -f u1 --project testovn + +# Check NAT rules got cleaned up.
[lxc-devel] [lxd/master] Network: OVN Ingress mode
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8226 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) === Add `ovn.ingress_mode` (either `l2proxy` (default) or `routed`) on `physical` networks to allow OVN NICs to change the way they advertise their external IPs on the uplink network. From 4ec52f656bb1c178a38f1bcffb489f12ad644a10 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 09:24:48 + Subject: [PATCH 1/7] lxd/network/driver/ovn: Improve error message Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index e222099fee..3dc4db91bb 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1411,7 +1411,7 @@ func (n *ovn) setup(update bool) error { err := n.state.Cluster.Transaction(func(tx *db.ClusterTx) error { err = tx.UpdateNetwork(n.id, n.description, n.config) if err != nil { - return errors.Wrapf(err, "Failed saving optimal bridge MTU") + return errors.Wrapf(err, "Failed saving updated network config") } return nil From 7cbdd62e06db2b2758a4d2b7ad620722fdc3f719 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 10:04:37 + Subject: [PATCH 2/7] lxd/network/driver/physical: Adds ovn.ingress_mode config key Allows specifying how external OVN NIC IPs are advertised to the uplink; either "l2proxy" (default) or "routed". Signed-off-by: Thomas Parrott --- lxd/network/driver_physical.go | 27 +++ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/lxd/network/driver_physical.go b/lxd/network/driver_physical.go index 19d0001a57..99a8be7f11 100644 --- a/lxd/network/driver_physical.go +++ b/lxd/network/driver_physical.go @@ -34,18 +34,21 @@ func (n *physical) DBType() db.NetworkType { // Validate network config. func (n *physical) Validate(config map[string]string) error { rules := map[string]func(value string) error{ - "parent": validate.Required(validate.IsNotEmpty, validInterfaceName), - "mtu": validate.Optional(validate.IsNetworkMTU), - "vlan": validate.Optional(validate.IsNetworkVLAN), - "maas.subnet.ipv4":validate.IsAny, - "maas.subnet.ipv6":validate.IsAny, - "ipv4.gateway": validate.Optional(validate.IsNetworkAddressCIDRV4), - "ipv6.gateway": validate.Optional(validate.IsNetworkAddressCIDRV6), - "ipv4.ovn.ranges": validate.Optional(validate.IsNetworkRangeV4List), - "ipv6.ovn.ranges": validate.Optional(validate.IsNetworkRangeV6List), - "ipv4.routes": validate.Optional(validate.IsNetworkV4List), - "ipv6.routes": validate.Optional(validate.IsNetworkV6List), - "dns.nameservers": validate.Optional(validate.IsNetworkAddressList), + "parent": validate.Required(validate.IsNotEmpty, validInterfaceName), + "mtu": validate.Optional(validate.IsNetworkMTU), + "vlan": validate.Optional(validate.IsNetworkVLAN), + "maas.subnet.ipv4": validate.IsAny, + "maas.subnet.ipv6": validate.IsAny, + "ipv4.gateway": validate.Optional(validate.IsNetworkAddressCIDRV4), + "ipv6.gateway": validate.Optional(validate.IsNetworkAddressCIDRV6), + "ipv4.ovn.ranges": validate.Optional(validate.IsNetworkRangeV4List), + "ipv6.ovn.ranges": validate.Optional(validate.IsNetworkRangeV6List), + "ipv4.routes": validate.Optional(validate.IsNetworkV4List), + "ipv6.routes": validate.Optional(validate.IsNetworkV6List), + "dns.nameservers": validate.Optional(validate.IsNetworkAddressList), + "ovn.ingress_mode": validate.Optional(func(value string) error { + return validate.IsOneOf(value, []string{"l2proxy", "routed"}) + }), "volatile.last_state.created": validate.Optional(validate.IsBool), } From 0e1537b591c9f317a47523eca3328c7bac5e058c Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 9 Dec 2020 10:05:39 + Subject: [PATCH 3/7] lxd/network/driver/ovn: Updates uplinkRoutes to accept an *api.Network argument Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go |
[lxc-devel] [lxc-ci/master] bin/test-lxd-vm: Adds ceph support and uses random pool name
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/209 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) === Depends on https://github.com/lxc/lxd/pull/8225 Signed-off-by: Thomas Parrott From f358834e4a7820e12f51d4022abaa6ec86379a0a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 8 Dec 2020 16:30:43 + Subject: [PATCH] bin/test-lxd-vm: Adds ceph support and uses random pool name Signed-off-by: Thomas Parrott --- bin/test-lxd-vm | 46 +- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/bin/test-lxd-vm b/bin/test-lxd-vm index b02715d..6fe72d1 100755 --- a/bin/test-lxd-vm +++ b/bin/test-lxd-vm @@ -12,7 +12,7 @@ cleanup() { exit 0 } -poolDriverList="${1:-dir btrfs lvm zfs}" +poolDriverList="${1:-dir btrfs lvm zfs ceph}" FAIL=1 trap cleanup EXIT HUP INT TERM @@ -39,17 +39,21 @@ lxd waitready --timeout=300 lxc network create lxdbr0 lxc profile device add default eth0 nic network=lxdbr0 +poolName="vmpool$$" + for poolDriver in $poolDriverList do echo "==> Create storage pool using driver ${poolDriver}" if [ "${poolDriver}" = "dir" ]; then -lxc storage create vmpool "${poolDriver}" +lxc storage create "${poolName}" "${poolDriver}" +elif [ "${poolDriver}" = "ceph" ]; then +lxc storage create "${poolName}" "${poolDriver}" source="${poolName}" else -lxc storage create vmpool "${poolDriver}" size=20GB +lxc storage create "${poolName}" "${poolDriver}" size=20GB fi echo "==> Create VM and boot" -lxc init images:ubuntu/20.04/cloud v1 --vm -s vmpool +lxc init images:ubuntu/20.04/cloud v1 --vm -s "${poolName}" lxc start v1 sleep 60 lxc info v1 @@ -74,8 +78,8 @@ do lxc delete -f v1 echo "==> Change volume.size on pool and create VM" -lxc storage set vmpool volume.size 6GB -lxc init images:ubuntu/20.04/cloud v1 --vm -s vmpool +lxc storage set "${poolName}" volume.size 6GB +lxc init images:ubuntu/20.04/cloud v1 --vm -s "${poolName}" lxc start v1 sleep 60 lxc info v1 @@ -85,12 +89,12 @@ do echo "==> Deleting VM and reset pool volume.size" lxc delete -f v1 -lxc storage unset vmpool volume.size +lxc storage unset "${poolName}" volume.size if [ "${poolDriver}" = "lvm" ]; then echo "==> Change volume.block.filesystem on pool and create VM" -lxc storage set vmpool volume.block.filesystem xfs -lxc init images:ubuntu/20.04/cloud v1 --vm -s vmpool +lxc storage set "${poolName}" volume.block.filesystem xfs +lxc init images:ubuntu/20.04/cloud v1 --vm -s "${poolName}" lxc start v1 sleep 60 lxc info v1 @@ -101,12 +105,12 @@ do echo "==> Deleting VM" lxc delete -f v1 -lxc storage unset vmpool volume.block.filesystem +lxc storage unset "${poolName}" volume.block.filesystem fi echo "==> Create VM from profile with small disk size" lxc profile copy default vmsmall -lxc profile device add vmsmall root disk pool=vmpool path=/ size=7GB +lxc profile device add vmsmall root disk pool="${poolName}" path=/ size=7GB lxc init images:ubuntu/20.04/cloud v1 --vm -p vmsmall lxc start v1 sleep 60 @@ -122,8 +126,8 @@ do dstPoolDriver=lvm # Use something different when testing ZFS. fi -lxc storage create vmpool2 "${dstPoolDriver}" size=20GB -lxc copy v1 v2 -s vmpool2 +lxc storage create "${poolName}"2 "${dstPoolDriver}" size=20GB +lxc copy v1 v2 -s "${poolName}"2 lxc start v2 sleep 60 lxc info v2 @@ -132,9 +136,9 @@ do lxc exec v2 -- df -B10 | grep sda2 | grep 7 lxc delete -f v2 -echo "==> Grow above default voume size and copy to different storage pool" +echo "==> Grow above default volume size and copy to different storage pool" lxc config device override v1 root size=11GB -lxc copy v1 v2 -s vmpool2 +lxc copy v1 v2 -s "${poolName}"2 lxc start v2 sleep 60 lxc info v2 @@ -146,14 +150,14 @@ do echo "==> Publishing larger VM" lxc publish v1 --alias vmbig lxc delete -f v1 -lxc storage set vmpool volume.size 9GB +lxc storage set "${poolName}" volume.size 9GB echo "==> Check VM create fails when image larger than volume.size" -! lxc init vmbig v1 --vm -s vmpool || false
[lxc-devel] [lxd/master] Storage: ZFS rounding up
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8225 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) === Fixes issue when copying from ceph to zfs pools, the zfs volumes were being rounded to the nearest 8192 bytes, which sometimes meant the volume size created was just too small to accommodate the source ceph volume (which doesn't round to nearest 8192 bytes). This modifies the ZFS volumes to round up to nearest 8192 bytes. From 23835ab8cc0a8b7334fff5a185b97e67a5920f86 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 8 Dec 2020 12:56:13 + Subject: [PATCH 1/8] lxd/storage/drivers/utils: Modifies roundVolumeBlockFileSizeBytes to round up Ensures that the returned bytes is always greater than or equal to the input bytes. Signed-off-by: Thomas Parrott --- lxd/storage/drivers/utils.go | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go index a64635bbc2..3a216852c7 100644 --- a/lxd/storage/drivers/utils.go +++ b/lxd/storage/drivers/utils.go @@ -310,16 +310,24 @@ func ensureSparseFile(filePath string, sizeBytes int64) error { return nil } -// roundVolumeBlockFileSizeBytes parses the supplied size string and then rounds it to the nearest 8k bytes. -func roundVolumeBlockFileSizeBytes(sizeBytes int64) (int64, error) { +// roundVolumeBlockFileSizeBytes parses the supplied size string and then rounds it to the nearest multiple of +// MinBlockBoundary bytes that is equal to or larger than sizeBytes. +func roundVolumeBlockFileSizeBytes(sizeBytes int64) int64 { // Qemu requires image files to be in traditional storage block boundaries. // We use 8k here to ensure our images are compatible with all of our backend drivers. if sizeBytes < MinBlockBoundary { sizeBytes = MinBlockBoundary } + roundedSizeBytes := int64(sizeBytes/MinBlockBoundary) * MinBlockBoundary + + // Ensure the rounded size is at least the size specified in sizeBytes. + if roundedSizeBytes < sizeBytes { + roundedSizeBytes += MinBlockBoundary + } + // Round the size to closest MinBlockBoundary bytes to avoid qemu boundary issues. - return int64(sizeBytes/MinBlockBoundary) * MinBlockBoundary, nil + return roundedSizeBytes } // ensureVolumeBlockFile creates new block file or enlarges the raw block file for a volume to the specified size. From f1a1b13c5acbd16969c5f3186d1c7cc74e2d3636 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 8 Dec 2020 12:56:55 + Subject: [PATCH 2/8] lxd/storage/drivers/utils: roundVolumeBlockFileSizeBytes usage Signed-off-by: Thomas Parrott --- lxd/storage/drivers/utils.go | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go index 3a216852c7..b922e12160 100644 --- a/lxd/storage/drivers/utils.go +++ b/lxd/storage/drivers/utils.go @@ -339,10 +339,7 @@ func ensureVolumeBlockFile(vol Volume, path string, sizeBytes int64) (bool, erro } // Get rounded block size to avoid qemu boundary issues. - sizeBytes, err := roundVolumeBlockFileSizeBytes(sizeBytes) - if err != nil { - return false, err - } + sizeBytes = roundVolumeBlockFileSizeBytes(sizeBytes) if shared.PathExists(path) { fi, err := os.Stat(path) @@ -384,7 +381,7 @@ func ensureVolumeBlockFile(vol Volume, path string, sizeBytes int64) (bool, erro // If path doesn't exist, then there has been no filler function supplied to create it from another source. // So instead create an empty volume (use for PXE booting a VM). - err = ensureSparseFile(path, sizeBytes) + err := ensureSparseFile(path, sizeBytes) if err != nil { return false, errors.Wrapf(err, "Failed creating disk image %q as size %d", path, sizeBytes) } From 8e7d36e48fa423424b37e5b08fb31f0025ac47f3 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 8 Dec 2020 12:57:16 + Subject: [PATCH 3/8] lxd/storage/drivers/driver/zfs/utils: Use roundVolumeBlockFileSizeBytes in createVolume Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_zfs_utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/drivers/driver_zfs_utils.go b/lxd/storage/drivers/driver_zfs_utils.go index 13e59cb80f..555a71b7ab 100644 --- a/lxd/storage/drivers/driver_zfs_utils.go +++ b/lxd/storage/drivers/driver_zfs_utils.go @@ -55,7 +55,7 @@ func (d *zfs) createDataset(dataset string, options ...string) error { } func (d *zfs) createVolume(dataset string, size int64, options ...string) error { - size = (size / MinBlockBoundary) *
[lxc-devel] [lxc-ci/master] Adds test for LXD VMs
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/205 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) === There's a few more tests to add, but this adds most of them: - VM create. - VM grow on next reboot. - VM shrink prevented. - VM create after storage volume.size changed. - VM create after storage volume.block.filesystem changed. - VM create from profile with disk smaller than default VM volume size. - VM migrate across pools with disk size larger than volume.size. - VM migrate across pools with disk size smaller than volume.size. Signed-off-by: Thomas Parrott From 9e7f5e431d73348d67d1f1a643d8f29c9bead2dd Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 7 Dec 2020 20:57:38 + Subject: [PATCH] Adds test for LXD VMs Signed-off-by: Thomas Parrott --- bin/test-lxd-vm | 152 1 file changed, 152 insertions(+) create mode 100755 bin/test-lxd-vm diff --git a/bin/test-lxd-vm b/bin/test-lxd-vm new file mode 100755 index 000..7c51b65 --- /dev/null +++ b/bin/test-lxd-vm @@ -0,0 +1,152 @@ +#!/bin/sh +set -eux + +cleanup() { +echo "" +if [ "${FAIL}" = "1" ]; then +echo "Test failed" +exit 1 +fi + +echo "Test passed" +exit 0 +} + +poolDriverList="${1:-dir btrfs lvm zfs}" +FAIL=1 +trap cleanup EXIT HUP INT TERM + +# Wait for snapd seeding +sleep 1m + +# Configure to use the proxy +curl -s http://canonical-lxd.stgraber.org/config/snapd.sh | sh + +# Install LXD +while :; do +[ ! -e /usr/bin/lxd ] && break +apt remove --purge lxd lxd-client --yes && break +done +snap install lxd --edge +snap install jq +snap refresh lxd --channel=latest/edge +lxd waitready --timeout=300 + +# Configure LXD +lxc network create lxdbr0 +lxc profile device add default eth0 nic network=lxdbr0 + +for poolDriver in $poolDriverList +do + echo "==> Create storage pool using driver ${poolDriver}" +if [ "${poolDriver}" = "dir" ]; then + lxc storage create vmpool "${poolDriver}" + else + lxc storage create vmpool "${poolDriver}" size=20GB + fi + + echo "==> Create VM and boot" + lxc init images:ubuntu/20.04/cloud v1 --vm -s vmpool + lxc start v1 + sleep 60 + lxc info v1 + + echo "==> Checking VM root disk size is 10GB" + lxc exec v1 -- df -B10 | grep sda2 | grep 10 + + echo "==> Increasing VM root disk size for next boot" + lxc config device set v1 root size=11GB + lxc config get v1 volatile.root.apply_quota | grep 11GB + lxc stop -f v1 + lxc start v1 + sleep 60 + + echo "==> Checking VM root disk size is 11GB" + lxc exec v1 -- df -B10 | grep sda2 | grep 11 + + echo "==> Check VM shrink is blocked" + ! lxc config device set v1 root size=10GB || false + + echo "==> Deleting VM" + lxc delete -f v1 + + echo "==> Change volume.size on pool and create VM" + lxc storage set vmpool volume.size 6GB + lxc init images:ubuntu/20.04/cloud v1 --vm -s vmpool +lxc start v1 +sleep 60 +lxc info v1 + +echo "==> Checking VM root disk size is 6GB" +lxc exec v1 -- df -B10 | grep sda2 | grep 6 + +echo "==> Deleting VM and reset pool volume.size" +lxc delete -f v1 + lxc storage unset vmpool volume.size + + if [ "${poolDriver}" = "lvm" ]; then + echo "==> Change volume.block.filesystem on pool and create VM" + lxc storage set vmpool volume.block.filesystem xfs + lxc init images:ubuntu/20.04/cloud v1 --vm -s vmpool + lxc start v1 + sleep 60 + lxc info v1 + + echo "==> Checking VM config disk filesyste is XFS" + serverPID="$(lxc query /1.0 | jq .environment.server_pid)" + nsenter -m -t "${serverPID}" stat -f -c %T /var/snap/lxd/common/lxd/virtual-machines/v1 | grep xfs + + echo "==> Deleting VM" + lxc delete -f v1 + lxc storage unset vmpool volume.block.filesystem + fi + + echo "==> Create VM from profile with small disk size" + lxc profile copy default vmsmall + lxc profile device add vmsmall root disk pool=vmpool path=/ size=7GB +lxc init images:ubuntu/20.04/cloud v1 --vm -p vmsmall +lxc start v1 +sleep 60 +lxc info v1 + +echo "==> Checking VM root disk size is 7GB" +lxc exec v1 -- df -B10 | grep sda2 | grep 7 + lxc stop -f v1 + + echo "==> Copy to different storage pool and check size" + dstPoolDriver=zfs # Use ZFS storage pool as that fixed volumes not files. + if [ "${poolDriver}" = "zfs" ]; then +
[lxc-devel] [lxd/master] Storage: Allow BTRFS to detect volume.size pool changes and regeneration image volumes
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8220 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) === Fixes image volume resize errors. From c622519f3cc9260dda192811626696b8e9283c5b Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 7 Dec 2020 19:27:15 + Subject: [PATCH 1/4] lxd/storage/backend/lxd: Comment typo fix Signed-off-by: Thomas Parrott --- lxd/storage/backend_lxd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 79a72c541e..0259328829 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -2201,8 +2201,8 @@ func (b *lxdBackend) EnsureImage(fingerprint string, op *operations.Operation) e imgVol.SetConfigSize(newVolSize) - // Try applying the current size policy to the existin volume. If it is the same the driver - // should make no changes, and if not then attempt to resize it to the new policy. + // Try applying the current size policy to the existing volume. If it is the same the + // driver should make no changes, and if not then attempt to resize it to the new policy. logger.Debug("Setting image volume size", "size", imgVol.ConfigSize()) err = b.driver.SetVolumeQuota(imgVol, imgVol.ConfigSize(), op) if errors.Cause(err) == drivers.ErrCannotBeShrunk || errors.Cause(err) == drivers.ErrNotSupported { From f245258acf7e23b74d6d16e050ab9656bde99c18 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 7 Dec 2020 19:27:38 + Subject: [PATCH 2/4] lxd/storage/drivers/driver/btrfs/volumes: Enable allowUnsafeResize in CreateVolume when creating initial image volume This is so the image volume can be resized to desired size after filler has run but before readonly snapshot is created. Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_btrfs_volumes.go | 7 +++ 1 file changed, 7 insertions(+) diff --git a/lxd/storage/drivers/driver_btrfs_volumes.go b/lxd/storage/drivers/driver_btrfs_volumes.go index 3de65c5c78..687c935138 100644 --- a/lxd/storage/drivers/driver_btrfs_volumes.go +++ b/lxd/storage/drivers/driver_btrfs_volumes.go @@ -68,6 +68,13 @@ func (d *btrfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Op return err } + // Allow unsafe resize of image volumes as filler won't have been able to resize the volume to the + // target size as volume file didn't exist then (and we can't create in advance because qemu-img + // truncates the file to image size). + if vol.volType == VolumeTypeImage { + vol.allowUnsafeResize = true + } + _, err = ensureVolumeBlockFile(vol, rootBlockPath, sizeBytes) // Ignore ErrCannotBeShrunk as this just means the filler has needed to increase the volume size. From 059863e24bcca4e9f53cff413541553e8a3d6f39 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 7 Dec 2020 19:29:02 + Subject: [PATCH 3/4] lxd/storage/drivers/utils: Updates ensureVolumeBlockFile to return unsupported when trying to resize image volume without allowUnsafeResize enabled This is so the correct error response is returned to trigger backendLXD to regenerate cached BTRFS image volume when pool's volume.size changes. Doesn't affect dir pools (which also use this function) as they do not have cached image volumes. Signed-off-by: Thomas Parrott --- lxd/storage/drivers/utils.go | 7 +++ 1 file changed, 7 insertions(+) diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go index 646d10c4a4..a64635bbc2 100644 --- a/lxd/storage/drivers/utils.go +++ b/lxd/storage/drivers/utils.go @@ -347,6 +347,13 @@ func ensureVolumeBlockFile(vol Volume, path string, sizeBytes int64) (bool, erro return false, nil } + // Block image volumes cannot be resized because they can have a readonly snapshot that doesn't get + // updated when the volume's size is changed, and this is what instances are created from. + // During initial volume fill allowUnsafeResize is enabled because snapshot hasn't been taken yet. + if !vol.allowUnsafeResize && vol.volType == VolumeTypeImage { + return false, ErrNotSupported + } + // Only perform pre-resize sanity checks if we are not in "unsafe" mode. // In unsafe mode we expect the caller to know what they are doing and understand the risks. if
[lxc-devel] [lxd/master] Storage: Fixes 10s delay when using VMs with ZFS in snap
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8218 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) === This is caused because /dev/zvol appears to not be populated when using the snap. Signed-off-by: Thomas Parrott From 2c6b7c840cfd03c1328a4ec3953239116b87321a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 7 Dec 2020 11:21:40 + Subject: [PATCH] lxd/storage/drivers/drivers/zfs/volumes: Fixes 10s delay when using VMs with ZFS in snap This is caused because /dev/zvol appears to not be populated when using the snap. Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_zfs_volumes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/drivers/driver_zfs_volumes.go b/lxd/storage/drivers/driver_zfs_volumes.go index 42e8056d1b..78152519e9 100644 --- a/lxd/storage/drivers/driver_zfs_volumes.go +++ b/lxd/storage/drivers/driver_zfs_volumes.go @@ -1003,7 +1003,7 @@ func (d *zfs) SetVolumeQuota(vol Volume, size string, op *operations.Operation) // GetVolumeDiskPath returns the location of a root disk block device. func (d *zfs) GetVolumeDiskPath(vol Volume) (string, error) { // Shortcut for udev. - if tryExists(filepath.Join("/dev/zvol", d.dataset(vol, false))) { + if shared.PathExists(filepath.Join("/dev/zvol", d.dataset(vol, false))) { return filepath.Join("/dev/zvol", d.dataset(vol, false)), nil } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Instance: Fixes instanceType in instance logger
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8213 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) === Fixes issue introduced by github.com/lxc/lxd/pull/8199 Signed-off-by: Thomas Parrott From b34e3792dea0f790695a42448d464bd8eb1304b4 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 4 Dec 2020 09:07:01 + Subject: [PATCH] lxd/instance/drivers: Fixes instanceType in instance logger Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 4 ++-- lxd/instance/drivers/driver_qemu.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index 7ce44fec2b..9b1f3dd757 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -155,7 +155,7 @@ func lxcCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error) lastUsedDate: args.LastUsedDate, localConfig: args.Config, localDevices: args.Devices, - logger: logging.AddContext(logger.Log, log.Ctx{"instanceType": args.Type.String, "instance": args.Name, "project": args.Project}), + logger: logging.AddContext(logger.Log, log.Ctx{"instanceType": args.Type, "instance": args.Name, "project": args.Project}), name: args.Name, node: args.Node, profiles: args.Profiles, @@ -375,7 +375,7 @@ func lxcInstantiate(s *state.State, args db.InstanceArgs, expandedDevices device lastUsedDate: args.LastUsedDate, localConfig: args.Config, localDevices: args.Devices, - logger: logging.AddContext(logger.Log, log.Ctx{"instanceType": args.Type.String, "instance": args.Name, "project": args.Project}), + logger: logging.AddContext(logger.Log, log.Ctx{"instanceType": args.Type, "instance": args.Name, "project": args.Project}), name: args.Name, node: args.Node, profiles: args.Profiles, diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index c2f9c04b44..8a5add66c5 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -113,7 +113,7 @@ func qemuInstantiate(s *state.State, args db.InstanceArgs, expandedDevices devic lastUsedDate: args.LastUsedDate, localConfig: args.Config, localDevices: args.Devices, - logger: logging.AddContext(logger.Log, log.Ctx{"instanceType": args.Type.String, "instance": args.Name, "project": args.Project}), + logger: logging.AddContext(logger.Log, log.Ctx{"instanceType": args.Type, "instance": args.Name, "project": args.Project}), name: args.Name, node: args.Node, profiles: args.Profiles, @@ -167,7 +167,7 @@ func qemuCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error) lastUsedDate: args.LastUsedDate, localConfig: args.Config, localDevices: args.Devices, - logger: logging.AddContext(logger.Log, log.Ctx{"instanceType": args.Type.String, "instance": args.Name, "project": args.Project}), + logger: logging.AddContext(logger.Log, log.Ctx{"instanceType": args.Type, "instance": args.Name, "project": args.Project}), name: args.Name, node: args.Node, profiles: args.Profiles, ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Various minor changes
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 Date: Thu, 3 Dec 2020 16:41:50 + 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 --- 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 00..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 Date: Thu, 3 Dec 2020 16:43:07 + Subject: [PATCH 02/10] lxd/cluster/connect: Removes client type constants and helper Signed-off-by: Thomas Parrott --- 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 Date: Thu, 3 Dec 2020 16:43:42 + Subject: [PATCH 03/10] lxd: Updates use of ClientType now moved to cluster/request package Signed-off-by: Thomas Parrott --- 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 ---
[lxc-devel] [lxd/master] Cluster: Moves ClientType, its constants and helper into own package
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8211 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) === To avoid circular imports conflicts with storage package. From 891610b075f0851d272056b83d95468033b845fc Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 3 Dec 2020 16:41:50 + Subject: [PATCH 1/3] 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 --- 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 00..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 Date: Thu, 3 Dec 2020 16:43:07 + Subject: [PATCH 2/3] lxd/cluster/connect: Removes client type constants and helper Signed-off-by: Thomas Parrott --- 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 Date: Thu, 3 Dec 2020 16:43:42 + Subject: [PATCH 3/3] lxd: Updates use of ClientType now moved to cluster/request package Signed-off-by: Thomas Parrott --- 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 @@
[lxc-devel] [lxd/master] Storage: Adds storage node state to improve clustered to creation process
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8205 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) === - Adds state column to `storage_pools_nodes` table. - Modifies storage pool create process to allow per-node state tracking. - Allows fixing of per-node creation blockers when creating a storage pool in a cluster. Checks: - [ ] Check partially created storage pools stays in `pending` state, but successful nodes are marked as `created`. - [ ] Allow update of `pending` node specific config when storage pool in `pending` state. - [ ] Block update of non-node-specific config when storage pool in `pending` state. - [ ] Block rename of storage pool in `pending state`. - [ ] Run local delete process for `created` nodes when deleting storage pool in `pending` state. - [ ] Allow subsequent non-targeted storage pool create command and skip any nodes already in `created` state. - [ ] Only mark storage pool as `created` when all nodes successfully created. From 22b0b86a0507cbe1d961e540181c0ee5f77596c7 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 1 Dec 2020 10:18:28 + Subject: [PATCH 01/16] lxd/db/cluster: Adds state column to storage_pools_nodes table and set existing rows to state=1 (created) Signed-off-by: Thomas Parrott --- lxd/db/cluster/schema.go | 3 ++- lxd/db/cluster/update.go | 11 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go index 4b110c8ada..00ce7ea8d3 100644 --- a/lxd/db/cluster/schema.go +++ b/lxd/db/cluster/schema.go @@ -490,6 +490,7 @@ CREATE TABLE storage_pools_nodes ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, storage_pool_id INTEGER NOT NULL, node_id INTEGER NOT NULL, +state INTEGER NOT NULL DEFAULT 0, UNIQUE (storage_pool_id, node_id), FOREIGN KEY (storage_pool_id) REFERENCES storage_pools (id) ON DELETE CASCADE, FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE @@ -590,5 +591,5 @@ CREATE TABLE storage_volumes_snapshots_config ( UNIQUE (storage_volume_snapshot_id, key) ); -INSERT INTO schema (version, updated_at) VALUES (40, strftime("%s")) +INSERT INTO schema (version, updated_at) VALUES (41, strftime("%s")) ` diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go index 55ab9c7b8e..16efb06b34 100644 --- a/lxd/db/cluster/update.go +++ b/lxd/db/cluster/update.go @@ -77,6 +77,17 @@ var updates = map[int]schema.Update{ 38: updateFromV37, 39: updateFromV38, 40: updateFromV39, + 41: updateFromV40, +} + +// Add state column to storage_pools_nodes tables. Set existing row's state to 1 ("created"). +func updateFromV40(tx *sql.Tx) error { + stmt := ` + ALTER TABLE storage_pools_nodes ADD COLUMN state INTEGER NOT NULL DEFAULT 0; + UPDATE storage_pools_nodes SET state = 1; + ` + _, err := tx.Exec(stmt) + return err } // Add state column to networks_nodes tables. Set existing row's state to 1 ("created"). From f25eff38edd6d8b698ab2172884ec8a5e8353c96 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 1 Dec 2020 10:29:05 + Subject: [PATCH 02/16] lxd/db/networks: Updates network state comments to indicate node usage Signed-off-by: Thomas Parrott --- 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 34a75003a6..c1a1263a25 100644 --- a/lxd/db/networks.go +++ b/lxd/db/networks.go @@ -460,9 +460,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. From 01526037d71723c77129ce18ff8e2657bad0ee73 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 1 Dec 2020 10:29:30 + Subject: [PATCH 03/16] lxd/db/storage/pools: Updates storage pool state comments to indicate node usage Signed-off-by: Thomas Parrott --- lxd/db/storage_pools.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go index 76d12693d1..d676941c80 100644 --- a/lxd/db/storage_pools.go +++ b/lxd/db/storage_pools.go @@ -372,9 +372,9 @@ func (c *ClusterTx) CreateStoragePoolConfig(poolID, nodeID int64, config map[str // Storage pools state.
[lxc-devel] [lxd/master] Storage: Add default content type to /1.0/storage-pools/{name}/volumes route
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8204 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) === Fixes https://github.com/lxc/lxd/issues/8203 From d97041090a02bfd27e21c6fd950cef4eaeaaf45e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 1 Dec 2020 14:14:01 + Subject: [PATCH 1/8] lxd/storage/volumes: Replace hardcoded "filesystem" with db.StoragePoolVolumeContentTypeNameFS in storagePoolVolumesTypePost Signed-off-by: Thomas Parrott --- lxd/storage_volumes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index 2c95560f3e..dd865ccf2a 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -290,7 +290,7 @@ func storagePoolVolumesTypePost(d *Daemon, r *http.Request) response.Response { // Backward compatibility. if req.ContentType == "" { - req.ContentType = "filesystem" + req.ContentType = db.StoragePoolVolumeContentTypeNameFS } _, err = storagePools.VolumeContentTypeNameToContentType(req.ContentType) From c353cb7bf4eba967b9058a9692d485076560eb8f Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 1 Dec 2020 14:14:24 + Subject: [PATCH 2/8] lxd/storage/volumes: Error quoting in storagePoolVolumesTypePost Signed-off-by: Thomas Parrott --- lxd/storage_volumes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index dd865ccf2a..ec83cfd155 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -303,7 +303,7 @@ func storagePoolVolumesTypePost(d *Daemon, r *http.Request) response.Response { // We currently only allow to create storage volumes of type storagePoolVolumeTypeCustom. // So check, that nothing else was requested. if req.Type != db.StoragePoolVolumeTypeNameCustom { - return response.BadRequest(fmt.Errorf(`Currently not allowed to create storage volumes of type %q`, req.Type)) + return response.BadRequest(fmt.Errorf("Currently not allowed to create storage volumes of type %q", req.Type)) } poolID, err := d.cluster.GetStoragePoolID(poolName) From e9532a3f3da83473c691a23da833cf9ea8e753a9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 1 Dec 2020 14:14:35 + Subject: [PATCH 3/8] lxd/storage/volumes: Fixes misleading comment in storagePoolVolumesPost Signed-off-by: Thomas Parrott --- lxd/storage_volumes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index ec83cfd155..9143c1ed34 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -385,7 +385,7 @@ func doVolumeCreateOrCopy(d *Daemon, projectName, poolName string, req *api.Stor return operations.OperationResponse(op) } -// /1.0/storage-pools/{name}/volumes/{type} +// /1.0/storage-pools/{name}/volumes // Create a storage volume of a given volume type in a given storage pool. func storagePoolVolumesPost(d *Daemon, r *http.Request) response.Response { resp := forwardedResponseIfTargetIsRemote(d, r) From f0047ce2de38b73355dd53a4272f7beb31361755 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 1 Dec 2020 14:15:12 + Subject: [PATCH 4/8] lxd/storage/volumes: Set default volume content type to filesystem in storagePoolVolumesPost Fixes #8203 Signed-off-by: Thomas Parrott --- lxd/storage_volumes.go | 5 + 1 file changed, 5 insertions(+) diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index 9143c1ed34..9350a3270c 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -422,6 +422,11 @@ func storagePoolVolumesPost(d *Daemon, r *http.Request) response.Response { return response.BadRequest(fmt.Errorf(`Currently not allowed to create storage volumes of type %q`, req.Type)) } + // Backward compatibility. + if req.ContentType == "" { + req.ContentType = db.StoragePoolVolumeContentTypeNameFS + } + projectName, err := project.StorageVolumeProject(d.State().Cluster, projectParam(r), db.StoragePoolVolumeTypeCustom) if err != nil { return response.SmartError(err) From fe4bfde7491f24c5d4f582df07240e58c971c085 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 1 Dec 2020 14:16:00 + Subject: [PATCH 5/8] lxd/storage/volumes: Error quoting in storagePoolVolumesPost Signed-off-by: Thomas Parrott --- lxd/storage_volumes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index 9350a3270c..831f9cebde 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -419,7 +419,7 @@ func storagePoolVolumesPost(d
[lxc-devel] [lxd/master] test: Adds tests for copying instance with snapshots containing invalid disk devices
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8194 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) === Signed-off-by: Thomas Parrott From de1a496c6ba1dcef90b540259ba8fb63b5a9edc4 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 26 Nov 2020 15:59:52 + Subject: [PATCH] test/suites/migration: Adds tests for copying instance with snapshots containing invalid disk devices Signed-off-by: Thomas Parrott --- test/suites/migration.sh | 19 +++ 1 file changed, 19 insertions(+) diff --git a/test/suites/migration.sh b/test/suites/migration.sh index f2416eed6b..2e7c3bc5e0 100644 --- a/test/suites/migration.sh +++ b/test/suites/migration.sh @@ -368,6 +368,25 @@ migration() { lxc_remote project switch l1:default lxc_remote project delete l1:proj + + # Check migration with invalid snapshot config (disks attached with missing source pool and source path). + lxc_remote init testimage l1:c1 + lxc_remote storage create l1:dir dir + lxc_remote storage volume create l1:dir vol1 + lxc_remote storage volume attach l1:dir vol1 c1 /mnt + mkdir "$LXD_DIR/testvol2" + lxc_remote config device add l1:c1 vol2 disk source="$LXD_DIR/testvol2" path=/vol2 + lxc_remote snapshot l1:c1 # Take snapshot with disk devices still attached. + lxc_remote config device remove c1 vol1 + lxc_remote config device remove c1 vol2 + rmdir "$LXD_DIR/testvol2" + lxc_remote copy l1:c1 l2: + lxc_remote info l2:c1 | grep snap0 + lxc_remote delete l1:c1 -f + lxc_remote delete l2:c1 -f + lxc_remote storage volume delete l1:dir vol1 + lxc_remote storage delete l1:dir + if ! which criu >/dev/null 2>&1; then echo "==> SKIP: live migration with CRIU (missing binary)" return ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Device: Only validate disk source pool when an actual instance is set
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8193 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) === Allows for migration of instances who have snapshots with invalid devices. Fixes #8187 Signed-off-by: Thomas Parrott From 3b3590cfab36b727ec2d63e72308c8295d7254f2 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 26 Nov 2020 14:44:04 + Subject: [PATCH] lxd/device/disk: Only validate disk source pool when an actual instance is set Allows for migration of instances who have snapshots with invalid devices. Fixes #8187 Signed-off-by: Thomas Parrott --- lxd/device/disk.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/device/disk.go b/lxd/device/disk.go index da29808a40..8c405aecbc 100644 --- a/lxd/device/disk.go +++ b/lxd/device/disk.go @@ -170,7 +170,7 @@ func (d *disk) validateConfig(instConf instance.ConfigReader) error { // Only perform expensive instance custom volume checks when not validating a profile and after // device expansion has occurred (to avoid doing it twice during instance load). - if instConf.Type() != instancetype.Any && len(instConf.ExpandedDevices()) > 0 && d.config["source"] != "" && d.config["path"] != "/" { + if d.inst != nil && len(instConf.ExpandedDevices()) > 0 && d.config["source"] != "" && d.config["path"] != "/" { poolID, err := d.state.Cluster.GetStoragePoolID(d.config["pool"]) if err != nil { return fmt.Errorf("The %q storage pool doesn't exist", d.config["pool"]) ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Don't fill default config when doing an update
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8192 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) === This allows for ipv4.address and ipv6.address settings to be removed and have the effect of "none" rather than "auto". Signed-off-by: Thomas Parrott From 1e5a150f30683127ef6e2b6901e6d098c7010d97 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 26 Nov 2020 09:29:28 + Subject: [PATCH] lxd/network/driver/bridge: Don't fill default config when doing an update This allows for ipv4.address and ipv6.address settings to be removed and have the effect of "none" rather than "auto". Signed-off-by: Thomas Parrott --- lxd/network/driver_bridge.go | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lxd/network/driver_bridge.go b/lxd/network/driver_bridge.go index a3260e056a..71cde3f7dc 100644 --- a/lxd/network/driver_bridge.go +++ b/lxd/network/driver_bridge.go @@ -193,7 +193,8 @@ func (n *bridge) Validate(config map[string]string) error { }, "ipv4.address": func(value string) error { - if validate.IsOneOf(value, []string{"none", "auto"}) == nil { + // Empty is equivalent to "none". + if validate.IsOneOf(value, []string{"", "none", "auto"}) == nil { return nil } @@ -214,7 +215,8 @@ func (n *bridge) Validate(config map[string]string) error { "ipv4.ovn.ranges": validate.Optional(validate.IsNetworkRangeV4List), "ipv6.address": func(value string) error { - if validate.IsOneOf(value, []string{"none", "auto"}) == nil { + // Empty is equivalent to "none". + if validate.IsOneOf(value, []string{"", "none", "auto"}) == nil { return nil } @@ -1524,12 +1526,6 @@ func (n *bridge) Stop() error { func (n *bridge) Update(newNetwork api.NetworkPut, targetNode string, clientType cluster.ClientType) error { n.logger.Debug("Update", log.Ctx{"clientType": clientType, "newNetwork": newNetwork}) - // Populate default values if they are missing. - err := n.FillConfig(newNetwork.Config) - if err != nil { - return err - } - dbUpdateNeeeded, changedKeys, oldNetwork, err := n.common.configChanged(newNetwork) if err != nil { return err ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Storage: Allow unsafe resize when filling initial image volume
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8184 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) === Allows unpacking of images larger than default volume size (while filler function itself still checks the storage pool's `volume.size` setting to ensure no additional restrictions set). Fixes https://discuss.linuxcontainers.org/t/widnows-vm-creation-from-image-error-increasing-volume-size/9552 From 5100d11c0694b767f938eca1673bc1f71bbd6bf9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 24 Nov 2020 23:10:14 + Subject: [PATCH 1/6] lxd/instance: Use revert package in instanceCreateFromImage Signed-off-by: Thomas Parrott --- lxd/instance.go | 13 - 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lxd/instance.go b/lxd/instance.go index 45aed86b17..515f7bc414 100644 --- a/lxd/instance.go +++ b/lxd/instance.go @@ -149,14 +149,9 @@ func instanceCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, op *o return nil, errors.Wrap(err, "Failed creating instance record") } - revert := true - defer func() { - if !revert { - return - } - - inst.Delete() - }() + revert := revert.New() + defer revert.Fail() + revert.Add(func() { inst.Delete() }) err = s.Cluster.UpdateImageLastUseDate(hash, time.Now().UTC()) if err != nil { @@ -178,7 +173,7 @@ func instanceCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, op *o return nil, err } - revert = false + revert.Success() return inst, nil } From dc9de71602879cc4b137f36bac8952a11417102a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 24 Nov 2020 23:10:40 + Subject: [PATCH 2/6] lxd/storage/backend/lxd: Remove revert from CreateInstanceFromImage Expect caller to call DeleteInstance on failure (due to this function not creating the storage DB record and upstream callers are also trying to remove it on failure). Signed-off-by: Thomas Parrott --- lxd/storage/backend_lxd.go | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index a2c86b94e9..ffb6d75699 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -1003,6 +1003,7 @@ func (b *lxdBackend) imageFiller(fingerprint string, op *operations.Operation) f } // CreateInstanceFromImage creates a new volume for an instance populated with the image requested. +// On failure caller is expected to call DeleteInstance() to clean up. func (b *lxdBackend) CreateInstanceFromImage(inst instance.Instance, fingerprint string, op *operations.Operation) error { logger := logging.AddContext(b.logger, log.Ctx{"project": inst.Project(), "instance": inst.Name()}) logger.Debug("CreateInstanceFromImage started") @@ -1026,9 +1027,7 @@ func (b *lxdBackend) CreateInstanceFromImage(inst instance.Instance, fingerprint vol := b.newVolume(volType, contentType, volStorageName, rootDiskConf) - revert := revert.New() - defer revert.Fail() - revert.Add(func() { b.DeleteInstance(inst, op) }) + // Leave reverting on failure to caller, they are expected to call DeleteInstance(). // If the driver doesn't support optimized image volumes then create a new empty volume and // populate it with the contents of the image archive. @@ -1106,7 +1105,6 @@ func (b *lxdBackend) CreateInstanceFromImage(inst instance.Instance, fingerprint return err } - revert.Success() return nil } From 8edbfff9d88caa82615ef5545135d67805658ae0 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 24 Nov 2020 23:11:33 + Subject: [PATCH 3/6] lxd/storage/drivers/driver/common: Enable unsafe resize mode in runFiller when unpacking into image volumes This allows image volumes to grow to accomodate larger images even on storage drivers that usually don't allow image volumes to be resized due to their read-only snapshots, as these have not been taken yet. Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_common.go | 9 + 1 file changed, 9 insertions(+) diff --git a/lxd/storage/drivers/driver_common.go b/lxd/storage/drivers/driver_common.go index 1aaa5561fe..f34d18a972 100644 --- a/lxd/storage/drivers/driver_common.go +++ b/lxd/storage/drivers/driver_common.go @@ -242,6 +242,15 @@ func (d *common) runFiller(vol Volume, devPath string, filler *VolumeFiller) err return nil } + // Allow filler to resize initial image volume as needed. Some storage drivers don't normally allow + // image volumes to be resized due to them having read-only snapshots
[lxc-devel] [lxd/master] Instance: Centralise logic for volatile key copying
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8181 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) === From 2c9fdc5afd27c2d90dd9dfa176e2ebab8295c7e0 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 24 Nov 2020 16:46:40 + Subject: [PATCH 1/8] shared/instance: golint fixes Signed-off-by: Thomas Parrott --- shared/instance.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/instance.go b/shared/instance.go index f4ac70993b..0b4ddff8e9 100644 --- a/shared/instance.go +++ b/shared/instance.go @@ -14,8 +14,10 @@ import ( "github.com/lxc/lxd/shared/validate" ) +// InstanceAction indicates the type of action being performed. type InstanceAction string +// InstanceAction types. const ( Stop InstanceAction = "stop" StartInstanceAction = "start" From 79941f59a92d0734d4273c75fb197c85a964163c Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 24 Nov 2020 16:46:53 + Subject: [PATCH 2/8] shared/instance: Adds ConfigVolatilePrefix constant To avoid inconsistent use of "volatile" and "volatile." prefix checks. Signed-off-by: Thomas Parrott --- shared/instance.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared/instance.go b/shared/instance.go index 0b4ddff8e9..2a0986f9b8 100644 --- a/shared/instance.go +++ b/shared/instance.go @@ -26,6 +26,9 @@ const ( Unfreeze InstanceAction = "unfreeze" ) +// ConfigVolatilePrefix indicates the prefix used for volatile config keys. +const ConfigVolatilePrefix = "volatile." + // IsRootDiskDevice returns true if the given device representation is configured as root disk for // an instance. It typically get passed a specific entry of api.Instance.Devices. func IsRootDiskDevice(device map[string]string) bool { From 1e7d93cc87128b919c2d6dbe5ae280bb9d5d5476 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 24 Nov 2020 16:47:21 + Subject: [PATCH 3/8] shared/instance: ConfigVolatilePrefix usage Signed-off-by: Thomas Parrott --- shared/instance.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/instance.go b/shared/instance.go index 2a0986f9b8..000825c247 100644 --- a/shared/instance.go +++ b/shared/instance.go @@ -275,7 +275,7 @@ func ConfigKeyChecker(key string) (func(value string) error, error) { return f, nil } - if strings.HasPrefix(key, "volatile.") { + if strings.HasPrefix(key, ConfigVolatilePrefix) { if strings.HasSuffix(key, ".hwaddr") { return validate.IsAny, nil } From 91277c1649fdf97fd888d3fc9465330226292280 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 24 Nov 2020 16:47:29 + Subject: [PATCH 4/8] shared/instance: Adds InstanceIncludeWhenCopying function Brings together the volatile inclusion/exclusion logic that was spread over lxd and lxc. Signed-off-by: Thomas Parrott --- shared/instance.go | 18 ++ 1 file changed, 18 insertions(+) diff --git a/shared/instance.go b/shared/instance.go index 000825c247..c1f1483776 100644 --- a/shared/instance.go +++ b/shared/instance.go @@ -355,3 +355,21 @@ func InstanceGetParentAndSnapshotName(name string) (string, string, bool) { return fields[0], fields[1], true } + +// InstanceIncludeWhenCopying is used to decide whether to include a config item or not when copying an instance. +// The remoteCopy argument indicates if the copy is remote (i.e between LXD nodes) as this affects the keys kept. +func InstanceIncludeWhenCopying(configKey string, remoteCopy bool) bool { + if configKey == "volatile.base_image" { + return true // Include volatile.base_image always as it can help optimize copies. + } + + if configKey == "volatile.last_state.idmap" && !remoteCopy { + return true // Include volatile.last_state.idmap when doing local copy to avoid needless remapping. + } + + if strings.HasPrefix(configKey, ConfigVolatilePrefix) { + return false // Exclude all other volatile keys. + } + + return true // Keep all other keys. +} From 76dcd882dd1bef3bb9713bd223f76630b24a2ba1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 24 Nov 2020 16:48:13 + Subject: [PATCH 5/8] lxd/copy: shared.InstanceIncludeWhenCopying usage in copyInstance Signed-off-by: Thomas Parrott --- lxc/copy.go | 13 ++--- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/lxc/copy.go b/lxc/copy.go index 7b88270ee4..128c52230b 100644 --- a/lxc/copy.go +++ b/lxc/copy.go @@ -224,13 +224,8 @@ func (c *cmdCopy) copyInstance(conf *config.Config, sourceResource string, destR delete(entry.Config, "volatile.last_state.power") if !keepVolatile
[lxc-devel] [lxd/master] Network: Adds network node state to improve clustered network creation process
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8180 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) === - Adds state column to networks_nodes table. - Modifies network create process to allow per-node state tracking. - Allows fixing of per-node creation blockers when creating a network in a cluster. Related to https://github.com/lxc/lxd/issues/8111 From 94f106b017fbb3c22805898981cbeace5d67b4fe Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 20 Nov 2020 11:44:34 + Subject: [PATCH 01/37] lxd/storage/pools/utils: Updates comment and error for storagePoolCreateLocal Makes more accurate. Signed-off-by: Thomas Parrott --- lxd/storage_pools_utils.go | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go index 57cc08b74f..6ea29eb5c2 100644 --- a/lxd/storage_pools_utils.go +++ b/lxd/storage_pools_utils.go @@ -3,6 +3,8 @@ package main import ( "fmt" + "github.com/pkg/errors" + "github.com/lxc/lxd/lxd/state" storagePools "github.com/lxc/lxd/lxd/storage" "github.com/lxc/lxd/shared" @@ -95,7 +97,7 @@ func storagePoolCreateGlobal(state *state.State, req api.StoragePoolsPost) error return nil } -// This performs all non-db related work needed to create the pool. +// This performs local pool setup and updates DB record if config was changed during pool setup. func storagePoolCreateLocal(state *state.State, id int64, req api.StoragePoolsPost, isNotification bool) (map[string]string, error) { tryUndo := true @@ -145,7 +147,7 @@ func storagePoolCreateLocal(state *state.State, id int64, req api.StoragePoolsPo // Create the database entry for the storage pool. err = state.Cluster.UpdateStoragePool(req.Name, req.Description, updatedConfig) if err != nil { - return nil, fmt.Errorf("Error inserting %s into database: %s", req.Name, err) + return nil, errors.Wrapf(err, "Error updating storage pool config after local create for %q", req.Name) } } From ecc1cdb3022219c536aba6b02b2191e0fcf059a5 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 20 Nov 2020 11:46:21 + Subject: [PATCH 02/37] lxd/storage/pools: Error quoting Signed-off-by: Thomas Parrott --- lxd/storage_pools.go | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lxd/storage_pools.go b/lxd/storage_pools.go index c631d7cbc7..2e3631e676 100644 --- a/lxd/storage_pools.go +++ b/lxd/storage_pools.go @@ -182,7 +182,7 @@ func storagePoolsPost(d *Daemon, r *http.Request) response.Response { // storage config are the ones in StoragePoolNodeConfigKeys. for key := range req.Config { if !shared.StringInSlice(key, db.StoragePoolNodeConfigKeys) { - return response.SmartError(fmt.Errorf("Config key '%s' may not be used as node-specific key", key)) + return response.SmartError(fmt.Errorf("Config key %q may not be used as node-specific key", key)) } } @@ -196,7 +196,7 @@ func storagePoolsPost(d *Daemon, r *http.Request) response.Response { }) if err != nil { if err == db.ErrAlreadyDefined { - return response.BadRequest(fmt.Errorf("The storage pool already defined on node %s", targetNode)) + return response.BadRequest(fmt.Errorf("The storage pool already defined on node %q", targetNode)) } return response.SmartError(err) @@ -209,7 +209,7 @@ func storagePoolsPostCluster(d *Daemon, req api.StoragePoolsPost) error { // Check that no node-specific config key has been defined. for key := range req.Config { if shared.StringInSlice(key, db.StoragePoolNodeConfigKeys) { - return fmt.Errorf("Config key '%s' is node-specific", key) + return fmt.Errorf("Config key %q is node-specific", key) } } @@ -525,7 +525,7 @@ func storagePoolPatch(d *Daemon, r *http.Request) response.Response { func storagePoolValidateClusterConfig(reqConfig map[string]string) error { for key := range reqConfig { if shared.StringInSlice(key, db.StoragePoolNodeConfigKeys) { - return fmt.Errorf("node-specific config key %s can't be changed", key) + return fmt.Errorf("Node-specific config key %q can't be changed", key) } } return nil From 43d0cba9443e07e7f828b9495e94ae5684db4e7a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 20 Nov 2020 14:37:47 + Subject: [PATCH 03/37] lxd/db/cluster: Adds
[lxc-devel] [lxd/master] Network: Adds state column to networks_nodes table
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8178 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) === - Adds state column to networks_nodes table. - Modifies network create process to allow per-node state tracking. - Allows fixing of per-node creation blockers when creating a network in a cluster. Related to https://github.com/lxc/lxd/issues/8111 From 4694b1a5955b131848b26db418720f126cc8b6e1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 20 Nov 2020 11:44:34 + Subject: [PATCH 01/35] lxd/storage/pools/utils: Updates comment and error for storagePoolCreateLocal Makes more accurate. Signed-off-by: Thomas Parrott --- lxd/storage_pools_utils.go | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go index 57cc08b74f..6ea29eb5c2 100644 --- a/lxd/storage_pools_utils.go +++ b/lxd/storage_pools_utils.go @@ -3,6 +3,8 @@ package main import ( "fmt" + "github.com/pkg/errors" + "github.com/lxc/lxd/lxd/state" storagePools "github.com/lxc/lxd/lxd/storage" "github.com/lxc/lxd/shared" @@ -95,7 +97,7 @@ func storagePoolCreateGlobal(state *state.State, req api.StoragePoolsPost) error return nil } -// This performs all non-db related work needed to create the pool. +// This performs local pool setup and updates DB record if config was changed during pool setup. func storagePoolCreateLocal(state *state.State, id int64, req api.StoragePoolsPost, isNotification bool) (map[string]string, error) { tryUndo := true @@ -145,7 +147,7 @@ func storagePoolCreateLocal(state *state.State, id int64, req api.StoragePoolsPo // Create the database entry for the storage pool. err = state.Cluster.UpdateStoragePool(req.Name, req.Description, updatedConfig) if err != nil { - return nil, fmt.Errorf("Error inserting %s into database: %s", req.Name, err) + return nil, errors.Wrapf(err, "Error updating storage pool config after local create for %q", req.Name) } } From f30c166a542ef2fa98a7d570dc2850b668e6c2d6 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 20 Nov 2020 11:46:21 + Subject: [PATCH 02/35] lxd/storage/pools: Error quoting Signed-off-by: Thomas Parrott --- lxd/storage_pools.go | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lxd/storage_pools.go b/lxd/storage_pools.go index c631d7cbc7..2e3631e676 100644 --- a/lxd/storage_pools.go +++ b/lxd/storage_pools.go @@ -182,7 +182,7 @@ func storagePoolsPost(d *Daemon, r *http.Request) response.Response { // storage config are the ones in StoragePoolNodeConfigKeys. for key := range req.Config { if !shared.StringInSlice(key, db.StoragePoolNodeConfigKeys) { - return response.SmartError(fmt.Errorf("Config key '%s' may not be used as node-specific key", key)) + return response.SmartError(fmt.Errorf("Config key %q may not be used as node-specific key", key)) } } @@ -196,7 +196,7 @@ func storagePoolsPost(d *Daemon, r *http.Request) response.Response { }) if err != nil { if err == db.ErrAlreadyDefined { - return response.BadRequest(fmt.Errorf("The storage pool already defined on node %s", targetNode)) + return response.BadRequest(fmt.Errorf("The storage pool already defined on node %q", targetNode)) } return response.SmartError(err) @@ -209,7 +209,7 @@ func storagePoolsPostCluster(d *Daemon, req api.StoragePoolsPost) error { // Check that no node-specific config key has been defined. for key := range req.Config { if shared.StringInSlice(key, db.StoragePoolNodeConfigKeys) { - return fmt.Errorf("Config key '%s' is node-specific", key) + return fmt.Errorf("Config key %q is node-specific", key) } } @@ -525,7 +525,7 @@ func storagePoolPatch(d *Daemon, r *http.Request) response.Response { func storagePoolValidateClusterConfig(reqConfig map[string]string) error { for key := range reqConfig { if shared.StringInSlice(key, db.StoragePoolNodeConfigKeys) { - return fmt.Errorf("node-specific config key %s can't be changed", key) + return fmt.Errorf("Node-specific config key %q can't be changed", key) } } return nil From e2481e8abce41ebc3ddee524aa4164863b102715 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 20 Nov 2020 14:37:47 + Subject: [PATCH 03/35] lxd/db/cluster:
[lxc-devel] [lxd/stable-4.0] Storage: Adds custom content type for mount refcount tracking
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8172 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) === From 7cad91eccb88fc38a221d0bec30adaa2970216f1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 20 Nov 2020 10:44:38 + Subject: [PATCH 1/2] lxd/db/storage/volumes: Adds content type constants and populates ContentType field in storagePoolVolumeGetType Signed-off-by: Thomas Parrott --- lxd/db/storage_volumes.go | 19 +++ 1 file changed, 19 insertions(+) diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go index 19ba3a3045..16a834c7a6 100644 --- a/lxd/db/storage_volumes.go +++ b/lxd/db/storage_volumes.go @@ -278,6 +278,13 @@ func (c *Cluster) storagePoolVolumeGetType(project string, volumeName string, vo storageVolume.Config = volumeConfig storageVolume.Location = volumeNode + // Populate volume's ContentType based on volume type (this is before custom block volumes were supported). + // The ContentType field is used for volume mount ref counting so important it is consistently populated. + storageVolume.ContentType = StoragePoolVolumeContentTypeNameFS + if volumeType == StoragePoolVolumeTypeVM { + storageVolume.ContentType = StoragePoolVolumeContentTypeNameBlock + } + return volumeID, , nil } @@ -523,6 +530,18 @@ const ( StoragePoolVolumeTypeNameCustomstring = "custom" ) +// Content types. +const ( + StoragePoolVolumeContentTypeFS = iota + StoragePoolVolumeContentTypeBlock +) + +// Content type names. +const ( + StoragePoolVolumeContentTypeNameFSstring = "filesystem" + StoragePoolVolumeContentTypeNameBlock string = "block" +) + // StorageVolumeArgs is a value object holding all db-related details about a // storage volume. type StorageVolumeArgs struct { From 030ca18bff04fda53b351f8fc1860945345b83e0 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 20 Nov 2020 10:45:12 + Subject: [PATCH 2/2] lxd/storage/backend/lxd: Use volume's ContentType field in MountCustomVolume Signed-off-by: Thomas Parrott --- lxd/storage/backend_lxd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index f7040022c1..68948a9211 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -2923,7 +2923,7 @@ func (b *lxdBackend) MountCustomVolume(projectName, volName string, op *operatio // Get the volume name on storage. volStorageName := project.StorageVolume(projectName, volName) - vol := b.newVolume(drivers.VolumeTypeCustom, drivers.ContentTypeFS, volStorageName, volume.Config) + vol := b.newVolume(drivers.VolumeTypeCustom, drivers.ContentType(volume.ContentType), volStorageName, volume.Config) return b.driver.MountVolume(vol, op) } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Use Instance UUID for generating OVN logical switch port names
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8170 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) === - Switches new OVN instance port names to use the instance's UUID setting rather than the instance's ID property. - This is because the instance's ID property can change if the instance is recovered using `lxd import` while it is still running. - This has the knock on effect that when the running instance is eventually stopped, its OVN logical switch port is not cleaned up as the ID has changed (and it is left in the OVN NB database). - Using the `volatile.uuid` setting ensures that it will remain the same between recoveries. However this introduces a related problem. What about instances that are already started and have an OVN port name containing the instance ID from the old regime. Once this change is applied, any running instance that is stopped will then also leave its OVN port orphaned. To account for this, we lookup the external OVN port name stored in the local OVS integration bridge (that maintains the link between local veth interface and OVN logical port) at device stop time. If there is a value available we use that over the current naming regime (as it represents the actual logical switch port the device was started with) to clear up the port. If for some reason the external OVN port name is not available in the local OVS bridge (perhaps it was removed manually before shutdown) then we fallback to using the current naming regime to try and clear up the OVN port. From b730e82e3cba90255cc78987d5d615a6f0a1857e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 19 Nov 2020 16:16:27 + Subject: [PATCH 1/7] lxd/network/openvswitch/ovs: Adds InterfaceAssociatedOVNSwitchPort function Allows the retrieval of the current external OVN logical switch port associated to an OVS interface. Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovs.go | 10 ++ 1 file changed, 10 insertions(+) diff --git a/lxd/network/openvswitch/ovs.go b/lxd/network/openvswitch/ovs.go index 478d9325aa..2d66bc6eb8 100644 --- a/lxd/network/openvswitch/ovs.go +++ b/lxd/network/openvswitch/ovs.go @@ -150,6 +150,16 @@ func (o *OVS) InterfaceAssociateOVNSwitchPort(interfaceName string, ovnSwitchPor return nil } +// InterfaceAssociatedOVNSwitchPort returns the OVN switch port associated to the OVS interface. +func (o *OVS) InterfaceAssociatedOVNSwitchPort(interfaceName string) (OVNSwitchPort, error) { + ovnSwitchPort, err := shared.RunCommand("ovs-vsctl", "get", "interface", interfaceName, "external_ids:iface-id") + if err != nil { + return "", err + } + + return OVNSwitchPort(strings.TrimSpace(ovnSwitchPort)), nil +} + // ChassisID returns the local chassis ID. func (o *OVS) ChassisID() (string, error) { // ovs-vsctl's get command doesn't support its --format flag, so we always get the output quoted. From 0e05f658031a0e447a1f5467f7d9435e6fbce74d Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 19 Nov 2020 16:17:26 + Subject: [PATCH 2/7] lxd/network/driver/ovn: Updates Instance port functions to use instance UUID rather than instance ID Allows for clean removal of OVN ports after an instance has been `lxd import`ed while running (changing its instance ID). Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 20 ++-- 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 950ac04be9..4f437fdb22 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1949,8 +1949,8 @@ func (n *ovn) Update(newNetwork api.NetworkPut, targetNode string, clientType cl } // getInstanceDevicePortName returns the switch port name to use for an instance device. -func (n *ovn) getInstanceDevicePortName(instanceID int, deviceName string) openvswitch.OVNSwitchPort { - return openvswitch.OVNSwitchPort(fmt.Sprintf("%s-%d-%s", n.getIntSwitchInstancePortPrefix(), instanceID, deviceName)) +func (n *ovn) getInstanceDevicePortName(instanceUUID string, deviceName string) openvswitch.OVNSwitchPort { + return openvswitch.OVNSwitchPort(fmt.Sprintf("%s-%s-%s", n.getIntSwitchInstancePortPrefix(), instanceUUID, deviceName)) } // InstanceDevicePortValidateExternalRoutes validates the external routes for an OVN instance port. @@ -2041,7 +2041,11 @@ func (n *ovn) InstanceDevicePortValidateExternalRoutes(deviceInstance instance.I } // InstanceDevicePortAdd adds an instance device port to the internal logical switch and returns the port name. -func (n *ovn) InstanceDevicePortAdd(instanceID int, instanceName string, deviceName string, mac net.HardwareAddr, ips []net.IP, internalRoutes []*net.IPNet, externalRoutes []*net.IPNet)
[lxc-devel] [lxd/master] Storage: Adds per-drive volume default settings
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8169 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) === Fixes an issue that means that block custom volumes were incorrectly populated with filesystem options, which prevented future modification of the volume as failed validation. From 432633b96f40a2efce03dfb36bdf02228fdf386c Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 19 Nov 2020 12:42:23 + Subject: [PATCH 01/13] lxd/patches/utils: Adds legacy volumeFillDefault function for patches Signed-off-by: Thomas Parrott --- lxd/patches_utils.go | 25 + 1 file changed, 25 insertions(+) diff --git a/lxd/patches_utils.go b/lxd/patches_utils.go index 256422f32e..fa00348024 100644 --- a/lxd/patches_utils.go +++ b/lxd/patches_utils.go @@ -14,6 +14,7 @@ import ( "github.com/lxc/lxd/lxd/state" storageDrivers "github.com/lxc/lxd/lxd/storage/drivers" "github.com/lxc/lxd/shared" + "github.com/lxc/lxd/shared/api" "github.com/lxc/lxd/shared/units" ) @@ -223,3 +224,27 @@ func lvmGetLVSize(lvPath string) (string, error) { return detectedSize, nil } + +// volumeFillDefault fills default settings into a volume config. +// Deprecated. Please use FillInstanceConfig() on the storage pool. +func volumeFillDefault(config map[string]string, parentPool *api.StoragePool) error { + if parentPool.Driver == "lvm" || parentPool.Driver == "ceph" { + if config["block.filesystem"] == "" { + config["block.filesystem"] = parentPool.Config["volume.block.filesystem"] + } + if config["block.filesystem"] == "" { + // Unchangeable volume property: Set unconditionally. + config["block.filesystem"] = storageDrivers.DefaultFilesystem + } + + if config["block.mount_options"] == "" { + config["block.mount_options"] = parentPool.Config["volume.block.mount_options"] + } + if config["block.mount_options"] == "" { + // Unchangeable volume property: Set unconditionally. + config["block.mount_options"] = "discard" + } + } + + return nil +} From f0daf911c1f8ca9cf322a1184bb506eb6e1c529a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 19 Nov 2020 12:44:13 + Subject: [PATCH 02/13] lxd/patches: Updates patches to switch from driver.VolumeFillDefault to volumeFillDefault Signed-off-by: Thomas Parrott --- lxd/patches.go | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lxd/patches.go b/lxd/patches.go index ef0bbee33c..194a5695c9 100644 --- a/lxd/patches.go +++ b/lxd/patches.go @@ -877,7 +877,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string, // Initialize empty storage volume configuration for the // container. containerPoolVolumeConfig := map[string]string{} - err = driver.VolumeFillDefault(containerPoolVolumeConfig, defaultPool) + err = volumeFillDefault(containerPoolVolumeConfig, defaultPool) if err != nil { return err } @@ -965,7 +965,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string, // Initialize empty storage volume configuration for the // container. snapshotPoolVolumeConfig := map[string]string{} - err = driver.VolumeFillDefault(snapshotPoolVolumeConfig, defaultPool) + err = volumeFillDefault(snapshotPoolVolumeConfig, defaultPool) if err != nil { return err } @@ -1046,7 +1046,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string, images := append(imgPublic, imgPrivate...) for _, img := range images { imagePoolVolumeConfig := map[string]string{} - err = driver.VolumeFillDefault(imagePoolVolumeConfig, defaultPool) + err = volumeFillDefault(imagePoolVolumeConfig, defaultPool) if err != nil { return err } @@ -1167,7 +1167,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d // Initialize empty storage volume configuration for the // container. containerPoolVolumeConfig := map[string]string{} - err = driver.VolumeFillDefault(containerPoolVolumeConfig, defaultPool) + err =
[lxc-devel] [lxd/master] Tp storage shiftfs debug
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8165 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) === From 524ca2a0d739e544374e59219befd8849855e8c3 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 17 Nov 2020 19:48:12 + Subject: [PATCH 1/2] debug start failure Signed-off-by: Thomas Parrott --- test/suites/container_devices_disk.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/suites/container_devices_disk.sh b/test/suites/container_devices_disk.sh index 7f80bc1ec7..fc6fc1b12f 100644 --- a/test/suites/container_devices_disk.sh +++ b/test/suites/container_devices_disk.sh @@ -30,7 +30,8 @@ test_container_devices_disk_shift() { [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false lxc stop foo -f - lxc start foo + lxc start foo || true + lxc info --show-log foo [ "$(lxc exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false lxc config device remove foo shiftfs lxc stop foo -f From 4ce98cc36d78a52690a3875871d34c1d2767635e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 17 Nov 2020 19:50:27 + Subject: [PATCH 2/2] disable all but disk checks Signed-off-by: Thomas Parrott --- test/main.sh | 230 +-- 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/test/main.sh b/test/main.sh index 56466e0147..f3cb5bbecb 100755 --- a/test/main.sh +++ b/test/main.sh @@ -154,122 +154,122 @@ if [ "$#" -gt 0 ]; then exit fi -run_test test_check_deps "checking dependencies" -run_test test_static_analysis "static analysis" -run_test test_database_update "database schema updates" -run_test test_database_restore "database restore" -run_test test_database_no_disk_space "database out of disk space" -run_test test_sql "lxd sql" -run_test test_basic_usage "basic usage" -run_test test_remote_url "remote url handling" -run_test test_remote_admin "remote administration" -run_test test_remote_usage "remote usage" -run_test test_clustering_enable "clustering enable" -run_test test_clustering_membership "clustering membership" -run_test test_clustering_containers "clustering containers" -run_test test_clustering_storage "clustering storage" -run_test test_clustering_storage_single_node "clustering storage single node" -run_test test_clustering_network "clustering network" -run_test test_clustering_publish "clustering publish" -run_test test_clustering_profiles "clustering profiles" -run_test test_clustering_join_api "clustering join api" -run_test test_clustering_shutdown_nodes "clustering shutdown" -run_test test_clustering_projects "clustering projects" -run_test test_clustering_address "clustering address" -run_test test_clustering_image_replication "clustering image replication" -run_test test_clustering_dns "clustering DNS" -run_test test_clustering_recover "clustering recovery" -run_test test_clustering_handover "clustering handover" -run_test test_clustering_rebalance "clustering rebalance" -run_test test_clustering_remove_raft_node "custering remove raft node" -run_test test_clustering_failure_domains "clustering failure domains" -# run_test test_clustering_upgrade "clustering upgrade" -run_test test_projects_default "default project" -run_test test_projects_crud "projects CRUD operations" -run_test test_projects_containers "containers inside projects" -run_test test_projects_snapshots "snapshots inside projects" -run_test test_projects_backups "backups inside projects" -run_test test_projects_profiles "profiles inside projects" -run_test test_projects_profiles_default "profiles from the global default project" -run_test test_projects_images "images inside projects" -run_test test_projects_images_default "images from the global default project" -run_test test_projects_storage "projects and storage pools" -run_test test_projects_network "projects and networks" -run_test test_projects_limits "projects limits" -run_test test_projects_restrictions "projects restrictions" +#run_test test_check_deps "checking dependencies" +#run_test test_static_analysis "static analysis" +#run_test test_database_update "database schema updates" +#run_test test_database_restore "database restore" +#run_test test_database_no_disk_space "database out of disk space" +#run_test test_sql "lxd sql" +#run_test test_basic_usage "basic usage" +#run_test test_remote_url "remote url handling" +#run_test test_remote_admin "remote administration" +#run_test test_remote_usage "remote usage" +#run_test test_clustering_enable "clustering enable" +#run_test test_clustering_membership "clustering membership" +#run_test test_clustering_containers "clustering containers" +#run_test test_clustering_storage "clustering storage" +#run_test test_clustering_storage_single_node "clustering storage single node" +#run_test
[lxc-devel] [lxd/master] Network: Don't fail when resetting SRIOV VF MAC to 00:00:00:00:00:00
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8164 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) === Apparently the bnx2x devices don't allow this. Fixes #8162 Signed-off-by: Thomas Parrott From f41c8ef7f40497e2ccdbcc8b8e1e8a8e7964dc56 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 17 Nov 2020 16:50:34 + Subject: [PATCH] lxd/device/nic/sriov: Don't fail when resetting VF MAC to 00:00:00:00:00:00 Apparently the bnx2x devices don't allow this. Fixes #8162 Signed-off-by: Thomas Parrott --- lxd/device/nic_sriov.go | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lxd/device/nic_sriov.go b/lxd/device/nic_sriov.go index fe358a3252..5e7a447401 100644 --- a/lxd/device/nic_sriov.go +++ b/lxd/device/nic_sriov.go @@ -461,11 +461,9 @@ func (d *nicSRIOV) setupSriovParent(vfDevice string, vfID int, volatile map[stri return vfPCIDev, err } } else { - // Reset VF to ensure no previous MAC restriction exists. - _, err := shared.TryRunCommand("ip", "link", "set", "dev", d.config["parent"], "vf", volatile["last_state.vf.id"], "mac", "00:00:00:00:00:00") - if err != nil { - return vfPCIDev, err - } + // Try to reset VF to ensure no previous MAC restriction exists, as some devices require this + // before being able to set a new VF MAC. However some devices don't allow it so ignore failures. + shared.TryRunCommand("ip", "link", "set", "dev", d.config["parent"], "vf", volatile["last_state.vf.id"], "mac", "00:00:00:00:00:00") // Ensure spoof checking is disabled if not enabled in instance. _, err = shared.TryRunCommand("ip", "link", "set", "dev", d.config["parent"], "vf", volatile["last_state.vf.id"], "spoofchk", "off") ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Storage: Support profile updates for VMs
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8163 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) === From b62438c41c6b51c9776b8af468d84fbb51ccd9fa Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 17 Nov 2020 11:26:09 + Subject: [PATCH 1/5] lxd/images: Add word "Image" to log line to give context Signed-off-by: Thomas Parrott --- lxd/images.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/images.go b/lxd/images.go index 4fb55b9087..123ac310d6 100644 --- a/lxd/images.go +++ b/lxd/images.go @@ -1241,7 +1241,7 @@ func autoUpdateImage(d *Daemon, op *operations.Operation, id int, info *api.Imag hash = newInfo.Fingerprint if hash == fingerprint { - logger.Debug("Already up to date", log.Ctx{"fp": fingerprint}) + logger.Debug("Image already up to date", log.Ctx{"fp": fingerprint}) continue } From 3833ce4d916d0d603713dc1f5ecb6b1a9611e35a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 17 Nov 2020 11:27:07 + Subject: [PATCH 2/5] lxd/daemon/images: Add contextual logging and use "fp" rather than "image" for consistency with other code areas Signed-off-by: Thomas Parrott --- lxd/daemon_images.go | 30 -- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/lxd/daemon_images.go b/lxd/daemon_images.go index 3a5b244d7e..a491ae4f4e 100644 --- a/lxd/daemon_images.go +++ b/lxd/daemon_images.go @@ -173,41 +173,45 @@ func (d *Daemon) ImageDownload(op *operations.Operation, server string, protocol } if imgInfo != nil { - logger.Debugf("Image %q already exists in the DB", fp) info = imgInfo + ctxMap = log.Ctx{"fp": info.Fingerprint} + logger.Debug("Image already exists in the DB", ctxMap) // If not requested in a particular pool, we're done. if storagePool == "" { return info, nil } - // Get the ID of the target storage pool + ctxMap["pool"] = storagePool + + // Get the ID of the target storage pool. poolID, err := d.cluster.GetStoragePoolID(storagePool) if err != nil { return nil, err } - // Check if the image is already in the pool + // Check if the image is already in the pool. poolIDs, err := d.cluster.GetPoolsWithImage(info.Fingerprint) if err != nil { return nil, err } if shared.Int64InSlice(poolID, poolIDs) { - logger.Debugf("Image already exists on storage pool %q", storagePool) + logger.Debug("Image already exists on storage pool", ctxMap) return info, nil } - // Import the image in the pool - logger.Debugf("Image does not exist on storage pool %q", storagePool) + // Import the image in the pool. + logger.Debug("Image does not exist on storage pool", ctxMap) err = imageCreateInPool(d, info, storagePool) if err != nil { - logger.Debugf("Failed to create image on storage pool %q: %v", storagePool, err) - return nil, err + ctxMap["err"] = err + logger.Debug("Failed to create image on storage pool", ctxMap) + return nil, errors.Wrapf(err, "Failed to create image %q on storage pool %q", info.Fingerprint, storagePool) } - logger.Debugf("Created image on storage pool %q", storagePool) + logger.Debugf("Created image on storage pool", ctxMap) return info, nil } @@ -217,9 +221,7 @@ func (d *Daemon) ImageDownload(op *operations.Operation, server string, protocol // We are already downloading the image imagesDownloadingLock.Unlock() - logger.Debug( - "Already downloading the image, waiting for it to succeed", - log.Ctx{"image": fp}) + logger.Debug("Already downloading the image, waiting for it to succeed", log.Ctx{"fp": fp}) // Wait until the download finishes (channel closes) <-waitChannel @@ -228,7 +230,7 @@ func (d *Daemon) ImageDownload(op *operations.Operation, server string, protocol _, imgInfo, err := d.cluster.GetImage(project, fp, false) if err != nil { // Other download
[lxc-devel] [lxd/master] Storage: Fixes migration quota
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8161 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) === From 02249b25f207f647f1d63c7e60d919607ea81f0e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 16 Nov 2020 11:27:07 + Subject: [PATCH 1/7] lxd/device/nic/ovn: Removes unused Add function Same as common device's Add function. Signed-off-by: Thomas Parrott --- lxd/device/nic_ovn.go | 5 - 1 file changed, 5 deletions(-) diff --git a/lxd/device/nic_ovn.go b/lxd/device/nic_ovn.go index 5eb94e5125..48bc65fd4d 100644 --- a/lxd/device/nic_ovn.go +++ b/lxd/device/nic_ovn.go @@ -212,11 +212,6 @@ func (d *nicOVN) CanHotPlug() (bool, []string) { return true, []string{} } -// Add is run when a device is added to an instance whether or not the instance is running. -func (d *nicOVN) Add() error { - return nil -} - // Start is run when the device is added to a running instance or instance is starting up. func (d *nicOVN) Start() (*deviceConfig.RunConfig, error) { err := d.validateEnvironment() From 86cf7529e400d342ef41e42eb967ac17d232f036 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 16 Nov 2020 11:27:32 + Subject: [PATCH 2/7] lxd/device/nic/bridged: Clarifies when device's Add function is called Signed-off-by: Thomas Parrott --- lxd/device/nic_bridged.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go index b6c339de3f..f4b6144adf 100644 --- a/lxd/device/nic_bridged.go +++ b/lxd/device/nic_bridged.go @@ -221,7 +221,7 @@ func (d *nicBridged) CanHotPlug() (bool, []string) { return true, []string{"limits.ingress", "limits.egress", "limits.max", "ipv4.routes", "ipv6.routes", "ipv4.address", "ipv6.address", "security.mac_filtering", "security.ipv4_filtering", "security.ipv6_filtering"} } -// Add is run when a device is added to an instance whether or not the instance is running. +// Add is run when a device is added to a non-snapshot instance whether or not the instance is running. func (d *nicBridged) Add() error { // Rebuild dnsmasq entry if needed and reload. err := d.rebuildDnsmasqEntry() From 656de3fac283129b9ee5a4d2927be6dafa375490 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 16 Nov 2020 13:00:16 + Subject: [PATCH 3/7] lxd/migrate/instance: Improves comments when instantiating migration.VolumeTargetArgs Signed-off-by: Thomas Parrott --- lxd/migrate_instance.go | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lxd/migrate_instance.go b/lxd/migrate_instance.go index f633eae312..2f5f970818 100644 --- a/lxd/migrate_instance.go +++ b/lxd/migrate_instance.go @@ -872,10 +872,10 @@ func (c *migrationSink) Do(state *state.State, migrateOp *operations.Operation) volTargetArgs := migration.VolumeTargetArgs{ Name: args.Instance.Name(), MigrationType: respTypes[0], - Refresh: args.Refresh, // Indicate to receiver volume should exist. - TrackProgress: false,// Do not use a progress tracker on receiver. - Live: args.Live,// Indicates we will get a final rootfs sync. - VolumeSize:args.VolumeSize, + Refresh: args.Refresh,// Indicate to receiver volume should exist. + TrackProgress: false, // Do not use a progress tracker on receiver. + Live: args.Live, // Indicates we will get a final rootfs sync. + VolumeSize:args.VolumeSize, // Block size setting override. } // At this point we have already figured out the parent container's root @@ -1045,7 +1045,7 @@ func (c *migrationSink) Do(state *state.State, migrateOp *operations.Operation) Refresh: c.refresh, RsyncFeatures: rsyncFeatures, Snapshots: snapshots, - VolumeSize:offerHeader.GetVolumeSize(), + VolumeSize:offerHeader.GetVolumeSize(), // Block size setting override. } err = myTarget(fsConn, migrateOp, args) From 14ae58156cea7864c36880cb5356ac36b73b0577 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 16 Nov 2020 13:00:52 + Subject: [PATCH 4/7] lxd/storage/backend/lxd: Improves comments when instantiating migration.VolumeTargetArgs Signed-off-by: Thomas Parrott --- lxd/storage/backend_lxd.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git
[lxc-devel] [lxd/master] Instance: Adds volatile.uuid key for container and VMs, replaces volatile.vm.uuid for VMs
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8157 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) === - Tested patch on running VMs with the `volatile.vm.uuid` key with and without snapshots to check they all get renamed. From cfa1d01ef9de7c93b034103905a92f45d55a0f73 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 13 Nov 2020 15:37:43 + Subject: [PATCH 1/8] lxd/patches: Adds patchVMRenameUUIDKey patch to renane config key from volatile.vm.uuid to volatile.uuid Brings into line with container's `volatile.uuid` key. Signed-off-by: Thomas Parrott --- lxd/patches.go | 52 ++ 1 file changed, 52 insertions(+) diff --git a/lxd/patches.go b/lxd/patches.go index d3ca662f9b..e0569dafee 100644 --- a/lxd/patches.go +++ b/lxd/patches.go @@ -116,6 +116,7 @@ var patches = []patch{ {name: "network_ovn_remove_routes", stage: patchPostDaemonStorage, run: patchNetworkOVNRemoveRoutes}, {name: "network_fan_enable_nat", stage: patchPostDaemonStorage, run: patchNetworkFANEnableNAT}, {name: "thinpool_typo_fix", stage: patchPostDaemonStorage, run: patchThinpoolTypoFix}, + {name: "vm_rename_uuid_key", stage: patchPostDaemonStorage, run: patchVMRenameUUIDKey}, } type patch struct { @@ -180,6 +181,57 @@ func patchesApply(d *Daemon, stage patchStage) error { // Patches begin here +// patchVMRenameUUIDKey renames the volatile.vm.uuid key to volatile.uuid. +func patchVMRenameUUIDKey(name string, d *Daemon) error { + oldUUIDKey := "volatile.vm.uuid" + newUUIDKey := "volatile.uuid" + + return d.State().Cluster.InstanceList(func(inst db.Instance, p api.Project, profiles []api.Profile) error { + if inst.Type != instancetype.VM { + return nil + } + + return d.State().Cluster.Transaction(func(tx *db.ClusterTx) error { + uuid := inst.Config[oldUUIDKey] + if uuid != "" { + changes := map[string]string{ + oldUUIDKey: "", + newUUIDKey: uuid, + } + + logger.Debugf("Renaming config key %q to %q for VM %q (Project %q)", oldUUIDKey, newUUIDKey, inst.Name, inst.Project) + err := tx.UpdateInstanceConfig(inst.ID, changes) + if err != nil { + return errors.Wrapf(err, "Failed renaming config key %q to %q for VM %q (Project %q)", oldUUIDKey, newUUIDKey, inst.Name, inst.Project) + } + } + + snaps, err := tx.GetInstanceSnapshotsWithName(inst.Project, inst.Name) + if err != nil { + return err + } + + for _, snap := range snaps { + uuid := snap.Config[oldUUIDKey] + if uuid != "" { + changes := map[string]string{ + oldUUIDKey: "", + newUUIDKey: uuid, + } + + logger.Debugf("Renaming config key %q to %q for VM %q (Project %q)", oldUUIDKey, newUUIDKey, inst.Name, inst.Project) + err = tx.UpdateInstanceSnapshotConfig(snap.ID, changes) + if err != nil { + return errors.Wrapf(err, "Failed renaming config key %q to %q for VM %q (Project %q)", oldUUIDKey, newUUIDKey, inst.Name, inst.Project) + } + } + } + + return nil + }) + }) +} + // patchThinpoolTypoFix renames any config incorrectly set config file entries due to the lvm.thinpool_name typo. func patchThinpoolTypoFix(name string, d *Daemon) error { revert := revert.New() From 79a0fecff37d6e0a42ef9d84293439defcdabdcf Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 13 Nov 2020 14:48:19 + Subject: [PATCH 2/8] shared/validate: Adds IsUUID function Signed-off-by: Thomas Parrott --- shared/validate/validate.go | 11 +++ 1 file changed, 11 insertions(+) diff --git a/shared/validate/validate.go b/shared/validate/validate.go index 2a84a2bf3e..70ac4ef807 100644 --- a/shared/validate/validate.go +++ b/shared/validate/validate.go @@ -7,6 +7,8 @@ import ( "strconv" "strings" +
[lxc-devel] [lxd/master] Container: Pass name rather than ID to LXC start, stopns and stop hooks
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8155 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) === This change ensures that if the instance ID changes while it is running (which can happen if one performs an `lxd import` over the top of a running container) that the container's stop hooks will still be able to find the instance by name and be able to cleanly shutdown. The start hook is also updated for consistency with the others. All 3 hooks still handle being passed instance ID in order to allow clean shutdown of instances started before this change. From d9d2a053653613b8ad593fbcbacd93dbecb3ec19 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 13 Nov 2020 12:00:31 + Subject: [PATCH 1/4] lxd/instance/drivers/driver/lxc: Updates initLXC to use project and instance name in callhook hook commands Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index 101a0078d7..4645fc6dc1 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -943,17 +943,20 @@ func (c *lxc) initLXC(config bool) error { return err } - err = lxcSetConfigItem(cc, "lxc.hook.pre-start", fmt.Sprintf("/proc/%d/exe callhook %s %d start", os.Getpid(), shared.VarPath(""), c.id)) + // Call the onstart hook on start. + err = lxcSetConfigItem(cc, "lxc.hook.pre-start", fmt.Sprintf("/proc/%d/exe callhook %s %s %s start", os.Getpid(), shared.VarPath(""), strconv.Quote(c.Project()), strconv.Quote(c.Name( if err != nil { return err } - err = lxcSetConfigItem(cc, "lxc.hook.stop", fmt.Sprintf("%s callhook %s %d stopns", c.state.OS.ExecPath, shared.VarPath(""), c.id)) + // Call the onstopns hook on stop but before namespaces are unmounted. + err = lxcSetConfigItem(cc, "lxc.hook.stop", fmt.Sprintf("%s callhook %s %s %s stopns", c.state.OS.ExecPath, shared.VarPath(""), strconv.Quote(c.Project()), strconv.Quote(c.Name( if err != nil { return err } - err = lxcSetConfigItem(cc, "lxc.hook.post-stop", fmt.Sprintf("%s callhook %s %d stop", c.state.OS.ExecPath, shared.VarPath(""), c.id)) + // Call the onstop hook on stop. + err = lxcSetConfigItem(cc, "lxc.hook.post-stop", fmt.Sprintf("%s callhook %s %s %s stop", c.state.OS.ExecPath, shared.VarPath(""), strconv.Quote(c.Project()), strconv.Quote(c.Name( if err != nil { return err } From 25bf93b31a892f662de892f6c4b4c0ef86e8f468 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 13 Nov 2020 12:01:12 + Subject: [PATCH 2/4] lxd/instance/drivers/driver/lxc: Updates startCommon to quote hook command arguments Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index 4645fc6dc1..4705a36d90 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -2187,19 +2187,19 @@ func (c *lxc) startCommon() (string, []func() error, error) { if c.state.OS.Shiftfs && !c.IsPrivileged() && diskIdmap == nil { // Host side mark mount. - err = lxcSetConfigItem(c.c, "lxc.hook.pre-start", fmt.Sprintf("/bin/mount -t shiftfs -o mark,passthrough=3 %s %s", c.RootfsPath(), c.RootfsPath())) + err = lxcSetConfigItem(c.c, "lxc.hook.pre-start", fmt.Sprintf("/bin/mount -t shiftfs -o mark,passthrough=3 %s %s", strconv.Quote(c.RootfsPath()), strconv.Quote(c.RootfsPath( if err != nil { return "", nil, errors.Wrapf(err, "Failed to setup device mount shiftfs '%s'", dev.Name) } // Container side shift mount. - err = lxcSetConfigItem(c.c, "lxc.hook.pre-mount", fmt.Sprintf("/bin/mount -t shiftfs -o passthrough=3 %s %s", c.RootfsPath(), c.RootfsPath())) + err = lxcSetConfigItem(c.c, "lxc.hook.pre-mount", fmt.Sprintf("/bin/mount -t shiftfs -o passthrough=3 %s %s", strconv.Quote(c.RootfsPath()), strconv.Quote(c.RootfsPath( if err != nil { return "", nil, errors.Wrapf(err, "Failed to setup device mount shiftfs '%s'", dev.Name) } // Host side umount of mark mount. -
[lxc-devel] [lxd/master] Project: Reject quotes in project names
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8154 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) === This is because some storage drivers cannot support quotes in the volume name. Also AppArmor policies do not support double quotes in their names. Signed-off-by: Thomas Parrott From 4288422d191c7b47e268464f383903c7f4c953e5 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 13 Nov 2020 14:20:23 + Subject: [PATCH] lxd/api/project: Reject quotes in project names This is because some storage drivers cannot support quotes in the volume name. Also AppArmor policies do not support double quotes in their names. Signed-off-by: Thomas Parrott --- lxd/api_project.go | 4 1 file changed, 4 insertions(+) diff --git a/lxd/api_project.go b/lxd/api_project.go index 5f22f62667..85de1f61b2 100644 --- a/lxd/api_project.go +++ b/lxd/api_project.go @@ -587,6 +587,10 @@ func projectValidateName(name string) error { return fmt.Errorf("Project names may not contain spaces") } + if strings.Contains(name, "'") || strings.Contains(name, `"`) { + return fmt.Errorf("Project names may not contain quotes") + } + if name == "*" { return fmt.Errorf("Reserved project name") } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Storage: Mount reference counting
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8147 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) === Introduces the concept of storage volume mount/unmount reference counting. When a storage volume is mounted for the first time, a global reference counter is created and incremented to 1. If other operations on the storage volume also need it while it is already mounted, then subsequent requests to mount the volume will just increment the reference counter again. Then once each operation has finished with the volume they unmount the volume, and the reference counter is decremented. If the reference counter is not yet at zero, then other operations are still using the volume and an `ErrInUse` error is returned. The last unmount request that detects the reference counter is at zero will actually perform the unmount of the volume. This work was done primarily to address the following group of issues related to copying ZFS VM snapshot as another instance: - https://github.com/lxc/lxd/issues/8113 - https://discuss.linuxcontainers.org/t/copying-vm-snapshot-to-other-host-not-working-attempts-to-create-a-container/9363 - https://discuss.linuxcontainers.org/t/lxc-copy-container-ok-lxc-copy-vm-fails-with-failed-to-mount-permission-denied/9237 Reference counting is required to solve these problems because in order to activate a ZFS block volume snapshot, the parent volume also needs to be activated. However the current storage interface didn't provide a clean way for the parent volume to be unmounted (if needed) once the snapshot volume was unmounted. By introducing reference counters we can just request that the parent volume always be unmounted when unmounting a snapshot, and if others are using it, the unmount request will fail. However reference counting also helps with several other classes of problems: - Instance file operations (push/pull/delete etc) while the instance is running. - Detecting when a custom volume is mounted in multiple running instances and deciding whether to unmount when one instance is stopped (which was causing shutdown delays and errors). In order to support reference counting, everywhere that mounts a volume needed to be reviewed to ensure that where appropriate the equivalent unmount request was made when the operation completed, otherwise the reference counter would not be decremented and the volume would be left mounted. From 47904e03ef85f80fbfbfe7461314a3cdde36c84a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 10 Nov 2020 11:34:46 + Subject: [PATCH 01/39] lxd/storage/drivers/driver/zfs/volumes: Remove workarounds for snapshot volume mounting And unmount parent volume when unmounting snapshot volume (to undo parent volume activation). Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_zfs_volumes.go | 48 +++ 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/lxd/storage/drivers/driver_zfs_volumes.go b/lxd/storage/drivers/driver_zfs_volumes.go index 463c97114b..07ae48a883 100644 --- a/lxd/storage/drivers/driver_zfs_volumes.go +++ b/lxd/storage/drivers/driver_zfs_volumes.go @@ -1215,18 +1215,6 @@ func (d *zfs) RenameVolume(vol Volume, newVolName string, op *operations.Operati func (d *zfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *migration.VolumeSourceArgs, op *operations.Operation) error { // Handle simple rsync and block_and_rsync through generic. if volSrcArgs.MigrationType.FSType == migration.MigrationFSType_RSYNC || volSrcArgs.MigrationType.FSType == migration.MigrationFSType_BLOCK_AND_RSYNC { - // Before doing a generic volume migration, we need to ensure volume (or snap volume parent) is - // activated to avoid issues activating the snapshot volume device. - parent, _, _ := shared.InstanceGetParentAndSnapshotName(vol.Name()) - parentVol := NewVolume(d, d.Name(), vol.volType, vol.contentType, parent, vol.config, vol.poolConfig) - ourMount, err := d.MountVolume(parentVol, op) - if err != nil { - return err - } - if ourMount { - defer d.UnmountVolume(parentVol, false, op) - } - return genericVFSMigrateVolume(d, d.state, vol, conn, volSrcArgs, op) } else if volSrcArgs.MigrationType.FSType != migration.MigrationFSType_ZFS { return ErrNotSupported @@ -1317,21 +1305,6 @@ func (d *zfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *mig func (d *zfs) BackupVolume(vol Volume, tarWriter *instancewriter.InstanceTarWriter, optimized bool, snapshots bool, op *operations.Operation) error { // Handle the non-optimized tarballs through the
[lxc-devel] [lxd/master] Container: Stop non-NIC devices after container fully stopped
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8136 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) === Avoid disk device cleanup issues due to container mounts still being active. From bf653a26f2c1251e67566736c841d894eaf8fed9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 10 Nov 2020 12:21:46 + Subject: [PATCH 1/2] lxd/instance/drivers/driver/lxc: Stop devices in two phases - Continue stopping NICs in the OnStopNS hook. - Stop all other devices in the OnStop hook after the container has been fully stopped. This is to prevent issues unmounting disk devices when the container hasn't been stopped yet. Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 53 -- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index faf251a23e..282c4937b2 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -1578,7 +1578,9 @@ func (c *lxc) deviceUpdate(deviceName string, rawConfig deviceConfig.Device, old } // deviceStop loads a new device and calls its Stop() function. -func (c *lxc) deviceStop(deviceName string, rawConfig deviceConfig.Device, stopHookNetnsPath string) error { +// Accepts a stopHookNetnsPath argument which is required when run from the onStopNS hook before the +// container's network namespace is unmounted (which is required for NIC device cleanup). +func (c *lxc) deviceStop(deviceName string, rawConfig deviceConfig.Device, instanceRunning bool, stopHookNetnsPath string) error { logger := logging.AddContext(logger.Log, log.Ctx{"device": deviceName, "type": rawConfig["type"], "project": c.Project(), "instance": c.Name()}) logger.Debug("Stopping device") @@ -1604,7 +1606,7 @@ func (c *lxc) deviceStop(deviceName string, rawConfig deviceConfig.Device, stopH canHotPlug, _ := d.CanHotPlug() // An empty netns path means we haven't been called from the LXC stop hook, so are running. - if stopHookNetnsPath == "" && !canHotPlug { + if instanceRunning && !canHotPlug { return fmt.Errorf("Device cannot be stopped when container is running") } @@ -1616,14 +1618,14 @@ func (c *lxc) deviceStop(deviceName string, rawConfig deviceConfig.Device, stopH if runConf != nil { // If network interface settings returned, then detach NIC from container. if len(runConf.NetworkInterface) > 0 { - err = c.deviceDetachNIC(configCopy, runConf.NetworkInterface, stopHookNetnsPath) + err = c.deviceDetachNIC(configCopy, runConf.NetworkInterface, instanceRunning, stopHookNetnsPath) if err != nil { return err } } // Add cgroup rules if requested and container is running. - if len(runConf.CGroups) > 0 && stopHookNetnsPath == "" { + if len(runConf.CGroups) > 0 && instanceRunning { err = c.deviceAddCgroupRules(runConf.CGroups) if err != nil { return err @@ -1631,7 +1633,7 @@ func (c *lxc) deviceStop(deviceName string, rawConfig deviceConfig.Device, stopH } // Detach mounts if requested and container is running. - if len(runConf.Mounts) > 0 && stopHookNetnsPath == "" { + if len(runConf.Mounts) > 0 && instanceRunning { err = c.deviceHandleMounts(runConf.Mounts) if err != nil { return err @@ -1649,7 +1651,9 @@ func (c *lxc) deviceStop(deviceName string, rawConfig deviceConfig.Device, stopH } // deviceDetachNIC detaches a NIC device from a container. -func (c *lxc) deviceDetachNIC(configCopy map[string]string, netIF []deviceConfig.RunConfigItem, stopHookNetnsPath string) error { +// Accepts a stopHookNetnsPath argument which is required when run from the onStopNS hook before the +// container's network namespace is unmounted (which is required for NIC device cleanup). +func (c *lxc) deviceDetachNIC(configCopy map[string]string, netIF []deviceConfig.RunConfigItem, instanceRunning bool, stopHookNetnsPath string) error { // Get requested device name to detach interface back to on the host. devName := "" for _, dev := range netIF { @@ -1664,7 +1668,7 @@ func (c *lxc) deviceDetachNIC(configCopy map[string]string, netIF []deviceConfig } // If container is running, perform live detach of interface back to host. - if stopHookNetnsPath == "" { + if instanceRunning { //
[lxc-devel] [lxd/master] Storage: Adds volume mount & unmount locking
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8135 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) === From 1f462d7515ecf46ab670d30c5604dd55f0ca6b66 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 9 Nov 2020 17:23:29 + Subject: [PATCH 1/7] lxd/locking/lock: Adds UnlockFunc type and updates Lock() signature Signed-off-by: Thomas Parrott --- lxd/locking/lock.go | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lxd/locking/lock.go b/lxd/locking/lock.go index 02c0ec992d..054d60c174 100644 --- a/lxd/locking/lock.go +++ b/lxd/locking/lock.go @@ -13,10 +13,13 @@ var locks = map[string]chan struct{}{} // locksMutex is used to access locks safely. var locksMutex sync.Mutex +// UnlockFunc unlocks the lock. +type UnlockFunc func() + // Lock creates a lock for a specific storage volume to allow activities that require exclusive access to occur. // Will block until the lock is established. On success, it returns an unlock function which needs to be called to // unlock the lock. -func Lock(lockName string) func() { +func Lock(lockName string) UnlockFunc { for { // Get exclusive access to the map and see if there is already an operation ongoing. locksMutex.Lock() From 84c6e7f0974e90827159acef204f4456803cb416 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 9 Nov 2020 17:24:31 + Subject: [PATCH 2/7] lxd/storage/drivers/utils: Extends OperationLockName to take into account content type. Also re-arranges arguments to be hierarchical and to include specific types where possible to avoid confusion. Signed-off-by: Thomas Parrott --- lxd/storage/drivers/utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go index de985134bb..09e10212b7 100644 --- a/lxd/storage/drivers/utils.go +++ b/lxd/storage/drivers/utils.go @@ -812,6 +812,6 @@ func PathNameDecode(text string) string { } // OperationLockName returns the storage specific lock name to use with locking package. -func OperationLockName(poolName string, volType string, volName string) string { - return fmt.Sprintf("%s/%s/%s", poolName, volType, volName) +func OperationLockName(operationName string, poolName string, volType VolumeType, contentType ContentType, volName string) string { + return fmt.Sprintf("%s/%s/%s/%s/%s", operationName, poolName, volType, contentType, volName) } From 865cc5611ee4d7194c684d4ad2dd7653f7ce99a9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 9 Nov 2020 17:25:49 + Subject: [PATCH 3/7] lxd/storage/drivers/volume: Adds MountLock function Signed-off-by: Thomas Parrott --- lxd/storage/drivers/volume.go | 5 + 1 file changed, 5 insertions(+) diff --git a/lxd/storage/drivers/volume.go b/lxd/storage/drivers/volume.go index 16296a84bc..3ced59a0e0 100644 --- a/lxd/storage/drivers/volume.go +++ b/lxd/storage/drivers/volume.go @@ -134,6 +134,11 @@ func (v Volume) MountPath() string { return GetVolumeMountPath(v.pool, v.volType, v.name) } +// MountLock attempts to lock the mount lock for the volume and returns the UnlockFunc. +func (v Volume) MountLock() locking.UnlockFunc { + return locking.Lock(OperationLockName("MountLock", v.pool, v.volType, v.contentType, v.name)) +} + // EnsureMountPath creates the volume's mount path if missing, then sets the correct permission for the type. // If permission setting fails and the volume is a snapshot then the error is ignored as snapshots are read only. func (v Volume) EnsureMountPath() error { From ca8f79852d7f4b6b96166ec839eb36bf690784ba Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 9 Nov 2020 17:26:16 + Subject: [PATCH 4/7] lxd/storage/drivers/driver/lvm/utils: drivers.OperationLockName usage Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_lvm_utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/drivers/driver_lvm_utils.go b/lxd/storage/drivers/driver_lvm_utils.go index ee81d9e021..9d4b2bed68 100644 --- a/lxd/storage/drivers/driver_lvm_utils.go +++ b/lxd/storage/drivers/driver_lvm_utils.go @@ -56,7 +56,7 @@ func (d *lvm) openLoopFile(source string) (*os.File, error) { } if filepath.IsAbs(source) && !shared.IsBlockdevPath(source) { - unlock := locking.Lock(OperationLockName(d.name, "", "")) + unlock := locking.Lock(OperationLockName("openLoopFile", d.name, "", "", "")) defer unlock() // Try to prepare new loop device. From 5df12c19e18dacd2603b688a082f61ada6bd73c5 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 9 Nov 2020 17:27:08 + Subject: [PATCH 5/7] lxd/storage/backend/lxd: drivers.OperationLockName
[lxc-devel] [lxd/master] Storage: Always initialise db.StorageRemoteDriverNames in DB tests
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8134 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) === From 33f1523397cd40c027d4d96bc511f0d122c70b3f Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 10 Nov 2020 10:44:34 + Subject: [PATCH 1/2] lxd/db/storage/pools/test: Initialise db.StorageRemoteDriverNames in db_test package Signed-off-by: Thomas Parrott --- lxd/db/storage_pools_test.go | 6 ++ 1 file changed, 6 insertions(+) diff --git a/lxd/db/storage_pools_test.go b/lxd/db/storage_pools_test.go index 2958900c5e..9830798068 100644 --- a/lxd/db/storage_pools_test.go +++ b/lxd/db/storage_pools_test.go @@ -11,6 +11,12 @@ import ( "github.com/stretchr/testify/require" ) +func init() { + db.StorageRemoteDriverNames = func() []string { + return []string{"ceph", "cephfs"} + } +} + // The GetStoragePoolsLocalConfigs method returns only node-specific config values. func TestGetStoragePoolsLocalConfigs(t *testing.T) { cluster, cleanup := db.NewTestCluster(t) From 7f8d26eb15ff1e5efaacc80372aa92743dbcbb1c Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 10 Nov 2020 10:46:21 + Subject: [PATCH 2/2] lxd/db: Removes duplicated db.StorageRemoteDriverNames init from tests Signed-off-by: Thomas Parrott --- lxd/db/instances_test.go | 4 lxd/db/storage_volumes_test.go | 4 2 files changed, 8 deletions(-) diff --git a/lxd/db/instances_test.go b/lxd/db/instances_test.go index 8922bcbe50..d6b71eb974 100644 --- a/lxd/db/instances_test.go +++ b/lxd/db/instances_test.go @@ -216,10 +216,6 @@ func TestInstanceList(t *testing.T) { } func TestCreateInstance(t *testing.T) { - db.StorageRemoteDriverNames = func() []string { - return []string{"ceph", "cephfs"} - } - tx, cleanup := db.NewTestClusterTx(t) defer cleanup() diff --git a/lxd/db/storage_volumes_test.go b/lxd/db/storage_volumes_test.go index 2dd65f699b..557a23b449 100644 --- a/lxd/db/storage_volumes_test.go +++ b/lxd/db/storage_volumes_test.go @@ -12,10 +12,6 @@ import ( // Addresses of all nodes with matching volume name are returned. func TestGetStorageVolumeNodes(t *testing.T) { - db.StorageRemoteDriverNames = func() []string { - return []string{"ceph", "cephfs"} - } - tx, cleanup := db.NewTestClusterTx(t) defer cleanup() ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/stable-4.0] Storage: Ensure Location field is empty when storage driver is remote in storagePoolVolumeGetType
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8133 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) === From c6084f03be3efe425b10edcc190bcb33e8c2474d Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 10 Nov 2020 10:26:34 + Subject: [PATCH 1/2] lxd/db/storage/pools: Adds isRemoteStorage function Signed-off-by: Thomas Parrott --- lxd/db/storage_pools.go | 17 + 1 file changed, 17 insertions(+) diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go index 14f72683d6..4a07bdbef4 100644 --- a/lxd/db/storage_pools.go +++ b/lxd/db/storage_pools.go @@ -869,3 +869,20 @@ var StoragePoolNodeConfigKeys = []string{ "lvm.thinpool_name", "lvm.vg_name", } + +func (c *Cluster) isRemoteStorage(poolID int64) (bool, error) { + isRemoteStorage := false + + err := c.Transaction(func(tx *ClusterTx) error { + driver, err := tx.GetStoragePoolDriver(poolID) + if err != nil { + return err + } + + isRemoteStorage = shared.StringInSlice(driver, StorageRemoteDriverNames()) + + return nil + }) + + return isRemoteStorage, err +} From 91c72686fcbe3e5c155f8e9e9c50e1d7e413f6f8 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 10 Nov 2020 10:26:52 + Subject: [PATCH 2/2] lxd/db/storage/volumes: Updates storagePoolVolumeGetType to not populate Location when driver is remote Signed-off-by: Thomas Parrott --- lxd/db/storage_volumes.go | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go index 240a33556b..19ba3a3045 100644 --- a/lxd/db/storage_volumes.go +++ b/lxd/db/storage_volumes.go @@ -241,11 +241,20 @@ func (c *Cluster) storagePoolVolumeGetType(project string, volumeName string, vo return -1, nil, err } - volumeNode, err := c.storageVolumeNodeGet(volumeID) + isRemoteStorage, err := c.isRemoteStorage(poolID) if err != nil { return -1, nil, err } + volumeNode := "" + + if !isRemoteStorage { + volumeNode, err = c.storageVolumeNodeGet(volumeID) + if err != nil { + return -1, nil, err + } + } + volumeConfig, err := c.storageVolumeConfigGet(volumeID, isSnapshot) if err != nil { return -1, nil, err ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Storage: Further bug fixes in relation to volume used by detection
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8132 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) === Includes https://github.com/lxc/lxd/pull/8125 From 1cb4bb18b2257dd3bc7e731def934feb148d87c2 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 30 Oct 2020 13:50:50 + Subject: [PATCH 01/44] lxd/db/storage/volumes: Adds workaround for old remote volume schema in GetStorageVolumeNodeAddresses Signed-off-by: Thomas Parrott --- lxd/db/storage_volumes.go | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go index 738c51849c..a028910c37 100644 --- a/lxd/db/storage_volumes.go +++ b/lxd/db/storage_volumes.go @@ -677,8 +677,23 @@ func (c *ClusterTx) GetStorageVolumeNodeAddresses(poolID int64, projectName stri sort.Strings(addresses) - if len(addresses) == 0 { + addressCount := len(addresses) + if addressCount == 0 { return nil, ErrNoSuchObject + } else if addressCount > 1 { + driver, err := c.GetStoragePoolDriver(poolID) + if err != nil { + return nil, err + } + + // Earlier schema versions created a volume DB record for each cluster member for remote storage + // pools, so if the storage driver is one of those remote pools and the addressCount is >1 then we + // take this to mean that the volume doesn't have an explicit cluster member and is therefore + // equivalent to db.ErrNoClusterMember that is used in newer schemas where a single remote volume + // DB record is created that is not associated to any single member. + if driver == "ceph" || driver == "cephfs" { + return nil, ErrNoClusterMember + } } return addresses, nil From f151a8be2f78d3d4e82d5849111fe0a49e0c9e96 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 6 Nov 2020 11:12:19 + Subject: [PATCH 02/44] lxd/db/storage/volumes: Renames GetStorageVolumeNodeAddresses to GetStorageVolumeNodes And updates to return a list of db.NodeInfo structs rather than just addresses. This is more useful and removes the percularities around returning empty node address for local nodes. This makes it dependent on the caller to identify a local node. Also unifies the function to handle both current and legacy volume records for remote drivers. Signed-off-by: Thomas Parrott --- lxd/db/storage_volumes.go | 58 +-- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go index a028910c37..261784ce1f 100644 --- a/lxd/db/storage_volumes.go +++ b/lxd/db/storage_volumes.go @@ -5,7 +5,6 @@ package db import ( "database/sql" "fmt" - "sort" "strings" "time" @@ -622,27 +621,20 @@ type StorageVolumeArgs struct { ContentType string } -// GetStorageVolumeNodeAddresses returns the addresses of all nodes on which the -// volume with the given name if defined. -// +// GetStorageVolumeNodes returns the node info of all nodes on which the volume with the given name is defined. // The volume name can be either a regular name or a volume snapshot name. -// -// The empty string is used in place of the address of the current node. -func (c *ClusterTx) GetStorageVolumeNodeAddresses(poolID int64, projectName string, volumeName string, volumeType int) ([]string, error) { - nodes := []struct { - id int64 - address string - }{} - dest := func(i int) []interface{} { - nodes = append(nodes, struct { - id int64 - address string - }{}) - return []interface{}{[i].id, [i].address} +// If the volume is defined, but without a specific node, then the ErrNoClusterMember error is returned. +// If the volume is not found then the ErrNoSuchObject error is returned. +func (c *ClusterTx) GetStorageVolumeNodes(poolID int64, projectName string, volumeName string, volumeType int) ([]NodeInfo, error) { + nodes := []NodeInfo{} + dest := func(i int) []interface{} { + nodes = append(nodes, NodeInfo{}) + return []interface{}{[i].ID, [i].Address, [i].Name} } + sql := ` - SELECT coalesce(nodes.id,0) AS nodeID, coalesce(nodes.address,"") AS nodeAddress + SELECT coalesce(nodes.id,0) AS nodeID, coalesce(nodes.address,"") AS nodeAddress, coalesce(nodes.name,"") AS nodeName FROM storage_volumes_all JOIN projects ON projects.id = storage_volumes_all.project_id LEFT JOIN nodes
[lxc-devel] [lxd/master] Storage: Updates volume used by logic to support volumes of same name on multiple nodes
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8125 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) === Unifies old and new schema so same function can be used on both 4.0 and current branches. From 1f3a943afcfb2d0d69a0782c6bbaaad62a2466a6 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 6 Nov 2020 11:05:45 + Subject: [PATCH 1/4] lxd/cluster/connect: Updates ConnectIfVolumeIsRemote to use tx.GetStorageVolumeNodes Signed-off-by: Thomas Parrott --- lxd/cluster/connect.go | 31 +-- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lxd/cluster/connect.go b/lxd/cluster/connect.go index 335341b022..825d3aee23 100644 --- a/lxd/cluster/connect.go +++ b/lxd/cluster/connect.go @@ -125,20 +125,22 @@ func ConnectIfVolumeIsRemote(s *state.State, poolName string, projectName string return nil, err } - var addresses []string + localNodeID := s.Cluster.GetNodeID() + var nodes []db.NodeInfo err = s.Cluster.Transaction(func(tx *db.ClusterTx) error { poolID, err := tx.GetStoragePoolID(poolName) if err != nil { return err } - addresses, err = tx.GetStorageVolumeNodeAddresses(poolID, projectName, volumeName, volumeType) + nodes, err = tx.GetStorageVolumeNodes(poolID, projectName, volumeName, volumeType) if err != nil { return err } return nil }) + if err != nil && err != db.ErrNoClusterMember { return nil, err } @@ -162,29 +164,30 @@ func ConnectIfVolumeIsRemote(s *state.State, poolName string, projectName string return nil, errors.Wrapf(err, "Failed getting cluster member info for %q", remoteInstance.Node) } - // Replace address list with instance's cluster member. - addresses = []string{instNode.Address} + // Replace node list with instance's cluster member node (which might be local member). + nodes = []db.NodeInfo{instNode} } else { - // Volume isn't exclusively attached to an instance and has no fixed node. - addresses = []string{""} // Use local cluster member. + // Volume isn't exclusively attached to an instance. Use local cluster member. + return nil, nil } } - addressCount := len(addresses) - if addressCount > 1 { - return nil, fmt.Errorf("More than one cluster member has a volume named %q", volumeName) - } else if addressCount < 1 { + nodeCount := len(nodes) + if nodeCount > 1 { + return nil, fmt.Errorf("More than one cluster member has a volume named %q. Use --target flag to specify member", volumeName) + } else if nodeCount < 1 { + // Should never get here. return nil, fmt.Errorf("Volume %q has empty cluster member list", volumeName) } - address := addresses[0] - // Use local cluster member. - if address == "" { + node := nodes[0] + if node.ID == localNodeID { + // Use local cluster member if volume belongs to this local node. return nil, nil } // Connect to remote cluster member. - return Connect(address, cert, false) + return Connect(node.Address, cert, false) } // SetupTrust is a convenience around InstanceServer.CreateCertificate that From 450e05daa8661187db89bd1dc78831e75d8a8ffa Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 30 Oct 2020 13:50:50 + Subject: [PATCH 2/4] lxd/db/storage/volumes: Adds workaround for old remote volume schema in GetStorageVolumeNodeAddresses Signed-off-by: Thomas Parrott --- lxd/db/storage_volumes.go | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go index 738c51849c..a028910c37 100644 --- a/lxd/db/storage_volumes.go +++ b/lxd/db/storage_volumes.go @@ -677,8 +677,23 @@ func (c *ClusterTx) GetStorageVolumeNodeAddresses(poolID int64, projectName stri sort.Strings(addresses) - if len(addresses) == 0 { + addressCount := len(addresses) + if addressCount == 0 { return nil, ErrNoSuchObject + } else if addressCount > 1 { + driver, err := c.GetStoragePoolDriver(poolID) + if err != nil { + return nil, err + } + + // Earlier schema versions created a volume DB record
[lxc-devel] [lxd/master] VM: Converts all supplied memory byte values to mebibytes for comparison
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8123 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) === As we supply mebibytes to qemu for boot time memory size. Fixes https://discuss.linuxcontainers.org/t/cpu-burst-windows-vm/8965/ Signed-off-by: Thomas Parrott From 4682ca05c56ab2f9587f4c12038a5fb9ff1df57e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 5 Nov 2020 23:02:50 + Subject: [PATCH] lxd/instance/drivers/driver/qemu: Converts all supplied memory byte values to mebibytes for comparison As we supply mebibytes to qemu for boot time memory size. Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_qemu.go | 22 +- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index abfbb346b2..760c8b8378 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -3270,6 +3270,7 @@ func (vm *qemu) updateMemoryLimit(newLimit string) error { if err != nil { return errors.Wrapf(err, "Invalid memory size") } + newSizeMB := newSizeBytes / 1024 / 1024 // Connect to the monitor. monitor, err := qmp.Connect(vm.monitorPath(), qemuSerialChardevName, vm.getMonitorEventHandler()) @@ -3281,16 +3282,18 @@ func (vm *qemu) updateMemoryLimit(newLimit string) error { if err != nil { return err } + baseSizeMB := baseSizeBytes / 1024 / 1024 curSizeBytes, err := monitor.GetMemoryBalloonSizeBytes() if err != nil { return err } + curSizeMB := curSizeBytes / 1024 / 1024 - if curSizeBytes == newSizeBytes { + if curSizeMB == newSizeMB { return nil - } else if baseSizeBytes < newSizeBytes { - return fmt.Errorf("Cannot increase memory size beyond boot time size when VM is running") + } else if baseSizeMB < newSizeMB { + return fmt.Errorf("Cannot increase memory to size beyond boot time size when VM is running (Boot time size %dMB, new size %dMB)", baseSizeMB, newSizeMB) } // Set effective memory size. @@ -3301,27 +3304,28 @@ func (vm *qemu) updateMemoryLimit(newLimit string) error { // Changing the memory balloon can take time, so poll the effectice size to check it has shrunk within 1% // of the target size, which we then take as success (it may still continue to shrink closer to target). - for i := 0; i < 5; i++ { + for i := 0; i < 10; i++ { curSizeBytes, err = monitor.GetMemoryBalloonSizeBytes() if err != nil { return err } + curSizeMB = curSizeBytes / 1024 / 1024 var diff int64 - if curSizeBytes < newSizeBytes { - diff = newSizeBytes - curSizeBytes + if curSizeMB < newSizeMB { + diff = newSizeMB - curSizeMB } else { - diff = curSizeBytes - newSizeBytes + diff = curSizeMB - newSizeMB } - if diff <= (newSizeBytes / 100) { + if diff <= (newSizeMB / 100) { return nil // We reached to within 1% of our target size. } time.Sleep(500 * time.Millisecond) } - return fmt.Errorf("Failed setting memory to %d bytes (currently %d bytes) as it was taking too long", newSizeBytes, curSizeBytes) + return fmt.Errorf("Failed setting memory to %dMB (currently %dMB) as it was taking too long", newSizeMB, curSizeMB) } func (vm *qemu) updateDevices(removeDevices deviceConfig.Devices, addDevices deviceConfig.Devices, updateDevices deviceConfig.Devices, oldExpandedDevices deviceConfig.Devices, isRunning bool) error { ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Storage: EnsureImage and CreateInstanceFromImage improvements on size management
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8118 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) === - Updates `EnsureImage` to take into account existing image volume's `volatile.rootfs.size` property when calculating the current size the volume should be. Avoids trying to shrink an existing volume that is larger than the default size when the pool doesn't have volume size limit. - Improves comments in `CreateInstanceFromImage`. From eb99aae132343179d4909cd59d3541fbbff5b4bd Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 5 Nov 2020 12:09:43 + Subject: [PATCH 1/3] lxd/storage/utils: Improves logging and uses size value from vol.ConfigSizeFromSource in ImageUnpack Signed-off-by: Thomas Parrott --- lxd/storage/utils.go | 17 +++-- 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go index 7675c7371f..f802933416 100644 --- a/lxd/storage/utils.go +++ b/lxd/storage/utils.go @@ -515,6 +515,8 @@ func validateVolumeCommonRules(vol drivers.Volume) map[string]func(string) error // - Unpack metadata tarball into mountPath. // - Check rootBlockPath is a file and convert qcow2 file into raw format in rootBlockPath. func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blockBackend, runningInUserns bool, tracker *ioprogress.ProgressTracker) (int64, error) { + logger := logging.AddContext(logger.Log, log.Ctx{"imageFile": imageFile, "vol": vol.Name()}) + // For all formats, first unpack the metadata (or combined) tarball into destPath. imageRootfsFile := imageFile + ".rootfs" destPath := vol.MountPath() @@ -594,20 +596,23 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo } if volSizeBytes < imgInfo.VirtualSize { - // Create a partial image volume struct and then use it to check that target - // volume size can be increased as needed. + // If the target volume's size is smaller than the image unpack size, then we need + // to check whether it is inline with the pool's settings to allow us to increase + // the target volume's size. Create a partial image volume struct and then use it + // to check that target volume size can be set as needed. imgVolConfig := map[string]string{ "volatile.rootfs.size": fmt.Sprintf("%d", imgInfo.VirtualSize), } imgVol := drivers.NewVolume(nil, "", drivers.VolumeTypeImage, drivers.ContentTypeBlock, "", imgVolConfig, nil) - _, err = vol.ConfigSizeFromSource(imgVol) + logger.Debug("Checking image unpack size") + newVolSize, err := vol.ConfigSizeFromSource(imgVol) if err != nil { return -1, err } - logger.Debugf("Increasing %q volume size from %d to %d to accomomdate image %q unpack", dstPath, volSizeBytes, imgInfo.VirtualSize, imgPath) - err = vol.SetQuota(fmt.Sprintf("%d", imgInfo.VirtualSize), nil) + logger.Debug("Increasing volume size", log.Ctx{"imgPath": imgPath, "dstPath": dstPath, "oldSize": volSizeBytes, "newSize": newVolSize}) + err = vol.SetQuota(newVolSize, nil) if err != nil { return -1, errors.Wrapf(err, "Error increasing volume size") } @@ -616,7 +621,7 @@ func ImageUnpack(imageFile string, vol drivers.Volume, destBlockFile string, blo // Convert the qcow2 format to a raw block device using qemu's dd mode to avoid issues with // loop backed storage pools. Use the MinBlockBoundary block size to speed up conversion. - logger.Debugf("Converting qcow2 image %q to raw disk %q", imgPath, dstPath) + logger.Debug("Converting qcow2 image to raw disk", log.Ctx{"imgPath": imgPath, "dstPath": dstPath}) _, err = shared.RunCommand("qemu-img", "dd", "-f", "qcow2", "-O", "raw", fmt.Sprintf("bs=%d", drivers.MinBlockBoundary), fmt.Sprintf("if=%s", imgPath), fmt.Sprintf("of=%s", dstPath)) if err != nil { return -1, errors.Wrapf(err, "Failed converting image to raw at %q", dstPath) From
[lxc-devel] [lxd/master] VM: Call MountInstanceSnapshot when mounting vm snapshots
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8116 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) === Signed-off-by: Thomas Parrott From a15e4c882fc7062d356bce3e1b1c1b2670615605 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 3 Nov 2020 16:28:46 + Subject: [PATCH] lxd/instance/drivers/driver/qemu: Call MountInstanceSnapshot when mounting vm snapshots Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_qemu.go | 9 + 1 file changed, 9 insertions(+) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index a05c27b9cd..7bcc0a60a2 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -413,6 +413,15 @@ func (vm *qemu) mount() (bool, error) { return false, err } + if vm.IsSnapshot() { + ourMount, err := pool.MountInstanceSnapshot(vm, nil) + if err != nil { + return false, err + } + + return ourMount, nil + } + ourMount, err := pool.MountInstance(vm, nil) if err != nil { return false, err ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Adds support for using uplink bridge using bridge.driver=openvswitch for OVN networks
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8109 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) === In this scenario the intermediate OVS bridge and connecting veth pair is not needed and we configure OVN to connect its patch port directly to the existing uplink OVS bridge. Signed-off-by: Thomas Parrott From 9ec01f2daad31649135557aa9dd443c25a0609b6 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 2 Nov 2020 12:09:44 + Subject: [PATCH] lxd/network/driver/ovn: Adds support for using uplink bridge using bridge.driver=openvswitch In this scenario the intermediate OVS bridge and connecting veth pair is not needed and we configure OVN to connect its patch port directly to the existing uplink OVS bridge. Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 195 ++ 1 file changed, 111 insertions(+), 84 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 825b9e4d09..950ac04be9 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -860,76 +860,86 @@ func (n *ovn) uplinkPortBridgeVars(uplinkNet Network) *ovnUplinkPortBridgeVars { // startUplinkPortBridge creates veth pair (if doesn't exist), creates OVS bridge (if doesn't exist) and // connects veth pair to uplink bridge and OVS bridge. func (n *ovn) startUplinkPortBridge(uplinkNet Network) error { - vars := n.uplinkPortBridgeVars(uplinkNet) - // Do this after gaining lock so that on failure we revert before release locking. revert := revert.New() defer revert.Fail() - // Create veth pair if needed. - if !InterfaceExists(vars.uplinkEnd) && !InterfaceExists(vars.ovsEnd) { - _, err := shared.RunCommand("ip", "link", "add", "dev", vars.uplinkEnd, "type", "veth", "peer", "name", vars.ovsEnd) - if err != nil { - return errors.Wrapf(err, "Failed to create the uplink veth interfaces %q and %q", vars.uplinkEnd, vars.ovsEnd) + ovs := openvswitch.NewOVS() + + // If uplink is a native bridge, then use a separate OVS bridge with veth pair connection to native bridge. + if uplinkNet.Config()["bridge.driver"] != "openvswitch" { + vars := n.uplinkPortBridgeVars(uplinkNet) + + // Create veth pair if needed. + if !InterfaceExists(vars.uplinkEnd) && !InterfaceExists(vars.ovsEnd) { + _, err := shared.RunCommand("ip", "link", "add", "dev", vars.uplinkEnd, "type", "veth", "peer", "name", vars.ovsEnd) + if err != nil { + return errors.Wrapf(err, "Failed to create the uplink veth interfaces %q and %q", vars.uplinkEnd, vars.ovsEnd) + } + + revert.Add(func() { shared.RunCommand("ip", "link", "delete", vars.uplinkEnd) }) } - revert.Add(func() { shared.RunCommand("ip", "link", "delete", vars.uplinkEnd) }) - } + // Ensure that the veth interfaces inherit the uplink bridge's MTU (which the OVS bridge also inherits). + uplinkNetConfig := uplinkNet.Config() + if uplinkNetConfig["bridge.mtu"] != "" { + err := InterfaceSetMTU(vars.uplinkEnd, uplinkNetConfig["bridge.mtu"]) + if err != nil { + return err + } - // Ensure that the veth interfaces inherit the uplink bridge's MTU (which the OVS bridge also inherits). - uplinkNetConfig := uplinkNet.Config() - if uplinkNetConfig["bridge.mtu"] != "" { - err := InterfaceSetMTU(vars.uplinkEnd, uplinkNetConfig["bridge.mtu"]) - if err != nil { - return err + err = InterfaceSetMTU(vars.ovsEnd, uplinkNetConfig["bridge.mtu"]) + if err != nil { + return err + } } - err = InterfaceSetMTU(vars.ovsEnd, uplinkNetConfig["bridge.mtu"]) + // Ensure correct sysctls are set on uplink veth interfaces to avoid getting IPv6 link-local addresses. + err := util.SysctlSet( + fmt.Sprintf("net/ipv6/conf/%s/disable_ipv6", vars.uplinkEnd), "1", + fmt.Sprintf("net/ipv6/conf/%s/disable_ipv6", vars.ovsEnd), "1", + fmt.Sprintf("net/ipv6/conf/%s/forwarding", vars.uplinkEnd), "0", + fmt.Sprintf("net/ipv6/conf/%s/forwarding", vars.ovsEnd), "0", + ) if err != nil { - return err + return errors.Wrapf(err, "Failed to configure uplink
[lxc-devel] [lxc-ci/master] bin/test-lxd-cluster: Adds cluster fan networking tests
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/203 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) === Signed-off-by: Thomas Parrott From c202714c45dc8752775474c47b6001c6b53c2d90 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 30 Oct 2020 17:52:18 + Subject: [PATCH] bin/test-lxd-cluster: Adds cluster fan networking tests Signed-off-by: Thomas Parrott --- bin/test-lxd-cluster | 19 +++ 1 file changed, 19 insertions(+) diff --git a/bin/test-lxd-cluster b/bin/test-lxd-cluster index f1cc6a4..297a6d3 100755 --- a/bin/test-lxd-cluster +++ b/bin/test-lxd-cluster @@ -61,6 +61,11 @@ for i in $(seq "$1"); do lxc exec "${PREFIX}-$i" -- lxc config set cluster.https_address "${CLUSTER_IP}:8443" lxc exec "${PREFIX}-$i" -- lxc config set core.trust_password "cluster" lxc exec "${PREFIX}-$i" -- lxc cluster enable "${PREFIX}-$i" +lxc exec "${PREFIX}-$i" -- lxc network create lxdfan0 bridge.mode=fan +lxc exec "${PREFIX}-$i" -- lxc storage create default dir +lxc exec "${PREFIX}-$i" -- lxc profile device add default root disk path=/ pool=default +lxc exec "${PREFIX}-$i" -- lxc profile device add default eth0 nic name=eth0 network=lxdfan0 +lxc exec "${PREFIX}-$i" -- lxc network show lxdfan0 CLUSTER_CRT=$(lxc file pull "${PREFIX}-$i"/var/snap/lxd/common/lxd/cluster.crt - | sed ':a;N;$!ba;s/\n/\n\n/g') else MEMBER_IP=$(lxc exec "${PREFIX}-$i" -- ip -4 addr show dev eth0 scope global | grep inet | cut -d' ' -f6 | cut -d/ -f1) @@ -85,6 +90,20 @@ echo "==> Validating the cluster" lxc exec "${PREFIX}-1" -- lxc info lxc exec "${PREFIX}-1" -- lxc cluster list +# Test fan networking (intra fan from container and host, as well as external NAT comms) +echo "==> Test fan networking" +lxc exec "${PREFIX}-1" -- lxc launch images:ubuntu/focal u1 +lxc exec "${PREFIX}-1" -- lxc launch images:ubuntu/focal u2 + +echo "==> Wait for addresses" +sleep 10 +lxc exec "${PREFIX}-1" -- lxc list + +U2_IPV4="$(lxc exec ${PREFIX}-1 -- lxc list u2 -c4 --format=csv | cut -d' ' -f1)" +lxc exec "${PREFIX}-1" -- lxc exec u1 -- ping -c1 -4 linuxcontainers.org +lxc exec "${PREFIX}-1" -- lxc exec u1 -- ping -c1 "${U2_IPV4}" +lxc exec "${PREFIX}-1" -- ping -c1 "${U2_IPV4}" + # Upgrade the cluster echo "==> Upgrading the cluster" for i in $(seq "$1"); do ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/stable-4.0] lxd/cluster/connect: Adds workaround for remote storage pool volumes using old schema in ConnectIfVolumeIsRemote
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8101 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) === Signed-off-by: Thomas Parrott From 92bee7be07b765539ef3db22ca9b870c405ec23f Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 30 Oct 2020 11:51:40 + Subject: [PATCH] lxd/cluster/connect: Adds workaround for remote storage pool volumes using old schema in ConnectIfVolumeIsRemote Signed-off-by: Thomas Parrott --- lxd/cluster/connect.go | 17 + 1 file changed, 17 insertions(+) diff --git a/lxd/cluster/connect.go b/lxd/cluster/connect.go index 335341b022..8d81a11011 100644 --- a/lxd/cluster/connect.go +++ b/lxd/cluster/connect.go @@ -137,6 +137,23 @@ func ConnectIfVolumeIsRemote(s *state.State, poolName string, projectName string return err } + addressesCount := len(addresses) + if addressesCount > 1 { + clusterMemberCount, err := tx.GetNodesCount() + if err != nil { + return err + } + + // Earlier schema versions created a volume DB record associated to each node in the + // cluster for remote storage pools, so if the address count equals the cluster member + // count then we take this to mean that the volume doesn't have an explicit cluster member + // and is therefore equivalent to db.ErrNoClusterMember that is used in newer schemas where + // a single remote volume DB record is created that is not associated to any single member. + if addressesCount == clusterMemberCount { + return db.ErrNoClusterMember + } + } + return nil }) if err != nil && err != db.ErrNoClusterMember { ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxc-ci/master] bin/test-lxd-ovn: Adds external subnets and routes overlap checks
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/202 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) === Signed-off-by: Thomas Parrott Depends on https://github.com/lxc/lxd/pull/8095 From 02bceb0499651a10c9add213a12e4255a2e746f9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 29 Oct 2020 13:42:37 + Subject: [PATCH] bin/test-lxd-ovn: Adds external subnets and routes overlap checks Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 17 + 1 file changed, 17 insertions(+) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index a2844cd..f011144 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -151,6 +151,13 @@ lxc network create ovn-virtual-network --type=ovn --project testovn network=dumm ipv4.nat=false \ ipv6.nat=false +# Check network external subnet overlap. +! lxc network create ovn-virtual-network2 --type=ovn --project default network=dummy \ +ipv4.address=198.51.100.1/26 \ +ipv6.address=2001:db8:1:2::1/122 \ +ipv4.nat=false \ +ipv6.nat=false || false + lxc init images:ubuntu/20.04 u1 --project testovn lxc config device add u1 eth0 nic network=ovn-virtual-network name=eth0 --project testovn lxc start u1 --project testovn @@ -170,10 +177,20 @@ lxc network set ovn-virtual-network --project testovn \ ipv4.nat=true \ ipv6.nat=true +# Check external routes are ensured to be within uplink's external routes. ! lxc config device set u1 eth0 ipv4.routes.external=198.51.100.0/24 --project testovn || false ! lxc config device set u1 eth0 ipv6.routes.external=2001:db8:1:2::/64 --project testovn || false lxc config device set u1 eth0 ipv4.routes.external=198.51.100.0/26 --project testovn lxc config device set u1 eth0 ipv6.routes.external=2001:db8:1:2::/122 --project testovn + +# Check NIC external route overlap detection. +lxc init images:ubuntu/20.04 u2 --project testovn +lxc config device add u2 eth0 nic network=ovn-virtual-network name=eth0 --project testovn +! lxc config device set u2 eth0 ipv4.routes.external=198.51.100.1/32 --project testovn || false +! lxc config device set u2 eth0 ipv6.routes.external=2001:db8:1:2::1/128 --project testovn || false +lxc delete -f u2 --project testovn + +# Check DNAT rules get added when starting instance port with external routes. lxc start u1 --project testovn ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | grep "198.51.100.0,198.51.100.0,dnat_and_snat" ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Adds external subnet overlap validation for OVN networks
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8095 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) === From f899806b77a562de10764e8f52afb0ac1d6d52fd Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 29 Oct 2020 11:03:01 + Subject: [PATCH 1/5] lxd/network/driver/ovn: Adds ovnProjectNetworksWithUplink function Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 24 1 file changed, 24 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 9ce25782e7..0f141d73e2 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -2353,3 +2353,27 @@ func (n *ovn) ovnNICExternalRoutes(ourDeviceInstance instance.Instance, ourDevic return externalRoutes, nil } + +// ovnProjectNetworksWithUplink accepts a map of all networks in all projects and returns a filtered map of OVN +// networks that use the uplink specified. +func (n *ovn) ovnProjectNetworksWithUplink(uplink string, projectNetworks map[string]map[int64]api.Network) map[string][]*api.Network { + ovnProjectNetworksWithOurUplink := make(map[string][]*api.Network) + for netProject, networks := range projectNetworks { + for _, ni := range networks { + network := ni // Local var creating pointer to rather than iterator. + + // Skip non-OVN networks or those networks that don't use the uplink specified. + if network.Type != "ovn" || network.Config["network"] != uplink { + continue + } + + if ovnProjectNetworksWithOurUplink[netProject] == nil { + ovnProjectNetworksWithOurUplink[netProject] = []*api.Network{} + } else { + ovnProjectNetworksWithOurUplink[netProject] = append(ovnProjectNetworksWithOurUplink[netProject], ) + } + } + } + + return ovnProjectNetworksWithOurUplink +} From c6d6045b8f43cf749666eefe99e6c4fa0d36d2e9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 29 Oct 2020 11:04:42 + Subject: [PATCH 2/5] lxd/network/driver/ovn: Updates ovnNetworkExternalSubnets to allow optional filtering of our own network's subnets Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 0f141d73e2..cbfaa1f080 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -2260,13 +2260,18 @@ func (n *ovn) DHCPv6Subnet() *net.IPNet { return subnet } -// ovnNetworkExternalSubnets returns a list of external subnets used by OVN networks (including our own) using the -// same uplink as this OVN network. OVN networks are considered to be using external subnets if their ipv4.address -// and/or ipv6.address are in the uplink's external routes and the associated NAT is disabled for the IP family. -func (n *ovn) ovnNetworkExternalSubnets(ovnProjectNetworksWithOurUplink map[string][]*api.Network, uplinkRoutes []*net.IPNet) ([]*net.IPNet, error) { +// ovnNetworkExternalSubnets returns a list of external subnets used by OVN networks (optionally exluding our own +// if both ourProject and ourNetwork are non-empty) using the same uplink as this OVN network. OVN networks are +// considered to be using external subnets if their ipv4.address and/or ipv6.address are in the uplink's external +// routes and the associated NAT is disabled for the IP family. +func (n *ovn) ovnNetworkExternalSubnets(ourProject string, ourNetwork string, ovnProjectNetworksWithOurUplink map[string][]*api.Network, uplinkRoutes []*net.IPNet) ([]*net.IPNet, error) { externalSubnets := make([]*net.IPNet, 0) - for _, networks := range ovnProjectNetworksWithOurUplink { + for netProject, networks := range ovnProjectNetworksWithOurUplink { for _, netInfo := range networks { + if netProject == ourProject && netInfo.Name == ourNetwork { + continue + } + for _, keyPrefix := range []string{"ipv4", "ipv6"} { if !shared.IsTrue(netInfo.Config[fmt.Sprintf("%s.nat", keyPrefix)]) { _, ipNet, _ := net.ParseCIDR(netInfo.Config[fmt.Sprintf("%s.address", keyPrefix)]) From 7872cdf100bfb56814b20357c8d869da194d6db3 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 29 Oct 2020 11:05:15 + Subject: [PATCH 3/5] lxd/network/driver/ovn: Updates ovnNICExternalRoutes to optionally filter our own NIC's external routes Signed-off-by: Thomas
[lxc-devel] [lxd/master] Network: OVN NIC external route overlap validation
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8092 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) === This PR adds validation of OVN NIC external routes (`ipv4.routes.external` and `ipv6.routes.external`) settings to check they do not overlap with any other OVN NICs that are connected to networks that use the same uplink, and that they do not overlap with any OVN networks (including the OVN network the OVN NIC we are validation is connected to) that use external subnets and also use the same uplink. From 4c1e883f9dbb88e9e4850ae9c98e5a23839d3f74 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 28 Oct 2020 14:10:00 + Subject: [PATCH 1/6] lxd/project/project: Updates StorageVolumeProjectFromRecord to not return error (as never populated) Signed-off-by: Thomas Parrott --- lxd/project/project.go | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lxd/project/project.go b/lxd/project/project.go index d7d40479fa..f1dbf556b5 100644 --- a/lxd/project/project.go +++ b/lxd/project/project.go @@ -79,26 +79,26 @@ func StorageVolumeProject(c *db.Cluster, projectName string, volumeType int) (st return "", errors.Wrapf(err, "Failed to load project %q", projectName) } - return StorageVolumeProjectFromRecord(project, volumeType) + return StorageVolumeProjectFromRecord(project, volumeType), nil } -// StorageVolumeProjectFromRecord returns the project name to use to for the volume based on the requested project. -// For custom volume type, if the project specified has the "features.storage.volumes" flag enabled then the +// StorageVolumeProjectFromRecord returns the project name to use to for the volume based on the supplied project. +// For custom volume type, if the project supplied has the "features.storage.volumes" flag enabled then the // project name is returned, otherwise the default project name is returned. For all other volume types the // supplied project's name is returned. -func StorageVolumeProjectFromRecord(p *api.Project, volumeType int) (string, error) { +func StorageVolumeProjectFromRecord(p *api.Project, volumeType int) string { // Non-custom volumes always use the project specified. if volumeType != db.StoragePoolVolumeTypeCustom { - return p.Name, nil + return p.Name } // Custom volumes only use the project specified if the project has the features.storage.volumes feature // enabled, otherwise the legacy behaviour of using the default project for custom volumes is used. if shared.IsTrue(p.Config["features.storage.volumes"]) { - return p.Name, nil + return p.Name } - return Default, nil + return Default } // NetworkProject returns the project name to use for the network based on the requested project. From 94a12db197d93e724177c6e883aa2c8c4d77d66b Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 28 Oct 2020 14:10:51 + Subject: [PATCH 2/6] lxd/project/project: Adds NetworkProjectFromRecord function And updates NetworkProject to use it. Signed-off-by: Thomas Parrott --- lxd/project/project.go | 21 + 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lxd/project/project.go b/lxd/project/project.go index f1dbf556b5..202f059650 100644 --- a/lxd/project/project.go +++ b/lxd/project/project.go @@ -106,16 +106,29 @@ func StorageVolumeProjectFromRecord(p *api.Project, volumeType int) string { // otherwise the default project name is returned. The second return value is the project's config if non-default // project is being returned, nil if not. func NetworkProject(c *db.Cluster, projectName string) (string, map[string]string, error) { - project, err := c.GetProject(projectName) + p, err := c.GetProject(projectName) if err != nil { return "", nil, errors.Wrapf(err, "Failed to load project %q", projectName) } + projectName = NetworkProjectFromRecord(p) + + if projectName != Default { + return projectName, p.Config, nil + } + + return Default, nil, nil +} + +// NetworkProjectFromRecord returns the project name to use for the network based on the supplied project. +// If the project supplied has the "features.networks" flag enabled then the project name is returned, +// otherwise the default project name is returned. +func NetworkProjectFromRecord(p *api.Project) string { // Networks only use the project specified if the project has the features.networks feature enabled, // otherwise the legacy behaviour of using the default project for networks is used. - if shared.IsTrue(project.Config["features.networks"]) { -
[lxc-devel] [lxc-ci/master] bin/test-lxd-ovn: Adds test for passing external IP subnet into network
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/199 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) === Signed-off-by: Thomas Parrott From 65216a680d6c62671460d2e9de418351a76226f3 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 28 Oct 2020 10:47:04 + Subject: [PATCH] bin/test-lxd-ovn: Adds test for passing external IP subnet into network Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 20 1 file changed, 20 insertions(+) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index fb0480e..a2844cd 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -161,6 +161,26 @@ U1_EXT_IPV4="$(lxc list u1 --project testovn -c4 --format=csv | cut -d' ' -f1)" U1_EXT_IPV6="$(lxc list u1 --project testovn -c6 --format=csv | cut -d' ' -f1)" ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | grep "${U1_EXT_IPV4},${U1_EXT_IPV4},dnat_and_snat" ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | grep "${U1_EXT_IPV6},${U1_EXT_IPV6},dnat_and_snat" +lxc stop -f u1 --project testovn + +# Test external IPs routed to OVN NIC. +lxc network set ovn-virtual-network --project testovn \ +ipv4.address=auto \ +ipv6.address=auto \ +ipv4.nat=true \ +ipv6.nat=true + +! lxc config device set u1 eth0 ipv4.routes.external=198.51.100.0/24 --project testovn || false +! lxc config device set u1 eth0 ipv6.routes.external=2001:db8:1:2::/64 --project testovn || false +lxc config device set u1 eth0 ipv4.routes.external=198.51.100.0/26 --project testovn +lxc config device set u1 eth0 ipv6.routes.external=2001:db8:1:2::/122 --project testovn +lxc start u1 --project testovn +ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat +ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | grep "198.51.100.0,198.51.100.0,dnat_and_snat" +ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | grep "198.51.100.63,198.51.100.63,dnat_and_snat" +ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | grep "2001:db8:1:2::,2001:db8:1:2::,dnat_and_snat" +ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | grep "2001:db8:1:2::3f,2001:db8:1:2::3f,dnat_and_snat" +ovn-nbctl --bare --format=csv --column=external_ip,logical_ip,type find nat | wc -l | grep 132 lxc delete -f u1 --project testovn lxc network delete ovn-virtual-network --project testovn ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Instance: Write out updated backup.yaml after rename
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8083 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) === Fixes #8071 Signed-off-by: Thomas Parrott From 74c1e881df63a4d211e674e790459925a321ac5e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 27 Oct 2020 17:24:08 + Subject: [PATCH] lxd/instance/drivers: Write out updated backup.yaml after rename Fixes #8071 Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 5 + lxd/instance/drivers/driver_qemu.go | 5 + 2 files changed, 10 insertions(+) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index 0efab52699..a89a68e866 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -3747,6 +3747,11 @@ func (c *lxc) Rename(newName string) error { // Update lease files. network.UpdateDNSMasqStatic(c.state, "") + err = c.UpdateBackupFile() + if err != nil { + return err + } + logger.Info("Renamed container", ctxMap) if c.IsSnapshot() { diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index ba1381043a..d5e81b5200 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -2751,6 +2751,11 @@ func (vm *qemu) Rename(newName string) error { // Update lease files. network.UpdateDNSMasqStatic(vm.state, "") + err = vm.UpdateBackupFile() + if err != nil { + return err + } + logger.Info("Renamed instance", ctxMap) if vm.IsSnapshot() { ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Tp storage forwarded response if volume is remote exclusive volumes
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8074 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) === From d520357207a0bb535f78212b25372aaf6478c9c5 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 22 Oct 2020 09:15:04 +0100 Subject: [PATCH 01/14] lxd/cluster/connect: Renames project arg to projectName in ConnectIfInstanceIsRemote Signed-off-by: Thomas Parrott --- lxd/cluster/connect.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/cluster/connect.go b/lxd/cluster/connect.go index 7ed1dd0773..a180d796f8 100644 --- a/lxd/cluster/connect.go +++ b/lxd/cluster/connect.go @@ -97,11 +97,11 @@ func Connect(address string, cert *shared.CertInfo, notify bool) (lxd.InstanceSe // running the container with the given name. If it's not the local node will // connect to it and return the connected client, otherwise it will just return // nil. -func ConnectIfInstanceIsRemote(cluster *db.Cluster, project, name string, cert *shared.CertInfo, instanceType instancetype.Type) (lxd.InstanceServer, error) { +func ConnectIfInstanceIsRemote(cluster *db.Cluster, projectName string, name string, cert *shared.CertInfo, instanceType instancetype.Type) (lxd.InstanceServer, error) { var address string // Node address err := cluster.Transaction(func(tx *db.ClusterTx) error { var err error - address, err = tx.GetNodeAddressOfInstance(project, name, instanceType) + address, err = tx.GetNodeAddressOfInstance(projectName, name, instanceType) return err }) if err != nil { From a5a1f424b9cdba09d91fd86532cdde51d896b253 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 22 Oct 2020 09:15:21 +0100 Subject: [PATCH 02/14] lxd/cluster/connect: Adds projectName arg to ConnectIfVolumeIsRemote Rather than being hardcoded to "default" project. Signed-off-by: Thomas Parrott --- lxd/cluster/connect.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/cluster/connect.go b/lxd/cluster/connect.go index a180d796f8..1d93cef6bf 100644 --- a/lxd/cluster/connect.go +++ b/lxd/cluster/connect.go @@ -121,11 +121,11 @@ func ConnectIfInstanceIsRemote(cluster *db.Cluster, projectName string, name str // // If there is more than one node with a matching volume name, an error is // returned. -func ConnectIfVolumeIsRemote(cluster *db.Cluster, poolID int64, volumeName string, volumeType int, cert *shared.CertInfo) (lxd.InstanceServer, error) { +func ConnectIfVolumeIsRemote(cluster *db.Cluster, poolID int64, projectName string, volumeName string, volumeType int, cert *shared.CertInfo) (lxd.InstanceServer, error) { var addresses []string // Node addresses err := cluster.Transaction(func(tx *db.ClusterTx) error { var err error - addresses, err = tx.GetStorageVolumeNodeAddresses(poolID, "default", volumeName, volumeType) + addresses, err = tx.GetStorageVolumeNodeAddresses(poolID, projectName, volumeName, volumeType) return err }) if err != nil { From 845d371084edd548435fb26bc8cfa293b8b06705 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 22 Oct 2020 09:15:54 +0100 Subject: [PATCH 03/14] lxd/response: Adds projectName argument to forwardedResponseIfVolumeIsRemote Signed-off-by: Thomas Parrott --- lxd/response.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/response.go b/lxd/response.go index 01c3c9c605..77557643cb 100644 --- a/lxd/response.go +++ b/lxd/response.go @@ -59,13 +59,13 @@ func forwardedResponseIfInstanceIsRemote(d *Daemon, r *http.Request, project, na // // This is used when no targetNode is specified, and saves users some typing // when the volume name/type is unique to a node. -func forwardedResponseIfVolumeIsRemote(d *Daemon, r *http.Request, poolID int64, volumeName string, volumeType int) response.Response { +func forwardedResponseIfVolumeIsRemote(d *Daemon, r *http.Request, poolID int64, projectName string, volumeName string, volumeType int) response.Response { if queryParam(r, "target") != "" { return nil } cert := d.endpoints.NetworkCert() - client, err := cluster.ConnectIfVolumeIsRemote(d.cluster, poolID, volumeName, volumeType, cert) + client, err := cluster.ConnectIfVolumeIsRemote(d.cluster, poolID, projectName, volumeName, volumeType, cert) if err != nil && err != db.ErrNoSuchObject { return response.SmartError(err) } From ca3badc5dc32930ab754615b4eae6763b2f6149b Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 22 Oct 2020 09:16:19 +0100 Subject: [PATCH 04/14] lxd/storage/volumes: forwardedResponseIfVolumeIsRemote projectName
[lxc-devel] [lxd/master] Storage: Fixes forwarded response if volume is remote to support projects
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8073 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) === Was previously hard coded to default, but custom volumes can support projects now. From d520357207a0bb535f78212b25372aaf6478c9c5 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 22 Oct 2020 09:15:04 +0100 Subject: [PATCH 1/4] lxd/cluster/connect: Renames project arg to projectName in ConnectIfInstanceIsRemote Signed-off-by: Thomas Parrott --- lxd/cluster/connect.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/cluster/connect.go b/lxd/cluster/connect.go index 7ed1dd0773..a180d796f8 100644 --- a/lxd/cluster/connect.go +++ b/lxd/cluster/connect.go @@ -97,11 +97,11 @@ func Connect(address string, cert *shared.CertInfo, notify bool) (lxd.InstanceSe // running the container with the given name. If it's not the local node will // connect to it and return the connected client, otherwise it will just return // nil. -func ConnectIfInstanceIsRemote(cluster *db.Cluster, project, name string, cert *shared.CertInfo, instanceType instancetype.Type) (lxd.InstanceServer, error) { +func ConnectIfInstanceIsRemote(cluster *db.Cluster, projectName string, name string, cert *shared.CertInfo, instanceType instancetype.Type) (lxd.InstanceServer, error) { var address string // Node address err := cluster.Transaction(func(tx *db.ClusterTx) error { var err error - address, err = tx.GetNodeAddressOfInstance(project, name, instanceType) + address, err = tx.GetNodeAddressOfInstance(projectName, name, instanceType) return err }) if err != nil { From a5a1f424b9cdba09d91fd86532cdde51d896b253 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 22 Oct 2020 09:15:21 +0100 Subject: [PATCH 2/4] lxd/cluster/connect: Adds projectName arg to ConnectIfVolumeIsRemote Rather than being hardcoded to "default" project. Signed-off-by: Thomas Parrott --- lxd/cluster/connect.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/cluster/connect.go b/lxd/cluster/connect.go index a180d796f8..1d93cef6bf 100644 --- a/lxd/cluster/connect.go +++ b/lxd/cluster/connect.go @@ -121,11 +121,11 @@ func ConnectIfInstanceIsRemote(cluster *db.Cluster, projectName string, name str // // If there is more than one node with a matching volume name, an error is // returned. -func ConnectIfVolumeIsRemote(cluster *db.Cluster, poolID int64, volumeName string, volumeType int, cert *shared.CertInfo) (lxd.InstanceServer, error) { +func ConnectIfVolumeIsRemote(cluster *db.Cluster, poolID int64, projectName string, volumeName string, volumeType int, cert *shared.CertInfo) (lxd.InstanceServer, error) { var addresses []string // Node addresses err := cluster.Transaction(func(tx *db.ClusterTx) error { var err error - addresses, err = tx.GetStorageVolumeNodeAddresses(poolID, "default", volumeName, volumeType) + addresses, err = tx.GetStorageVolumeNodeAddresses(poolID, projectName, volumeName, volumeType) return err }) if err != nil { From 845d371084edd548435fb26bc8cfa293b8b06705 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 22 Oct 2020 09:15:54 +0100 Subject: [PATCH 3/4] lxd/response: Adds projectName argument to forwardedResponseIfVolumeIsRemote Signed-off-by: Thomas Parrott --- lxd/response.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/response.go b/lxd/response.go index 01c3c9c605..77557643cb 100644 --- a/lxd/response.go +++ b/lxd/response.go @@ -59,13 +59,13 @@ func forwardedResponseIfInstanceIsRemote(d *Daemon, r *http.Request, project, na // // This is used when no targetNode is specified, and saves users some typing // when the volume name/type is unique to a node. -func forwardedResponseIfVolumeIsRemote(d *Daemon, r *http.Request, poolID int64, volumeName string, volumeType int) response.Response { +func forwardedResponseIfVolumeIsRemote(d *Daemon, r *http.Request, poolID int64, projectName string, volumeName string, volumeType int) response.Response { if queryParam(r, "target") != "" { return nil } cert := d.endpoints.NetworkCert() - client, err := cluster.ConnectIfVolumeIsRemote(d.cluster, poolID, volumeName, volumeType, cert) + client, err := cluster.ConnectIfVolumeIsRemote(d.cluster, poolID, projectName, volumeName, volumeType, cert) if err != nil && err != db.ErrNoSuchObject { return response.SmartError(err) } From ca3badc5dc32930ab754615b4eae6763b2f6149b Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 22 Oct 2020 09:16:19 +0100 Subject: [PATCH
[lxc-devel] [lxd/master] Instance: Mount instance volume before devices start
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8070 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) === This is to accommodate TPM devices that need to write their state to the instance's root/config volume during start. From 6b3d569c493e7cc5e0367fb45d4f6a54c60fe636 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 21 Oct 2020 11:14:56 +0100 Subject: [PATCH 01/18] lxd/storage/backend/lxd: b.driver.UnmountVolume usage Signed-off-by: Thomas Parrott --- lxd/storage/backend_lxd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 20ddfc145c..e14f911692 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -1652,7 +1652,7 @@ func (b *lxdBackend) UnmountInstance(inst instance.Instance, op *operations.Oper // Get the volume. vol := b.newVolume(volType, contentType, volStorageName, rootDiskConf) - return b.driver.UnmountVolume(vol, op) + return b.driver.UnmountVolume(vol, false, op) } // GetInstanceDisk returns the location of the disk. @@ -2976,7 +2976,7 @@ func (b *lxdBackend) UnmountCustomVolume(projectName, volName string, op *operat volStorageName := project.StorageVolume(projectName, volName) vol := b.newVolume(drivers.VolumeTypeCustom, drivers.ContentTypeFS, volStorageName, volume.Config) - return b.driver.UnmountVolume(vol, op) + return b.driver.UnmountVolume(vol, false, op) } // CreateCustomVolumeSnapshot creates a snapshot of a custom volume. From 4c1aa33f61f9a4bb6bc757629d6f99c3eea61b92 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 21 Oct 2020 11:15:26 +0100 Subject: [PATCH 02/18] lxd/instance/drivers/driver/lxc: Moves log rotate and mount before devices start in startCommon This is to accomodate TPM devices that need to write their state to the instance's volume during start. Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 32 +++--- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index 03170057c3..aa3228cdb0 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -2077,6 +2077,22 @@ func (c *lxc) startCommon() (string, []func() error, error) { return "", postStartHooks, err } + // Rotate the log file. + logfile := c.LogFilePath() + if shared.PathExists(logfile) { + os.Remove(logfile + ".old") + err := os.Rename(logfile, logfile+".old") + if err != nil { + return "", postStartHooks, err + } + } + + // Mount instance root volume. + ourStart, err = c.mount() + if err != nil { + return "", postStartHooks, err + } + // Create the devices nicID := -1 @@ -2224,22 +2240,6 @@ func (c *lxc) startCommon() (string, []func() error, error) { } } - // Rotate the log file - logfile := c.LogFilePath() - if shared.PathExists(logfile) { - os.Remove(logfile + ".old") - err := os.Rename(logfile, logfile+".old") - if err != nil { - return "", postStartHooks, err - } - } - - // Storage is guaranteed to be mountable now (must be called after devices setup). - ourStart, err = c.mount() - if err != nil { - return "", postStartHooks, err - } - // Generate the LXC config configPath := filepath.Join(c.LogPath(), "lxc.conf") err = c.c.SaveConfigFile(configPath) From 65ee12cf2442b95f998e32b3221bee15706cb6b1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 21 Oct 2020 11:16:09 +0100 Subject: [PATCH 03/18] lxd/storage/drivers/interface: Adds keepBlockDev arg to UnmountVolume Signed-off-by: Thomas Parrott --- lxd/storage/drivers/interface.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/drivers/interface.go b/lxd/storage/drivers/interface.go index 4aba1a134c..7913b221e1 100644 --- a/lxd/storage/drivers/interface.go +++ b/lxd/storage/drivers/interface.go @@ -67,7 +67,7 @@ type Driver interface { // UnmountVolume unmounts a storage volume, returns true if unmounted, false if was not // mounted. - UnmountVolume(vol Volume, op *operations.Operation) (bool, error) + UnmountVolume(vol Volume, keepBlockDev bool, op *operations.Operation) (bool, error) // UnmountVolume unmounts a storage volume snapshot, returns true if unmounted, false if was // not mounted. From 9eb284da66d53e7a73188a6c9c3d66b314df94cb Mon
[lxc-devel] [lxc-ci/master] OVN: External IP tests
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/196 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) === From e1759fd36b251872804e9b55e9cbeb9c8b00d57c Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 11:29:28 +0100 Subject: [PATCH 1/4] bin/test-lxd-ovn: Adds debugging throughout script So we can see which commands are being run. Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index b6b6810..5ec282f 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -1,5 +1,5 @@ #!/bin/sh -set -eu +set -eux cleanup() { echo "" @@ -35,7 +35,6 @@ lxd waitready --timeout=300 apt install ovn-host ovn-central --yes # Configure OVN -set -x ovs-vsctl set open_vswitch . \ external_ids:ovn-remote=unix:/var/run/ovn/ovnsb_db.sock \ external_ids:ovn-encap-type=geneve \ @@ -56,7 +55,6 @@ lxc network create lxdbr0 \ lxc network create ovn-virtual-network --type=ovn # Test -set +x lxc network list lxc project switch default From 8637bc622210597da24e9b4881a27f0ed84aa160 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 16:19:38 +0100 Subject: [PATCH 2/4] bin/test-lxd-ovn: Improves section titles Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index 5ec282f..0ee328f 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -98,7 +98,7 @@ echo "==> OVN to OVN" lxc exec u2 -- ping -c1 -4 "${U3_IPV4}" lxc exec u2 -- ping -c1 -6 "${U3_IPV6}" -echo "==> OVN to lxdbr0" +echo "==> OVN to lxdbr0 instance" lxc exec u3 -- ping -c1 -4 "${U1_IPV4}" lxc exec u3 -- ping -c1 -6 "${U1_IPV6}" @@ -106,7 +106,7 @@ echo "==> DNS resolution on OVN" lxc exec u3 -- ping -c1 -4 u2.lxd lxc exec u3 -- ping -c1 -6 u2.lxd -echo "==> OVN to lxdbr0" +echo "==> OVN to lxdbr0 gateway" lxc exec u2 -- ping -c1 10.10.10.1 lxc exec u2 -- ping -c1 fd42:4242:4242:1010::1 @@ -174,7 +174,7 @@ echo "==> OVN to OVN in project testovn" lxc exec u2 -- ping -c1 -4 "${U3_IPV4}" lxc exec u2 -- ping -c1 -6 "${U3_IPV6}" -echo "==> OVN to lxdbr0 in project testovn" +echo "==> OVN to lxdbr0 instance in project testovn" lxc exec u3 -- ping -c1 -4 "${U1_IPV4}" lxc exec u3 -- ping -c1 -6 "${U1_IPV6}" @@ -182,7 +182,7 @@ echo "==> DNS resolution on OVN in project testovn" lxc exec u3 -- ping -c1 -4 u2.lxd lxc exec u3 -- ping -c1 -6 u2.lxd -echo "==> OVN to lxdbr0 in project testovn" +echo "==> OVN to lxdbr0 gateway in project testovn" lxc exec u2 -- ping -c1 10.10.10.1 lxc exec u2 -- ping -c1 fd42:4242:4242:1010::1 From 3a83bc3e415657e66d41880b844b34c97fc0010a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 16:35:15 +0100 Subject: [PATCH 3/4] bin/test-lxd-ovn: Adds test for using external subnet as OVN network address Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 39 ++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index 0ee328f..179fc57 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -116,6 +116,7 @@ lxc exec u2 -- ping -c1 -6 linuxcontainers.org echo "===> Testing project restrictions" lxc project create testovn -c features.networks=true -c restricted=true +lxc profile device add default root disk path=/ pool=default --project testovn # Test we cannot create network in restricted project with no defined uplinks. ! lxc network create ovn-virtual-network --project testovn @@ -131,9 +132,45 @@ lxc project set testovn restricted.networks.uplinks=lxdbr0,lxdbr1 ! lxc network create ovn-virtual-network --project testovn lxc network create ovn-virtual-network network=lxdbr0 --project testovn lxc network delete ovn-virtual-network --project testovn -lxc project delete testovn lxc network delete lxdbr1 --project default +# Test physical uplink with external IPs +ip link add dummy0 type dummy +lxc network create dummy --type=physical --project default \ +parent=dummy0 \ +ipv4.gateway=192.0.2.1/24 \ +ipv6.gateway=2001:db8:1:1::1/64 \ +ipv4.ovn.ranges=192.0.2.10-192.0.2.19 \ +ipv4.routes=198.51.100.0/24 \ +ipv6.routes=2001:db8:1:2::/64 \ +dns.nameservers=192.0.2.53 + +# Test using external subnets using physical uplink. +lxc project set testovn restricted.networks.uplinks=dummy +lxc network create ovn-virtual-network --type=ovn --project testovn network=dummy \ +ipv4.address=198.51.100.1/24 \ +ipv6.address=2001:db8:1:2::1/64 \ +ipv4.nat=false \ +ipv6.nat=false + +lxc init images:ubuntu/20.04 u1 --project testovn +lxc config device add u1 eth0 nic network=ovn-virtual-network name=eth0
[lxc-devel] [lxd/master] Network: Sets ipv4.nat=true by default for new fan bridges and adds the setting if missing to existing fan bridges
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8064 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) === Fixes an issue introduced by https://github.com/lxc/lxd/pull/8037 where fan bridges do not have `ipv4.nat` setting by default which broke external connectivity. From f6dd88a5b60b99fb65d23f6c769368459366d849 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 14:40:04 +0100 Subject: [PATCH 1/2] lxd/network/driver/bridge: Sets ipv4.nat=true when adding a new fan network with fan.underlay_subnet=auto Signed-off-by: Thomas Parrott --- 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 e0d8779072..72a0952ca7 100644 --- a/lxd/network/driver_bridge.go +++ b/lxd/network/driver_bridge.go @@ -89,6 +89,10 @@ func (n *bridge) FillConfig(config map[string]string) error { if config["fan.underlay_subnet"] == "" { config["fan.underlay_subnet"] = "auto" } + + if config["fan.underlay_subnet"] == "auto" && config["ipv4.nat"] == "" { + config["ipv4.nat"] = "true" + } } else { if config["ipv4.address"] == "" { config["ipv4.address"] = "auto" From e59f674cee6f2b5c3baeb694d3e351c27726c520 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 15:11:48 +0100 Subject: [PATCH 2/2] lxd/patches: Adds patchNetworkFANEnableNAT to set ipv4.nat=true for fan networks missing the setting Signed-off-by: Thomas Parrott --- lxd/patches.go | 49 + 1 file changed, 49 insertions(+) diff --git a/lxd/patches.go b/lxd/patches.go index 462cd78173..4b3d415fef 100644 --- a/lxd/patches.go +++ b/lxd/patches.go @@ -103,6 +103,7 @@ var patches = []patch{ {name: "move_backups_instances", stage: patchPostDaemonStorage, run: patchMoveBackupsInstances}, {name: "network_ovn_enable_nat", stage: patchPostDaemonStorage, run: patchNetworkOVNEnableNAT}, {name: "network_ovn_remove_routes", stage: patchPostDaemonStorage, run: patchNetworkOVNRemoveRoutes}, + {name: "network_fan_enable_nat", stage: patchPostDaemonStorage, run: patchNetworkFANEnableNAT}, } type patch struct { @@ -167,6 +168,54 @@ func patchesApply(d *Daemon, stage patchStage) error { // Patches begin here +// patchNetworkFANEnableNAT sets "ipv4.nat=true" on fan bridges that are missing the "ipv4.nat" setting. +// This prevents outbound connectivity breaking on existing fan networks now that the default behaviour of not +// having "ipv4.nat" set is to disable NAT (bringing in line with the non-fan bridge behavior and docs). +func patchNetworkFANEnableNAT(name string, d *Daemon) error { + err := d.cluster.Transaction(func(tx *db.ClusterTx) error { + projectNetworks, err := tx.GetNonPendingNetworks() + if err != nil { + return err + } + + for _, networks := range projectNetworks { + for networkID, network := range networks { + if network.Type != "bridge" { + continue + } + + if network.Config["bridge.mode"] != "fan" { + continue + } + + modified := false + + // Enable ipv4.nat if setting not specified. + if _, found := network.Config["ipv4.nat"]; !found { + modified = true + network.Config["ipv4.nat"] = "true" + } + + if modified { + err = tx.UpdateNetwork(networkID, network.Description, network.Config) + if err != nil { + return errors.Wrapf(err, "Failed setting ipv4.nat=true for fan network %q (%d)", network.Name, networkID) + } + + logger.Debugf("Set ipv4.nat=true for fan network %q (%d)", network.Name, networkID) + } + } + } + + return nil + }) + if err != nil { + return err + } + + return nil +} + // patchNetworkOVNRemoveRoutes removes the "ipv4.routes.external" and "ipv6.routes.external" settings from OVN // networks. It was decided that the OVN NIC level equivalent settings were
[lxc-devel] [lxd/master] init: Clarifies question about using an existing empty disk
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8063 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) === Fixes #8060 Signed-off-by: Thomas Parrott From 78afd4d6cc3922df13570f863ed7056eb8b71953 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 14:34:06 +0100 Subject: [PATCH] lxd/main/init/interactive: Clarifies question about using an existing empty disk Fixes #8060 Signed-off-by: Thomas Parrott --- lxd/main_init_interactive.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/main_init_interactive.go b/lxd/main_init_interactive.go index 5fa8f755a6..dfc8f0c0de 100644 --- a/lxd/main_init_interactive.go +++ b/lxd/main_init_interactive.go @@ -554,7 +554,7 @@ func (c *cmdInit) askStoragePool(config *cmdInitData, d lxd.InstanceServer, pool // Ask for the name of the cluster pool.Config["source"] = cli.AskString("Name of the CEPHfs volume: ", "", nil) - } else if cli.AskBool("Would you like to use an existing empty disk or partition? (yes/no) [default=no]: ", "no") { + } else if cli.AskBool("Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]: ", "no") { deviceExists := func(path string) error { if !shared.IsBlockdevPath(path) { return fmt.Errorf("'%s' is not a block device", path) ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Instance: Fix a class of bugs related to incorrect log path generation when instance is in non-default project
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8062 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) === I noticed this issue whilst working on OVN CI tests. The reproducer was: ``` lxc launch images:ubuntu/focal c1 --project default lxc exec c1 -- whoami --project default # Succeeds lxc init images:ubuntu/focal c1 --project test lxc exec c1 -- whoami --project default # Fails. Because the /var/log/lxd/c1/lxc.conf was removed when creating c1 in test project. ``` From 0364002a9db6bfa9707710b7b64a5ca0a93514a5 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 13:51:58 +0100 Subject: [PATCH 1/5] lxd/instance: Use project aware inst.LogPath() function when clearing log dir in instanceCreateInternal Avoids clearing lxc.conf of a different container and preventing access to it. Signed-off-by: Thomas Parrott --- lxd/instance.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/instance.go b/lxd/instance.go index 2d812f6b97..71718a6390 100644 --- a/lxd/instance.go +++ b/lxd/instance.go @@ -640,15 +640,15 @@ func instanceCreateInternal(s *state.State, args db.InstanceArgs) (instance.Inst s.Cluster.DeleteInstance(dbInst.Project, dbInst.Name) }() - // Wipe any existing log for this instance name. - os.RemoveAll(shared.LogPath(args.Name)) - args = db.InstanceToArgs() inst, err := instance.Create(s, args) if err != nil { return nil, errors.Wrap(err, "Create instance") } + // Wipe any existing log for this instance name. + os.RemoveAll(inst.LogPath()) + revert = false return inst, nil } From c029aab2ca63ea6a83f6f73be8d0e8b7a827a525 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 13:57:21 +0100 Subject: [PATCH 2/5] lxd/instance/drivers/driver/lxc: Project aware rename of log path in Rename() Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index e4290118f5..e99c01f4df 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -3682,9 +3682,10 @@ func (c *lxc) Rename(newName string) error { } // Rename the logging path. - os.RemoveAll(shared.LogPath(newName)) + newFullName := project.Instance(c.Project(), c.Name()) + os.RemoveAll(shared.LogPath(newFullName)) if shared.PathExists(c.LogPath()) { - err := os.Rename(c.LogPath(), shared.LogPath(newName)) + err := os.Rename(c.LogPath(), shared.LogPath(newFullName)) if err != nil { logger.Error("Failed renaming container", ctxMap) return err From feb558885cbedfbbf55911a5cba96d0890720b74 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 13:58:18 +0100 Subject: [PATCH 3/5] lxd/instance/drivers/driver/qemu: Project aware rename of log path in Rename() Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_qemu.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index 1abaddbbb2..733a868605 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -2647,9 +2647,10 @@ func (vm *qemu) Rename(newName string) error { } // Rename the logging path. - os.RemoveAll(shared.LogPath(newName)) + newFullName := project.Instance(vm.Project(), vm.Name()) + os.RemoveAll(shared.LogPath(newFullName)) if shared.PathExists(vm.LogPath()) { - err := os.Rename(vm.LogPath(), shared.LogPath(newName)) + err := os.Rename(vm.LogPath(), shared.LogPath(newFullName)) if err != nil { logger.Error("Failed renaming instance", ctxMap) return err From fa7f5e39b6ad4cd27b6e0dd38a3d79d9c147c293 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 14:00:26 +0100 Subject: [PATCH 4/5] lxd/instance/drivers/driver/lxc: Makes collectCRIULogFile project log path aware Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index e99c01f4df..81d814e3df 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -4815,7 +4815,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) (api.ImageMetada func collectCRIULogFile(c instance.Instance, imagesDir string, function string, method string)
[lxc-devel] [lxd/master] lxd: Fixes ineffectual assignment warnings
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8059 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) === Fixes ineffectual assignment warnings from https://goreportcard.com/report/github.com/lxc/lxd#ineffassign From ef2dfa8748815befa7f6705798c23d7445cb4691 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 09:30:13 +0100 Subject: [PATCH 1/3] lxd/images: Fixes ineffectual assign warning Signed-off-by: Thomas Parrott --- lxd/images.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/images.go b/lxd/images.go index 39c7df8d75..d97e759408 100644 --- a/lxd/images.go +++ b/lxd/images.go @@ -241,7 +241,7 @@ func imgPostInstanceInfo(d *Daemon, r *http.Request, req api.ImagesPost, op *ope Tracker: { Handler: func(value, speed int64) { percent := int64(0) - processed := int64(0) + var processed int64 if totalSize > 0 { percent = value From a4e89992943eb88dd8d1d1c010b332f626738170 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 09:31:05 +0100 Subject: [PATCH 2/3] lxd/resources/usb: Fixes ineffectual assign warning Signed-off-by: Thomas Parrott --- lxd/resources/usb.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/resources/usb.go b/lxd/resources/usb.go index 6479d252fc..fc88c459dc 100644 --- a/lxd/resources/usb.go +++ b/lxd/resources/usb.go @@ -186,7 +186,7 @@ func GetUSB() (*api.ResourcesUSB, error) { return nil, errors.Wrapf(err, "Failed to parse class ID %q", content) } - ok := false + var ok bool class, ok = usbid.Classes[usbid.ClassCode(iface.ClassID)] if ok { From 9aa5cfd3840415368d71064868391a570976c8fb Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 09:32:13 +0100 Subject: [PATCH 3/3] lxd/storage/drivers/driver/lvm/volumes: Fixes ineffectual assign warning Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_lvm_volumes.go | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lxd/storage/drivers/driver_lvm_volumes.go b/lxd/storage/drivers/driver_lvm_volumes.go index fbe1ef16da..e761fa2582 100644 --- a/lxd/storage/drivers/driver_lvm_volumes.go +++ b/lxd/storage/drivers/driver_lvm_volumes.go @@ -433,12 +433,9 @@ func (d *lvm) GetVolumeDiskPath(vol Volume) (string, error) { // MountVolume mounts a volume. Returns true if this volume was our mount. func (d *lvm) MountVolume(vol Volume, op *operations.Operation) (bool, error) { - var err error - activated := false - // Activate LVM volume if needed. volDevPath := d.lvmDevPath(d.config["lvm.vg_name"], vol.volType, vol.contentType, vol.name) - activated, err = d.activateVolume(volDevPath) + activated, err := d.activateVolume(volDevPath) if err != nil { return false, err } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/stable-4.0] Doc: Re-organises NIC device type docs introducing section about network property
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8058 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) === - Adds explanation of `network` property. - Removes `nictype` prefix on each NIC device type section (to avoid confusion when a NIC can be specified using both `nictype` and `network). - Adds `Managed` column for `bridged` NIC type. - Re-formats additional info section at bottom. Signed-off-by: Thomas Parrott From 5626dd4362c5ac65039c76cc4485c66396fb035e Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 20 Oct 2020 09:04:42 +0100 Subject: [PATCH] doc/instances: Re-organises NIC device type docs introducing section about network property Signed-off-by: Thomas Parrott --- doc/instances.md | 190 --- 1 file changed, 99 insertions(+), 91 deletions(-) diff --git a/doc/instances.md b/doc/instances.md index 7efdf5dd71..9290de18d2 100644 --- a/doc/instances.md +++ b/doc/instances.md @@ -250,25 +250,74 @@ To do so, just add a none type device with the same name of the one you wish to It can be added in a profile being applied after the profile it originated from or directly on the instance. ### Type: nic -LXD supports different kind of network devices: +LXD supports several different kinds of network devices (referred to as Network Interface Controller or NIC). - - [physical](#nictype-physical): Straight physical device passthrough from the host. The targeted device will vanish from the host and appear in the instance. - - [bridged](#nictype-bridged): Uses an existing bridge on the host and creates a virtual device pair to connect the host bridge to the instance. - - [macvlan](#nictype-macvlan): Sets up a new network device based on an existing one but using a different MAC address. - - [ipvlan](#nictype-ipvlan): Sets up a new network device based on an existing one using the same MAC address but a different IP. - - [p2p](#nictype-p2p): Creates a virtual device pair, putting one side in the instance and leaving the other side on the host. - - [sriov](#nictype-sriov): Passes a virtual function of an SR-IOV enabled physical network device into the instance. - - [routed](#nictype-routed): Creates a virtual device pair to connect the host to the instance and sets up static routes and proxy ARP/NDP entries to allow the instance to join the network of a designated parent interface. +When adding a network device to an instance, there are two ways to specify the type of device you want to add; +either by specifying the `nictype` property or using the `network` property. -Different network interface types have different additional properties. + Specifying a NIC using the `network` property -Each possible `nictype` value is documented below along with the relevant properties for nics of that type. +When specifying the `network` property, the NIC is linked to an existing managed network and the `nictype` is +automatically detected based on the network's type. - nictype: physical +Some of the NICs properties are inherited from the network rather than being customisable for each NIC. + +These are detailed in the "Managed" column in the NIC specific sections below. + + NICs Available: + +See the NIC's settings below for details about which properties are available. + +The following NICs can be specified using the `nictype` or `network` properties: + + - [bridged](#nic-bridged): Uses an existing bridge on the host and creates a virtual device pair to connect the host bridge to the instance. + +The following NICs can be specified using only the `nictype` property: + + - [macvlan](#nic-macvlan): Sets up a new network device based on an existing one but using a different MAC address. + - [sriov](#nic-sriov): Passes a virtual function of an SR-IOV enabled physical network device into the instance. + - [physical](#nic-physical): Straight physical device passthrough from the host. The targeted device will vanish from the host and appear in the instance. + - [ipvlan](#nic-ipvlan): Sets up a new network device based on an existing one using the same MAC address but a different IP. + - [p2p](#nic-p2p): Creates a virtual device pair, putting one side in the instance and leaving the other side on the host. + - [routed](#nic-routed): Creates a virtual device pair to connect the host to the instance and sets up static routes and proxy ARP/NDP entries to allow the instance to join the network of a designated parent interface. + + nic: bridged Supported instance types: container, VM -Straight physical device passthrough from the host. The targeted device will vanish from the host and appear in the instance. +Selected using: `nictype`, `network` + +Uses an existing bridge on the host and creates a virtual device pair to connect the
[lxc-devel] [lxd/master] Network: Fix project restricted subnets check in OVN network validateExternalSubnet
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8056 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) === Signed-off-by: Thomas Parrott From bccedf2bdde9459fcf7bc5dd1862f6f651a92679 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 19 Oct 2020 17:44:15 +0100 Subject: [PATCH] lxd/network/driver/ovn: Fix project restricted subnets check in validateExternalSubnet Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index ea1616d269..cf1b91ed82 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -86,7 +86,7 @@ func (n *ovn) validateExternalSubnet(uplinkRoutes []*net.IPNet, projectRestricte if projectRestrictedSubnets != nil { foundMatch := false for _, projectRestrictedSubnet := range projectRestrictedSubnets { - if !SubnetContains(projectRestrictedSubnet, ipNet) { + if SubnetContains(projectRestrictedSubnet, ipNet) { foundMatch = true break } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Network: Removes OVN ipv4.routes.external and ipv6.routes.external
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8055 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) === These are only used on OVN NICs now. From 71caae866af04c142dbb48cc19a4d7a126e3657a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 19 Oct 2020 15:56:33 +0100 Subject: [PATCH 01/15] lxd/network/driver/ovn: Only call Validate in FillConfig if state is set Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index ea1616d269..cfc5e7fff2 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1168,7 +1168,7 @@ func (n *ovn) FillConfig(config map[string]string) error { changedConfig = true } - if changedConfig { + if changedConfig && n.state != nil { return n.Validate(config) } From f6add9084341a88c0847398eb4db5610e7e5f1bd Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 19 Oct 2020 15:56:15 +0100 Subject: [PATCH 02/15] lxd/db/projects: Adds GetProject function Signed-off-by: Thomas Parrott --- lxd/db/projects.go | 19 +++ 1 file changed, 19 insertions(+) diff --git a/lxd/db/projects.go b/lxd/db/projects.go index cf03765ea5..ff613611d1 100644 --- a/lxd/db/projects.go +++ b/lxd/db/projects.go @@ -189,3 +189,22 @@ func (c *ClusterTx) InitProjectWithoutImages(project string) error { _, err = c.tx.Exec(stmt, defaultProfileID) return err } + +// GetProject returns the project with the given key. +func (c *Cluster) GetProject(projectName string) (*api.Project, error) { + var err error + var p *api.Project + err = c.Transaction(func(tx *ClusterTx) error { + p, err = tx.GetProject(projectName) + if err != nil { + return err + } + + return nil + }) + if err != nil { + return nil, err + } + + return p, nil +} From fa2da560919d515ecd24a2aebc40b4a213c34fea Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 19 Oct 2020 13:56:53 +0100 Subject: [PATCH 03/15] lxd/network/driver/ovn: Converts instance port functions to exported So they can be accessed by OVN NIC directly. Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index cfc5e7fff2..25780813e1 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1887,8 +1887,8 @@ func (n *ovn) getInstanceDevicePortName(instanceID int, deviceName string) openv return openvswitch.OVNSwitchPort(fmt.Sprintf("%s-%d-%s", n.getIntSwitchInstancePortPrefix(), instanceID, deviceName)) } -// instanceDevicePortAdd adds an instance device port to the internal logical switch and returns the port name. -func (n *ovn) instanceDevicePortAdd(instanceID int, instanceName string, deviceName string, mac net.HardwareAddr, ips []net.IP, internalRoutes []*net.IPNet, externalRoutes []*net.IPNet) (openvswitch.OVNSwitchPort, error) { +// InstanceDevicePortAdd adds an instance device port to the internal logical switch and returns the port name. +func (n *ovn) InstanceDevicePortAdd(instanceID int, instanceName string, deviceName string, mac net.HardwareAddr, ips []net.IP, internalRoutes []*net.IPNet, externalRoutes []*net.IPNet) (openvswitch.OVNSwitchPort, error) { var dhcpV4ID, dhcpv6ID string revert := revert.New() @@ -2065,8 +2065,8 @@ func (n *ovn) instanceDevicePortAdd(instanceID int, instanceName string, deviceN return instancePortName, nil } -// instanceDevicePortIPs returns the dynamically allocated IPs for a device port. -func (n *ovn) instanceDevicePortDynamicIPs(instanceID int, deviceName string) ([]net.IP, error) { +// InstanceDevicePortDynamicIPs returns the dynamically allocated IPs for a device port. +func (n *ovn) InstanceDevicePortDynamicIPs(instanceID int, deviceName string) ([]net.IP, error) { instancePortName := n.getInstanceDevicePortName(instanceID, deviceName) client, err := n.getClient() @@ -2077,8 +2077,8 @@ func (n *ovn) instanceDevicePortDynamicIPs(instanceID int, deviceName string) ([ return client.LogicalSwitchPortDynamicIPs(instancePortName) } -// instanceDevicePortDelete deletes an instance device port from the internal logical switch. -func (n *ovn) instanceDevicePortDelete(instanceID int, deviceName string, internalRoutes []*net.IPNet, externalRoutes []*net.IPNet) error { +// InstanceDevicePortDelete deletes an instance device port from the internal logical switch. +func (n *ovn) InstanceDevicePortDelete(instanceID int,
[lxc-devel] [lxd/master] Network: Adds support for "none" in "ipv4.address" and "ipv6.address" settings
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8053 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) === From 0e5c2730002452dbc53a11c3dab6e681cd19d3df Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 19 Oct 2020 09:29:59 +0100 Subject: [PATCH 1/4] lxd/network/driver/ovn: Allows "none" as value for ipv4.address and ipv6.address Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 5ea70ba071..04b846b3f1 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -120,14 +120,14 @@ func (n *ovn) Validate(config map[string]string) error { "bridge.hwaddr": validate.Optional(validate.IsNetworkMAC), "bridge.mtu":validate.Optional(validate.IsNetworkMTU), "ipv4.address": func(value string) error { - if validate.IsOneOf(value, []string{"auto"}) == nil { + if validate.IsOneOf(value, []string{"none", "auto"}) == nil { return nil } return validate.Optional(validate.IsNetworkAddressCIDRV4)(value) }, "ipv6.address": func(value string) error { - if validate.IsOneOf(value, []string{"auto"}) == nil { + if validate.IsOneOf(value, []string{"none", "auto"}) == nil { return nil } @@ -219,7 +219,7 @@ func (n *ovn) Validate(config map[string]string) error { // If NAT disabled, check subnets are within the uplink network's routes and project's subnet restrictions. for _, keyPrefix := range []string{"ipv4", "ipv6"} { - if !shared.IsTrue(config[fmt.Sprintf("%s.nat", keyPrefix)]) && config[fmt.Sprintf("%s.address", keyPrefix)] != "" { + if !shared.IsTrue(config[fmt.Sprintf("%s.nat", keyPrefix)]) && validate.IsOneOf(config[fmt.Sprintf("%s.address", keyPrefix)], []string{"", "none", "auto"}) != nil { _, ipNet, err := net.ParseCIDR(config[fmt.Sprintf("%s.address", keyPrefix)]) if err != nil { return err From 9d4ceec468a1fc0d1a81597cddba19793f97951b Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 19 Oct 2020 11:18:44 +0100 Subject: [PATCH 2/4] lxd/network/driver/ovn: Re-run validation of auto generated address used in FillConfig Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 12 1 file changed, 12 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 04b846b3f1..d8b9b39714 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1122,14 +1122,18 @@ func (n *ovn) deleteUplinkPortPhysical(uplinkNet Network) error { // FillConfig fills requested config with any default values. func (n *ovn) FillConfig(config map[string]string) error { + changedConfig := false + if config["ipv4.address"] == "" { config["ipv4.address"] = "auto" + changedConfig = true } if config["ipv6.address"] == "" { content, err := ioutil.ReadFile("/proc/sys/net/ipv6/conf/default/disable_ipv6") if err == nil && string(content) == "0\n" { config["ipv6.address"] = "auto" + changedConfig = true } } @@ -1145,6 +1149,8 @@ func (n *ovn) FillConfig(config map[string]string) error { if config["ipv4.nat"] == "" { config["ipv4.nat"] = "true" } + + changedConfig = true } if config["ipv6.address"] == "auto" { @@ -1158,6 +1164,12 @@ func (n *ovn) FillConfig(config map[string]string) error { if config["ipv6.nat"] == "" { config["ipv6.nat"] = "true" } + + changedConfig = true + } + + if changedConfig { + return n.Validate(config) } return nil From f3da8b57c47423616e6490c89fb820be6c5dd651 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 19 Oct 2020 11:21:00 +0100 Subject: [PATCH 3/4] lxd/network/driver/ovn: Modify setup() to support optional IP addresses Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 66 ++- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index d8b9b39714..4e06b123e2 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1371,14 +1371,14 @@ func (n *ovn)
[lxc-devel] [lxd/master] Network: Generates EUI64 IPv6 DNS record for OVN NICs when static IPv4 address is defined
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8045 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) === Fixes an issue where if a static IPv4 address was set for a NIC using ipv4.address, as OVN does not allow a mixture of static and dynamic IPs on a port, this would prevent a dynamic IPv6 address from being added to the port, which in turn prevented a DNS name from being created. We now populate the logical port with a static EUI64 address if only static IPv4 addresses are set, and IPv6 is enabled on the bridge. From c470380fd10673ee00dd9bf1e28371bf4e3fb2bb Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 16 Oct 2020 10:18:27 +0100 Subject: [PATCH 1/2] lxd/device/nic/ovn: Improved error messages Signed-off-by: Thomas Parrott --- lxd/device/nic_ovn.go | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lxd/device/nic_ovn.go b/lxd/device/nic_ovn.go index 766adbcdf0..091888ab60 100644 --- a/lxd/device/nic_ovn.go +++ b/lxd/device/nic_ovn.go @@ -300,7 +300,7 @@ func (d *nicOVN) Start() (*deviceConfig.RunConfig, error) { internalRoutes, err = network.SubnetParseAppend(internalRoutes, strings.Split(d.config[key], ",")...) if err != nil { - return nil, errors.Wrapf(err, "Invalid %s", key) + return nil, errors.Wrapf(err, "Invalid %q value", key) } } @@ -312,7 +312,7 @@ func (d *nicOVN) Start() (*deviceConfig.RunConfig, error) { externalRoutes, err = network.SubnetParseAppend(externalRoutes, strings.Split(d.config[key], ",")...) if err != nil { - return nil, errors.Wrapf(err, "Invalid %s", key) + return nil, errors.Wrapf(err, "Invalid %q value", key) } } @@ -439,7 +439,7 @@ func (d *nicOVN) Stop() (*deviceConfig.RunConfig, error) { internalRoutes, err = network.SubnetParseAppend(internalRoutes, strings.Split(d.config[key], ",")...) if err != nil { - return nil, errors.Wrapf(err, "Invalid %s", key) + return nil, errors.Wrapf(err, "Invalid %q value", key) } } @@ -451,7 +451,7 @@ func (d *nicOVN) Stop() (*deviceConfig.RunConfig, error) { externalRoutes, err = network.SubnetParseAppend(externalRoutes, strings.Split(d.config[key], ",")...) if err != nil { - return nil, errors.Wrapf(err, "Invalid %s", key) + return nil, errors.Wrapf(err, "Invalid %q value", key) } } From 1666e7465339f83f126960324849268e495a4c71 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 16 Oct 2020 14:32:48 +0100 Subject: [PATCH 2/2] lxd/network/driver/ovn: Generates static EUI64 IPv6 address for instance switch ports in instanceDevicePortAdd When only static IPv4 addresses have been added to a logical switch port. This ensures that the switch port has an IPv6 address, as OVN has a limitation that prevents a port from being statically addressed for IPv4 and dynamically allocated for IPv6. This in turn meant that if using the `ipv4.address` key without an associated `ipv6.address` key, then DNS record would not be created. Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 24 1 file changed, 24 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index a6dc816a7a..47f1c0daf9 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1873,6 +1873,30 @@ func (n *ovn) instanceDevicePortAdd(instanceID int, instanceName string, deviceN if err != nil { return "", err } + + // If port isn't going to have fully dynamic IPs allocated by OVN, and instead only static IPv4 + // addresses have been added, then add an EUI64 static IPv6 address so that the switch port has an + // IPv6 address that will be used to generate a DNS record. This works around a limitation in OVN + // that prevents us requesting dynamic IPv6 address allocation when static IPv4 allocation is used. + if len(ips) > 0 { + hasIPv6 := false + for _, ip := range ips { + if ip.To4() == nil { + hasIPv6 = true + break + } + } + + if !hasIPv6 { + eui64IP, err := eui64.ParseMAC(routerIntPortIPv6Net.IP, mac) + if err != nil { +
[lxc-devel] [lxd/master] Network: Adds support for external subnets for OVN networks
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8044 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) === - Adds support for using subnets from the OVN network's `ipv4.routes.external` and `ipv6.routes.external` for OVN networ's main subnet, as long as the associated `ipv4.nat` or `ipv6.nat` setting(s) are disabled. - Allows for instance IPs on OVN networks to be published to the external uplink network (no NAT mode). - Fixes an issue where if a static IPv4 address was set for a NIC using `ipv4.address`, OVN does not allow a mixture of static and dynamic IPs on a port, so this would prevent a dynamic IPv6 address from being added to the port, which in turn prevented a DNS name from being created. We now populate the logical port with an EUI64 address if only static IPv4 addresses are set, and IPv6 is enabled on the bridge. From 05044a7c2567cd52534bc48ac61e207363f56556 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 16 Oct 2020 14:31:22 +0100 Subject: [PATCH 1/6] lxd/network/openvswitch/ovn: Adds LogicalSwitchPortGetDNS to return switch port DNS info Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovn.go | 35 ++ 1 file changed, 35 insertions(+) diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go index bb08c505af..475398d23e 100644 --- a/lxd/network/openvswitch/ovn.go +++ b/lxd/network/openvswitch/ovn.go @@ -791,6 +791,41 @@ func (o *OVN) LogicalSwitchPortSetDNS(switchName OVNSwitch, portName OVNSwitchPo return dnsIPv4, dnsIPv6, nil } +// LogicalSwitchPortGetDNS returns the logical switch port DNS info (UUID, name and IPs). +func (o *OVN) LogicalSwitchPortGetDNS(portName OVNSwitchPort) (string, string, []net.IP, error) { + // Get UUID and DNS IPs for a switch port in the format: ",= " + output, err := o.nbctl("--format=csv", "--no-headings", "--data=bare", "--colum=_uuid,records", "find", "dns", + fmt.Sprintf("external_ids:lxd_switch_port=%s", string(portName)), + ) + if err != nil { + return "", "", nil, err + } + + parts := strings.Split(strings.TrimSpace(output), ",") + dnsUUID := strings.TrimSpace(parts[0]) + + var dnsName string + var ips []net.IP + + // Try and parse the DNS name and IPs. + if len(parts) > 1 { + dnsParts := strings.SplitN(strings.TrimSpace(parts[1]), "=", 2) + if len(dnsParts) == 2 { + dnsName = strings.TrimSpace(dnsParts[0]) + ipParts := strings.Split(dnsParts[1], " ") + for _, ipPart := range ipParts { + ip := net.ParseIP(strings.TrimSpace(ipPart)) + if ip != nil { + ips = append(ips, ip) + } + } + } + + } + + return dnsUUID, dnsName, ips, nil +} + // LogicalSwitchPortDeleteDNS removes DNS records for a switch port. func (o *OVN) LogicalSwitchPortDeleteDNS(switchName OVNSwitch, portName OVNSwitchPort) error { // Check if existing DNS record exists for switch port. From 835968cbbdc2e9f104422e93102cea9f8c063408 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 16 Oct 2020 14:30:47 +0100 Subject: [PATCH 2/6] lxd/network/openvswitch/ovn: Updates LogicalSwitchPortDeleteDNS to only accept DNS UUID rather than port name Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovn.go | 25 +++-- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go index 475398d23e..b6a05abf18 100644 --- a/lxd/network/openvswitch/ovn.go +++ b/lxd/network/openvswitch/ovn.go @@ -827,28 +827,17 @@ func (o *OVN) LogicalSwitchPortGetDNS(portName OVNSwitchPort) (string, string, [ } // LogicalSwitchPortDeleteDNS removes DNS records for a switch port. -func (o *OVN) LogicalSwitchPortDeleteDNS(switchName OVNSwitch, portName OVNSwitchPort) error { - // Check if existing DNS record exists for switch port. - dnsUUID, err := o.nbctl("--format=csv", "--no-headings", "--data=bare", "--colum=_uuid", "find", "dns", - fmt.Sprintf("external_ids:lxd_switch_port=%s", string(portName)), - ) +func (o *OVN) LogicalSwitchPortDeleteDNS(switchName OVNSwitch, dnsUUID string) error { + // Remove DNS record association from switch. + _, err := o.nbctl("remove", "logical_switch", string(switchName), "dns_records", dnsUUID) if err != nil { return err } - dnsUUID = strings.TrimSpace(dnsUUID) - if dnsUUID != "" { - // Remove DNS record association from switch. -
[lxc-devel] [lxd/master] network: Adds OVN ipv4.nat and ipv6.nat keys
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8038 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) === These will be automatically added to new OVN networks when the associated IP address setting is being auto-generated. Otherwise if these settings are missing then the default is to disable NAT. From e67455914b5fe60c4a16c7a102518f3358df7ebf Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 15 Oct 2020 17:29:57 +0100 Subject: [PATCH 1/3] api: Adds network_ovn_nat extension Signed-off-by: Thomas Parrott --- doc/api-extensions.md | 8 shared/version/api.go | 1 + 2 files changed, 9 insertions(+) diff --git a/doc/api-extensions.md b/doc/api-extensions.md index 06d84d4570..aac2f59bcf 100644 --- a/doc/api-extensions.md +++ b/doc/api-extensions.md @@ -1200,3 +1200,11 @@ allowed to be used in child OVN networks in their `ipv4.routes.external` and `ip Introduces the `restricted.networks.subnets` project setting that specifies which external subnets are allowed to be used by OVN networks inside the project (if not set then all routes defined on the uplink network are allowed). + +## network\_ovn\_nat +Adds support for `ipv4.nat` and `ipv6.nat` settings on `ovn` networks. + +When creating the network if these settings are unspecified, and an equivalent IP address is being generated for +the subnet, then the appropriate NAT setting will added set to `true`. + +If the setting is missing then the value is taken as `false`. diff --git a/shared/version/api.go b/shared/version/api.go index 9d9da206d9..b0bada4a3f 100644 --- a/shared/version/api.go +++ b/shared/version/api.go @@ -231,6 +231,7 @@ var APIExtensions = []string{ "storage_rsync_compression", "network_type_physical", "network_ovn_external_subnets", + "network_ovn_nat", } // APIExtensionsCount returns the number of available API extensions. From 69e1cdff5f9b5e64db04ff731863b51c23f69251 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 15 Oct 2020 16:48:03 +0100 Subject: [PATCH 2/3] doc/networks: Adds ipv4.nat and ipv6.nat to OVN networks Signed-off-by: Thomas Parrott --- doc/networks.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/networks.md b/doc/networks.md index 3d972ddf72..6fb54fec4d 100644 --- a/doc/networks.md +++ b/doc/networks.md @@ -317,9 +317,11 @@ mtu | integer | - | - parent | string| - | - | Parent interface to create sriov NICs on vlan| integer | - | - | The VLAN ID to attach to ipv4.gateway| string| standard mode | - | IPv4 address for the gateway and network (CIDR notation) +ipv4.nat| boolean | ipv4 address | false | Whether to NAT (will default to true if unset and a random ipv4.address is generated) ipv4.ovn.ranges | string| - | none | Comma separate list of IPv4 ranges to use for child OVN network routers (FIRST-LAST format) ipv4.routes | string| ipv4 address | - | Comma separated list of additional IPv4 CIDR subnets that can be used with child OVN networks ipv4.routes.external setting ipv6.gateway| string| standard mode | - | IPv6 address for the gateway and network (CIDR notation) +ipv6.nat| boolean | ipv6 address | false | Whether to NAT (will default to true if unset and a random ipv6.address is generated) ipv6.ovn.ranges | string| - | none | Comma separate list of IPv6 ranges to use for child OVN network routers (FIRST-LAST format) ipv6.routes | string| ipv6 address | - | Comma separated list of additional IPv6 CIDR subnets that can be used with child OVN networks ipv6.routes.external setting dns.nameservers | string| standard mode | - | List of DNS server IPs on physical network From 9d52d2f6597aa76df8dc7deb95903d2294cf3a21 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 15 Oct 2020 17:13:00 +0100 Subject: [PATCH 3/3] lxd/network/driver/ovn: Adds ipv4.nat and ipv6.nat support NAT defaults to disabled if these settings are unset. Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lxd/network/driver_ovn.go
[lxc-devel] [lxd/master] Instance: Updates templateApplyNow to close files at end of each iteration
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8035 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) === By using an anonymous function so that defer runs at end of each iteration. Similar to fix in https://github.com/lxc/lxd/pull/8025 Signed-off-by: Thomas Parrott From 6ffef1d5a7cd31671e1595fa4670fe58570acb1b Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Thu, 15 Oct 2020 09:37:57 +0100 Subject: [PATCH] lxd/instance/drivers: Updates templateApplyNow to close files at end of each iteration By using an anonymous function so that defer runs at end of each iteration. Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_lxc.go | 124 +++- lxd/instance/drivers/driver_qemu.go | 99 +++--- 2 files changed, 119 insertions(+), 104 deletions(-) diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go index ac307d6d1e..7e716b9d7d 100644 --- a/lxd/instance/drivers/driver_lxc.go +++ b/lxd/instance/drivers/driver_lxc.go @@ -5119,81 +5119,89 @@ func (c *lxc) templateApplyNow(trigger string) error { // Go through the templates for tplPath, tpl := range metadata.Templates { - var w *os.File + err = func(tplPath string, tpl *api.ImageMetadataTemplate) error { + var w *os.File + + // Check if the template should be applied now + found := false + for _, tplTrigger := range tpl.When { + if tplTrigger == trigger { + found = true + break + } + } - // Check if the template should be applied now - found := false - for _, tplTrigger := range tpl.When { - if tplTrigger == trigger { - found = true - break + if !found { + return nil } - } - if !found { - continue - } + // Open the file to template, create if needed + fullpath := filepath.Join(c.RootfsPath(), strings.TrimLeft(tplPath, "/")) + if shared.PathExists(fullpath) { + if tpl.CreateOnly { + return nil + } - // Open the file to template, create if needed - fullpath := filepath.Join(c.RootfsPath(), strings.TrimLeft(tplPath, "/")) - if shared.PathExists(fullpath) { - if tpl.CreateOnly { - continue + // Open the existing file + w, err = os.Create(fullpath) + if err != nil { + return errors.Wrap(err, "Failed to create template file") + } + } else { + // Create the directories leading to the file + shared.MkdirAllOwner(path.Dir(fullpath), 0755, int(rootUID), int(rootGID)) + + // Create the file itself + w, err = os.Create(fullpath) + if err != nil { + return err + } + + // Fix ownership and mode + w.Chown(int(rootUID), int(rootGID)) + w.Chmod(0644) } + defer w.Close() - // Open the existing file - w, err = os.Create(fullpath) + // Read the template + tplString, err := ioutil.ReadFile(filepath.Join(c.TemplatesPath(), tpl.Template)) if err != nil { - return errors.Wrap(err, "Failed to create template file") + return errors.Wrap(err, "Failed to read template file") } - } else { - // Create the directories leading to the file - shared.MkdirAllOwner(path.Dir(fullpath), 0755, int(rootUID), int(rootGID)) - // Create the file itself - w, err = os.Create(fullpath) + // Restrict filesystem access to within the container's rootfs +
[lxc-devel] [lxd/master] Network: Adds ability route external IPs to OVN NICs
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8031 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) === Introduces the ability to route external IPs to OVN NICs by way of proxy ARP (for IPv4) or proxy NDP (for IPv6). This is achieved using the following process: 1. Define a `physical` network with `ipv4.routes` and/or `ipv6.routes` set - this indicates which subnets the upstream router has already routed into the physical network (but importantly, *not* to the LXD host's IP). 2. Optionally you can set `restricted.networks.subnets` on a project to allocate a subset of the routes set on the uplink network as allowed for use with OVN networks inside this project. 3. Next, create an `ovn` network and set the `ipv4.routes.external` and/or `ipv6.routes.external` to a list of subnets that are within *both* the uplink's routes and (if set) the project's `restricted.networks.subnets` setting. 4. Finally, add an `ovn` NIC device to an instance, and specify `ipv4.routes.external` and/or `ipv6.routes.external` as a list of subnets that should be routed to the NIC device and published to the uplink network using proxy ARP or proxy NDP. From 36502eb09df6082b16108e759cd405ce1a8cc170 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 9 Oct 2020 10:13:46 +0100 Subject: [PATCH 01/30] lxd/api/project: Adds restricted.networks.subnets config key Signed-off-by: Thomas Parrott --- lxd/api_project.go | 1 + 1 file changed, 1 insertion(+) diff --git a/lxd/api_project.go b/lxd/api_project.go index 770e9abf65..d70d1a2901 100644 --- a/lxd/api_project.go +++ b/lxd/api_project.go @@ -556,6 +556,7 @@ var projectConfigKeys = map[string]func(value string) error{ "restricted.devices.nic": isEitherAllowOrBlockOrManaged, "restricted.devices.disk": isEitherAllowOrBlockOrManaged, "restricted.networks.uplinks": validate.IsAny, + "restricted.networks.subnets": validate.Optional(validate.IsNetworkList), } func projectValidateConfig(config map[string]string) error { From 5be6eede2f1c35babfabfa7ca03e930aef68ca53 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 9 Oct 2020 10:14:24 +0100 Subject: [PATCH 02/30] lxd/network/driver/physical: Adds ipv4.routes and ipv6.routes config keys Signed-off-by: Thomas Parrott --- lxd/network/driver_physical.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxd/network/driver_physical.go b/lxd/network/driver_physical.go index bcbcc8cf1f..3d24584924 100644 --- a/lxd/network/driver_physical.go +++ b/lxd/network/driver_physical.go @@ -43,6 +43,8 @@ func (n *physical) Validate(config map[string]string) error { "ipv6.gateway": validate.Optional(validate.IsNetworkAddressCIDRV6), "ipv4.ovn.ranges": validate.Optional(validate.IsNetworkRangeV4List), "ipv6.ovn.ranges": validate.Optional(validate.IsNetworkRangeV6List), + "ipv4.routes": validate.Optional(validate.IsNetworkV4List), + "ipv6.routes": validate.Optional(validate.IsNetworkV6List), "dns.nameservers": validate.Optional(validate.IsNetworkAddressList), "volatile.last_state.created": validate.Optional(validate.IsBool), } From 6a01cbf588a2205d5e867969ac42047f64356491 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 9 Oct 2020 10:14:46 +0100 Subject: [PATCH 03/30] lxd/network/driver/ovn: Adds ipv4.routes and ipv6.routes config keys Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index ca3373c9f4..972ea31828 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -99,6 +99,8 @@ func (n *ovn) Validate(config map[string]string) error { return validate.Optional(validate.IsNetworkAddressCIDRV6)(value) }, "ipv6.dhcp.stateful": validate.Optional(validate.IsBool), + "ipv4.routes": validate.Optional(validate.IsNetworkV4List), + "ipv6.routes": validate.Optional(validate.IsNetworkV6List), "dns.domain": validate.IsAny, "dns.search": validate.IsAny, From cf9f092edb0218164eb37e737bd1d47b5d4a1456 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 13 Oct 2020 14:25:00 +0100 Subject: [PATCH 04/30] lxd/network/network/utils: Adds SubnetContains function Signed-off-by: Thomas Parrott --- lxd/network/network_utils.go | 26 ++ 1 file changed, 26 insertions(+) diff --git a/lxd/network/network_utils.go b/lxd/network/network_utils.go index
[lxc-devel] [lxd/master] Network: OVN uplink terminology
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8028 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) === - Ensures consistent use of uplink terminology rather than parent in docs and code. - Adds new validators for forthcoming restricted subnets feature - Bans colon char from network name. From 5d8ced58e9b060ef3638237f3b6ffeb150c65c23 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 9 Oct 2020 09:38:36 +0100 Subject: [PATCH 1/8] shared/validate/validate: Removes inaccurate comments about optional values Signed-off-by: Thomas Parrott --- shared/validate/validate.go | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/shared/validate/validate.go b/shared/validate/validate.go index 10067d8c26..92939c4e39 100644 --- a/shared/validate/validate.go +++ b/shared/validate/validate.go @@ -161,7 +161,7 @@ func IsNetworkMAC(value string) error { return nil } -// IsNetworkAddress validates an IP (v4 or v6) address string. If string is empty, returns valid. +// IsNetworkAddress validates an IP (v4 or v6) address string. func IsNetworkAddress(value string) error { ip := net.ParseIP(value) if ip == nil { @@ -184,7 +184,7 @@ func IsNetworkAddressList(value string) error { return nil } -// IsNetworkV4 validates an IPv4 CIDR string. If string is empty, returns valid. +// IsNetworkV4 validates an IPv4 CIDR string. func IsNetworkV4(value string) error { ip, subnet, err := net.ParseCIDR(value) if err != nil { @@ -202,7 +202,7 @@ func IsNetworkV4(value string) error { return nil } -// IsNetworkAddressV4 validates an IPv4 addresss string. If string is empty, returns valid. +// IsNetworkAddressV4 validates an IPv4 addresss string. func IsNetworkAddressV4(value string) error { ip := net.ParseIP(value) if ip == nil || ip.To4() == nil { @@ -212,7 +212,7 @@ func IsNetworkAddressV4(value string) error { return nil } -// IsNetworkAddressCIDRV4 validates an IPv4 addresss string in CIDR format. If string is empty, returns valid. +// IsNetworkAddressCIDRV4 validates an IPv4 addresss string in CIDR format. func IsNetworkAddressCIDRV4(value string) error { ip, subnet, err := net.ParseCIDR(value) if err != nil { @@ -256,7 +256,7 @@ func IsNetworkV4List(value string) error { return nil } -// IsNetworkV6 validates an IPv6 CIDR string. If string is empty, returns valid. +// IsNetworkV6 validates an IPv6 CIDR string. func IsNetworkV6(value string) error { ip, subnet, err := net.ParseCIDR(value) if err != nil { @@ -274,7 +274,7 @@ func IsNetworkV6(value string) error { return nil } -// IsNetworkAddressV6 validates an IPv6 addresss string. If string is empty, returns valid. +// IsNetworkAddressV6 validates an IPv6 addresss string. func IsNetworkAddressV6(value string) error { ip := net.ParseIP(value) if ip == nil || ip.To4() != nil { @@ -284,7 +284,7 @@ func IsNetworkAddressV6(value string) error { return nil } -// IsNetworkAddressCIDRV6 validates an IPv6 addresss string in CIDR format. If string is empty, returns valid. +// IsNetworkAddressCIDRV6 validates an IPv6 addresss string in CIDR format. func IsNetworkAddressCIDRV6(value string) error { ip, subnet, err := net.ParseCIDR(value) if err != nil { From 6bc696e845f1e50f717363cb9b9191320452952a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 9 Oct 2020 09:39:08 +0100 Subject: [PATCH 2/8] shared/validate/validate: Adds IsNetwork and IsNetworkList functions Signed-off-by: Thomas Parrott --- shared/validate/validate.go | 26 ++ 1 file changed, 26 insertions(+) diff --git a/shared/validate/validate.go b/shared/validate/validate.go index 92939c4e39..3978ad5a80 100644 --- a/shared/validate/validate.go +++ b/shared/validate/validate.go @@ -184,6 +184,32 @@ func IsNetworkAddressList(value string) error { return nil } +// IsNetwork validates an IP network CIDR string. +func IsNetwork(value string) error { + ip, subnet, err := net.ParseCIDR(value) + if err != nil { + return err + } + + if ip.String() != subnet.IP.String() { + return fmt.Errorf("Not an IP network address %q", value) + } + + return nil +} + +// IsNetworkList validates a comma delimited list of IP network CIDR strings. +func IsNetworkList(value string) error { + for _, network := range strings.Split(value, ",") { + err := IsNetwork(strings.TrimSpace(network)) + if err != nil { + return err + } + } + + return nil +} + // IsNetworkV4 validates an IPv4 CIDR string. func IsNetworkV4(value string) error { ip,
[lxc-devel] [lxd/master] Storage: Don't remove empty LVM thinpool and volume group if lvm.vg.force_reuse enabled
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8023 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) === Signed-off-by: Thomas Parrott From 54922c2dd5ef61454df93b4535f6c6d4be0f42ce Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 12 Oct 2020 17:43:48 +0100 Subject: [PATCH] lxd/storage/drivers/driver/lvm: Don't remove empty thinpool and volume group if lvm.vg.force_reuse enabled Signed-off-by: Thomas Parrott --- lxd/storage/drivers/driver_lvm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/drivers/driver_lvm.go b/lxd/storage/drivers/driver_lvm.go index f68d537cd8..cda510284f 100644 --- a/lxd/storage/drivers/driver_lvm.go +++ b/lxd/storage/drivers/driver_lvm.go @@ -333,7 +333,7 @@ func (d *lvm) Delete(op *operations.Operation) error { } removeVg := false - if vgExists { + if vgExists && !shared.IsTrue(d.config["lvm.vg.force_reuse"]) { // Count normal and thin volumes. lvCount, err := d.countLogicalVolumes(d.config["lvm.vg_name"]) if err != nil && err != errLVMNotFound { ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxc-ci/master] bin/test-lxd-ovn: Reorders comms tests so that external is last
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc-ci/pull/194 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) === Adds OVN to lxdbr0 test before external test, so we can see where intermittent failures are occurring. Signed-off-by: Thomas Parrott From 1b643e93288ed271f59146ea43ab7aa2221fa7c1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Mon, 12 Oct 2020 16:26:41 +0100 Subject: [PATCH] bin/test-lxd-ovn: Reorders comms tests so that external is last Adds OVN to lxdbr0 test before external test, so we can see where intermittent failures are occurring. Signed-off-by: Thomas Parrott --- bin/test-lxd-ovn | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/bin/test-lxd-ovn b/bin/test-lxd-ovn index e8261ea..318dc06 100755 --- a/bin/test-lxd-ovn +++ b/bin/test-lxd-ovn @@ -96,10 +96,6 @@ echo "==> lxdbr0 to OVN gateway" lxc exec u1 -- ping -c1 -4 10.10.10.200 lxc exec u1 -- ping -c1 -6 fd42:4242:4242:1010::200 -echo "==> OVN to internet" -lxc exec u2 -- ping -c1 -4 linuxcontainers.org -lxc exec u2 -- ping -c1 -6 linuxcontainers.org - echo "==> OVN to OVN" lxc exec u2 -- ping -c1 -4 "${U3_IPV4}" lxc exec u2 -- ping -c1 -6 "${U3_IPV6}" @@ -112,6 +108,14 @@ echo "==> DNS resolution on OVN" lxc exec u3 -- ping -c1 -4 u2.lxd lxc exec u3 -- ping -c1 -6 u2.lxd +echo "==> OVN to lxdbr0" +lxc exec u2 -- ping -c1 10.10.10.1 +lxc exec u2 -- ping -c1 fd42:4242:4242:1010::1 + +echo "==> OVN to internet" +lxc exec u2 -- ping -c1 -4 linuxcontainers.org +lxc exec u2 -- ping -c1 -6 linuxcontainers.org + echo "===> Testing project restrictions" lxc project create testovn -c features.networks=true -c restricted=true @@ -168,10 +172,6 @@ echo "==> lxdbr0 to OVN gateway in project testovn" lxc exec u1 --project default -- ping -c1 -4 10.10.10.201 lxc exec u1 --project default -- ping -c1 -6 fd42:4242:4242:1010::201 -echo "==> OVN to internet in project testovn" -lxc exec u2 -- ping -c1 -4 linuxcontainers.org -lxc exec u2 -- ping -c1 -6 linuxcontainers.org - echo "==> OVN to OVN in project testovn" lxc exec u2 -- ping -c1 -4 "${U3_IPV4}" lxc exec u2 -- ping -c1 -6 "${U3_IPV6}" @@ -184,6 +184,14 @@ echo "==> DNS resolution on OVN in project testovn" lxc exec u3 -- ping -c1 -4 u2.lxd lxc exec u3 -- ping -c1 -6 u2.lxd +echo "==> OVN to lxdbr0 in project testovn" +lxc exec u2 -- ping -c1 10.10.10.1 +lxc exec u2 -- ping -c1 fd42:4242:4242:1010::1 + +echo "==> OVN to internet in project testovn" +lxc exec u2 -- ping -c1 -4 linuxcontainers.org +lxc exec u2 -- ping -c1 -6 linuxcontainers.org + echo "===> Check network in use protection from deletion" # Delete instances in default project first. lxc delete -f u1 u2 u3 --project default ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [go-lxc/v2] Fixes crash in cgroupItem()
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/go-lxc/pull/143 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) === When container is shutting down and `lxc ls` is run, it can crash LXD with stack trace: ``` fatal error: unexpected signal during runtime execution [signal SIGSEGV: segmentation violation code=0x1 addr=0x2380 pc=0x7fe173a817d2] runtime stack: runtime.throw(0x159c9bf, 0x2a) /usr/lib/go-1.13/src/runtime/panic.go:774 +0x72 runtime.sigpanic() /usr/lib/go-1.13/src/runtime/signal_unix.go:378 +0x47c goroutine 19614 [syscall]: runtime.cgocall(0x1249fa9, 0xc234a8, 0xc234b8) /usr/lib/go-1.13/src/runtime/cgocall.go:128 +0x5b fp=0xc23478 sp=0xc23440 pc=0x41061b gopkg.in/lxc/go-lxc%2ev2._Cfunc_go_lxc_get_cgroup_item(0x7fe11c005100, 0x7fe140003e30, 0x0) _cgo_gotypes.go:674 +0x4e fp=0xc234a8 sp=0xc23478 pc=0x8bd43e gopkg.in/lxc/go-lxc%2ev2.(*Container).cgroupItem.func2(0xc00032d950, 0x7fe140003e30, 0x7fe140003e30) /home/user/go/src/gopkg.in/lxc/go-lxc.v2/container.go:845 +0x69 fp=0xc234e8 sp=0xc234a8 pc=0x8d0fa9 gopkg.in/lxc/go-lxc%2ev2.(*Container).cgroupItem(0xc00032d950, 0x1578126, 0x19, 0x0, 0x0, 0x0) /home/user/go/src/gopkg.in/lxc/go-lxc.v2/container.go:845 +0xc9 fp=0xc235c0 sp=0xc234e8 pc=0x8c4c59 gopkg.in/lxc/go-lxc%2ev2.(*Container).CgroupItem(0xc00032d950, 0x1578126, 0x19, 0x0, 0x0, 0x0) /home/user/go/src/gopkg.in/lxc/go-lxc.v2/container.go:870 +0xa5 fp=0xc23638 sp=0xc235c0 pc=0x8c4fd5 github.com/lxc/lxd/lxd/instance/drivers.(*lxcCgroupReadWriter).Get(0xc000708850, 0x1, 0x1549c59, 0x6, 0x1578126, 0x19, 0xc00019eb08, 0x9, 0x1, 0x1) /home/user/go/src/github.com/lxc/lxd/lxd/instance/drivers/driver_lxc.go:7061 +0x1d8 fp=0xc23690 sp=0xc23638 pc=0xfa0178 github.com/lxc/lxd/lxd/cgroup.(*CGroup).GetMemoryMaxUsage(0xc0004fa4a0, 0x9, 0xc0004fa4a0, 0x1, 0x3bdf000) /home/user/go/src/github.com/lxc/lxd/lxd/cgroup/abstraction.go:155 +0x10e fp=0xc236f0 sp=0xc23690 pc=0xc4b98e github.com/lxc/lxd/lxd/instance/drivers.(*lxc).memoryState(0xc34dc0, 0x5dcffb4e, 0x7, 0xc0004783c8, 0x1486080) /home/user/go/src/github.com/lxc/lxd/lxd/instance/drivers/driver_lxc.go:5839 +0x2db fp=0xc23760 sp=0xc236f0 pc=0xf975eb github.com/lxc/lxd/lxd/instance/drivers.(*lxc).RenderState(0xc34dc0, 0xc000514140, 0x0, 0x0) /home/user/go/src/github.com/lxc/lxd/lxd/instance/drivers/driver_lxc.go:3230 +0x891 fp=0xc23838 sp=0xc23760 pc=0xf7d151 github.com/lxc/lxd/lxd/instance/drivers.(*lxc).RenderFull(0xc34dc0, 0xc0007247b0, 0xc0004c6e30, 0x2, 0xc00019ee18, 0xc0009650e0) /home/user/go/src/github.com/lxc/lxd/lxd/instance/drivers/driver_lxc.go:3172 +0x167 fp=0xc23c20 sp=0xc23838 pc=0xf7c137 main.doContainersGet.func5(0xc00032a9c0, 0xc0005704c0, 0xc0007247b0, 0xc00069c200, 0xc00069c220, 0xc000670b10) /home/user/go/src/github.com/lxc/lxd/lxd/instances_get.go:268 +0x228 fp=0xc23fb0 sp=0xc23c20 pc=0x121e198 runtime.goexit() /usr/lib/go-1.13/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc23fb8 sp=0xc23fb0 pc=0x46d091 created by main.doContainersGet /home/user/go/src/github.com/lxc/lxd/lxd/instances_get.go:250 +0xc47 goroutine 1 [select, 36 minutes]: main.(*cmdDaemon).Run(0xc0003900c0, 0xc0001982c0, 0xc0001a1a40, 0x0, 0x4, 0x0, 0x0) /home/user/go/src/github.com/lxc/lxd/lxd/main_daemon.go:93 +0x734 github.com/spf13/cobra.(*Command).execute(0xc0001982c0, 0xc32060, 0x4, 0x4, 0xc0001982c0, 0xc32060) /home/user/go/src/github.com/spf13/cobra/command.go:850 +0x460 github.com/spf13/cobra.(*Command).ExecuteC(0xc0001982c0, 0xc00037bf30, 0x1, 0x1) /home/user/go/src/github.com/spf13/cobra/command.go:958 +0x349 github.com/spf13/cobra.(*Command).Execute(...) /home/user/go/src/github.com/spf13/cobra/command.go:895 main.main() /home/user/go/src/github.com/lxc/lxd/lxd/main.go:213 +0xf3b goroutine 76 [select, 36 minutes]: database/sql.(*DB).connectionResetter(0xc00025a300, 0x180b9a0, 0xc83640) /usr/lib/go-1.13/src/database/sql/sql.go:1065 +0xfb created by database/sql.OpenDB /usr/lib/go-1.13/src/database/sql/sql.go:723 +0x193 goroutine 23 [syscall, 36 minutes]: os/signal.signal_recv(0x0) /usr/lib/go-1.13/src/runtime/sigqueue.go:147 +0x9c os/signal.loop() /usr/lib/go-1.13/src/os/signal/signal_unix.go:23 +0x22 created by os/signal.init.0 /usr/lib/go-1.13/src/os/signal/signal_unix.go:29 +0x41 goroutine 19612 [runnable]: syscall.Syscall(0x0, 0x10, 0xc000570060, 0x8, 0x8, 0x8, 0x0) /usr/lib/go-1.13/src/syscall/asm_linux_amd64.s:18 +0x5 syscall.read(0x10, 0xc000570060, 0x8, 0x8, 0x0, 0x17e2c40, 0x2147fb8) /usr/lib/go-1.13/src/syscall/zsyscall_linux_amd64.go:732 +0x5a syscall.Read(...) /usr/lib/go-1.13/src/syscall/syscall_unix.go:183 internal/poll.(*FD).Read(0xcf9180, 0xc000570060, 0x8, 0x8, 0x0, 0x0, 0x0)
[lxc-devel] [lxd/master] VM: Fixes disk resize regression
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8013 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) === - Moves check for preventing update of devices when VM is running into updateDevices(). - Fixes regression introduced by 6697599#diff-8ac4860b5f669c17c92c37545fe2ecfd. - Removes 1 call to IsRunning() by passing into updateDevices() from Update(). From 57f1dc94a63d5faf175b096f280269adcca51786 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 9 Oct 2020 19:39:09 +0100 Subject: [PATCH 1/2] lxd/instance/drivers/driver/qemu: Restores ability to resize VM disks - Moves check for preventing update of devices when VM is running into updateDevices(). - Fixes regression introduced by https://github.com/lxc/lxd/commit/6697599975c1199c226c00b68c7e3e278ea49c66#diff-8ac4860b5f669c17c92c37545fe2ecfd. - Removes 1 call to IsRunning() by passing into updateDevices() from Update(). Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_qemu.go | 44 +++-- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index 0b697cbf58..7c641ef033 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -2836,7 +2836,37 @@ func (vm *qemu) Update(args db.InstanceArgs, userRequested bool) error { } // Diff the devices. - removeDevices, addDevices, updateDevices, allUpdatedKeys := oldExpandedDevices.Update(vm.expandedDevices, nil) + removeDevices, addDevices, updateDevices, allUpdatedKeys := oldExpandedDevices.Update(vm.expandedDevices, func(oldDevice deviceConfig.Device, newDevice deviceConfig.Device) []string { + // This function needs to return a list of fields that are excluded from differences + // between oldDevice and newDevice. The result of this is that as long as the + // devices are otherwise identical except for the fields returned here, then the + // device is considered to be being "updated" rather than "added & removed". + oldNICType, err := nictype.NICType(vm.state, vm.Project(), newDevice) + if err != nil { + return []string{} // Cannot hot-update due to config error. + } + + newNICType, err := nictype.NICType(vm.state, vm.Project(), oldDevice) + if err != nil { + return []string{} // Cannot hot-update due to config error. + } + + if oldDevice["type"] != newDevice["type"] || oldNICType != newNICType { + return []string{} // Device types aren't the same, so this cannot be an update. + } + + d, err := device.New(vm, vm.state, "", newDevice, nil, nil) + if err != nil { + return []string{} // Couldn't create Device, so this cannot be an update. + } + + // TODO modify device framework to differentiate between devices that can only be updated when VM + // is stopped, but don't need to be removed then re-added. For now we rely upon the disk device + // indicating that it supports hot plugging, even for VMs, which it cannot. However this is + // needed so that the disk device's Update() function is called to allow disk resizing. + _, updateFields := d.CanHotPlug() + return updateFields + }) if userRequested { // Do some validation of the config diff. @@ -2854,12 +2884,8 @@ func (vm *qemu) Update(args db.InstanceArgs, userRequested bool) error { isRunning := vm.IsRunning() - if isRunning && len(allUpdatedKeys) > 0 { - return fmt.Errorf("Devices cannot be changed when VM is running") - } - // Use the device interface to apply update changes. - err = vm.updateDevices(removeDevices, addDevices, updateDevices, oldExpandedDevices) + err = vm.updateDevices(removeDevices, addDevices, updateDevices, oldExpandedDevices, isRunning) if err != nil { return err } @@ -3055,8 +3081,10 @@ func (vm *qemu) updateMemoryLimit(newLimit string) error { return fmt.Errorf("Failed setting memory to %d bytes (currently %d bytes) as it was taking too long", newSizeBytes, curSizeBytes) } -func (vm *qemu) updateDevices(removeDevices deviceConfig.Devices, addDevices deviceConfig.Devices, updateDevices deviceConfig.Devices, oldExpandedDevices deviceConfig.Devices) error { - isRunning := vm.IsRunning() +func (vm *qemu) updateDevices(removeDevices deviceConfig.Devices, addDevices deviceConfig.Devices, updateDevices
[lxc-devel] [lxd/master] dnsmasq: Adds 100ms sleep to successful Kill() to allow sockets to be released by OS
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8009 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) === Otherwise trying to immediately start dnsmasq again can result in socket binding errors. Signed-off-by: Thomas Parrott From 23694b750d164369ece64c402f36a76358d2d957 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Fri, 9 Oct 2020 17:19:44 +0100 Subject: [PATCH] lxd/dnsmasq: Adds 100ms sleep to successful Kill() to allow sockets to be released by OS Otherwise trying to immediately start dnsmasq again can result in socket binding errors. Signed-off-by: Thomas Parrott --- lxd/dnsmasq/dnsmasq.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lxd/dnsmasq/dnsmasq.go b/lxd/dnsmasq/dnsmasq.go index 90c222ae66..d8491c2572 100644 --- a/lxd/dnsmasq/dnsmasq.go +++ b/lxd/dnsmasq/dnsmasq.go @@ -8,6 +8,7 @@ import ( "os" "strings" "sync" + "time" "github.com/lxc/lxd/lxd/project" "github.com/lxc/lxd/shared" @@ -95,7 +96,8 @@ func Kill(name string, reload bool) error { return fmt.Errorf("Unable to kill dnsmasq: %s", err) } - // Cleanup + time.Sleep(100 * time.Millisecond) // Give OS time to release sockets. + return nil } ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] Storage: Gives clear error message when trying to create duplicate storage pool in single node
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7994 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) === Previously it errored with: `Error: Pool not defined on nodes: none` As was falling through into cluster storage pool setup mode. Signed-off-by: Thomas Parrott From 2983af787e86c2e8d42d9f55ae0b9d5ae198f55f Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 7 Oct 2020 16:47:24 +0100 Subject: [PATCH] lxd/storage/pools: Gives clear error message when trying to create duplicate storage pool in single node Previously it errored with: `Error: Pool not defined on nodes: none` As was falling through into cluster storage pool setup mode. Signed-off-by: Thomas Parrott --- lxd/storage_pools.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxd/storage_pools.go b/lxd/storage_pools.go index b24443404b..01ce07e034 100644 --- a/lxd/storage_pools.go +++ b/lxd/storage_pools.go @@ -159,6 +159,8 @@ func storagePoolsPost(d *Daemon, r *http.Request) response.Response { } return resp } + + return response.BadRequest(fmt.Errorf("The storage pool already exists")) } // No targetNode was specified and we're clustered, so finalize the ___ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel
[lxc-devel] [lxd/master] network: Adds physical network type and adds OVN support for using it as an uplink
The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7990 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) === - Adds `physical` network type. - Updates `ovn` networks to allow the use of a `physical` network as an uplink network. Includes https://github.com/lxc/lxd/pull/7989 From efffd128341001511c5b3bbeb82af6178c71fd3d Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 6 Oct 2020 16:31:37 +0100 Subject: [PATCH 01/14] shares/validate: Whitespace Signed-off-by: Thomas Parrott --- shared/validate/validate.go | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/validate/validate.go b/shared/validate/validate.go index 356a7d8744..4217ecf89f 100644 --- a/shared/validate/validate.go +++ b/shared/validate/validate.go @@ -226,6 +226,7 @@ func IsNetworkAddressV4List(value string) error { return err } } + return nil } From 896679be6effa830345a836920db173bd3935210 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 6 Oct 2020 16:33:00 +0100 Subject: [PATCH 02/14] lxd/network/openvswitch/ovn: Updates RecursiveDNSServer to be list of IPs Signed-off-by: Thomas Parrott --- lxd/network/openvswitch/ovn.go | 26 ++ 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go index ef181d8706..e0a0d0dc44 100644 --- a/lxd/network/openvswitch/ovn.go +++ b/lxd/network/openvswitch/ovn.go @@ -66,7 +66,7 @@ type OVNDHCPv4Opts struct { ServerID net.IP ServerMAC net.HardwareAddr Router net.IP - RecursiveDNSServer net.IP + RecursiveDNSServer []net.IP DomainName string LeaseTime time.Duration MTUuint32 @@ -75,7 +75,7 @@ type OVNDHCPv4Opts struct { // OVNDHCPv6Opts IPv6 DHCP option set that can be created (and then applied to a switch port by resulting ID). type OVNDHCPv6Opts struct { ServerID net.HardwareAddr - RecursiveDNSServer net.IP + RecursiveDNSServer []net.IP DNSSearchList []string } @@ -358,7 +358,16 @@ func (o *OVN) LogicalSwitchDHCPv4OptionsSet(switchName OVNSwitch, uuid string, s } if opts.RecursiveDNSServer != nil { - args = append(args, fmt.Sprintf("dns_server=%s", opts.RecursiveDNSServer.String())) + nsIPs := make([]string, 0, len(opts.RecursiveDNSServer)) + for _, nsIP := range opts.RecursiveDNSServer { + if nsIP.To4() == nil { + continue // Only include IPv4 addresses. + } + + nsIPs = append(nsIPs, nsIP.String()) + } + + args = append(args, fmt.Sprintf("dns_server={%s}", strings.Join(nsIPs, ","))) } if opts.DomainName != "" { @@ -416,7 +425,16 @@ func (o *OVN) LogicalSwitchDHCPv6OptionsSet(switchName OVNSwitch, uuid string, s } if opts.RecursiveDNSServer != nil { - args = append(args, fmt.Sprintf("dns_server=%s", opts.RecursiveDNSServer.String())) + nsIPs := make([]string, 0, len(opts.RecursiveDNSServer)) + for _, nsIP := range opts.RecursiveDNSServer { + if nsIP.To4() != nil { + continue // Only include IPv6 addresses. + } + + nsIPs = append(nsIPs, nsIP.String()) + } + + args = append(args, fmt.Sprintf("dns_server={%s}", strings.Join(nsIPs, ","))) } _, err = o.nbctl(args...) From c775eceac72df08927c5f6799e9b88244b19ea9f Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 6 Oct 2020 16:35:07 +0100 Subject: [PATCH 03/14] lxd/network/driver/ovn: Updates allocateParentPortIPs to detect the parent network IP address and DNS settings Signed-off-by: Thomas Parrott --- lxd/network/driver_ovn.go | 46 +-- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 99423d4b3c..3080c9da3f 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -44,8 +44,8 @@ type ovnParentVars struct { extSwitchProviderName string // DNS. - dnsIPv6 net.IP - dnsIPv4 net.IP + dnsIPv6 []net.IP + dnsIPv4 []net.IP } // ovnParentPortBridgeVars parent bridge port variables used for start/stop. @@ -391,7 +391,7 @@ func (n *ovn) setupParentPortBridge(parentNet Network, routerMAC net.HardwareAdd // allocateParentPortIPs attempts to find a free IP in the parent network's OVN ranges and then stores it in // ovnVolatileParentIPv4 and