From 29ea73c30f6715b77f752ee32bedc3f4da1e8a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bi=C3=A1n=20Tam=C3=A1s=20L=C3=A1szl=C3=B3?= Date: Sat, 2 Oct 2021 15:50:19 +0200 Subject: [PATCH 1/3] Fix GetCapacity reports zero if poolname includes dataset path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fábián Tamás László --- changelogs/unreleased/392-zero-cap-nonroot-ds | 3 +++ pkg/driver/controller.go | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/392-zero-cap-nonroot-ds diff --git a/changelogs/unreleased/392-zero-cap-nonroot-ds b/changelogs/unreleased/392-zero-cap-nonroot-ds new file mode 100644 index 00000000..86c06747 --- /dev/null +++ b/changelogs/unreleased/392-zero-cap-nonroot-ds @@ -0,0 +1,3 @@ +Fixes GetCapacity in pkg/driver/controller.go to report the ZFS pool +capacity even when using a child dataset at the storage class' poolname +attribute. diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index f31454c9..484c1b71 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -873,8 +873,18 @@ func (cs *controller) GetCapacity( } zfsNodesCache := cs.zfsNodeInformer.GetIndexer() + params := req.GetParameters() + poolParam := helpers.GetInsensitiveParameter(¶ms, "poolname") + poolParamPool, _ := func() (string, string) { + poolParamSliced := strings.SplitN(poolParam, "/", 2) + if len(poolParamSliced) == 2 { + return poolParamSliced[0], poolParamSliced[1] + } else { + return poolParamSliced[0], "" + } + }() var availableCapacity int64 for _, nodeName := range nodeNames { @@ -892,7 +902,7 @@ func (cs *controller) GetCapacity( // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1472-storage-capacity-tracking#available-capacity-vs-maximum-volume-size & // https://github.com/container-storage-interface/spec/issues/432 for more details for _, zpool := range zfsNode.Pools { - if zpool.Name != poolParam { + if zpool.Name != poolParamPool { continue } freeCapacity := zpool.Free.Value() From 87b535442c1a2bd0c9ab2a5a8d2beda8f5b8074a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bi=C3=A1n=20Tam=C3=A1s=20L=C3=A1szl=C3=B3?= Date: Mon, 4 Oct 2021 16:30:53 +0200 Subject: [PATCH 2/3] Add comment explaining the treatment of the "poolname" parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fábián Tamás László --- pkg/driver/controller.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 484c1b71..913b0df9 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -877,6 +877,21 @@ func (cs *controller) GetCapacity( params := req.GetParameters() poolParam := helpers.GetInsensitiveParameter(¶ms, "poolname") + + // The "poolname" parameter can either be the name of a ZFS pool + // (e.g. "zpool"), or a path to a child dataset (e.g. "zpool/k8s/localpv"). + // + // We parse the "poolname" parameter so the name of the ZFS pool and the + // path to the dataset is available separately. + // + // The dataset path is not used now. It could be used later to query the + // capacity of the child dataset, which could be smaller than the capacity + // of the whole pool. + // + // This is necessary because capacity calculation currently only works with + // ZFS pool names. This is why it always returns the capacitry of the whole + // pool, even if the child dataset given as the "poolname" parameter has a + // smaller capacity than the whole pool. poolParamPool, _ := func() (string, string) { poolParamSliced := strings.SplitN(poolParam, "/", 2) if len(poolParamSliced) == 2 { From 8ada33cf146616a854318d759105e9be762148a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bi=C3=A1n=20Tam=C3=A1s=20L=C3=A1szl=C3=B3?= Date: Mon, 4 Oct 2021 16:32:35 +0200 Subject: [PATCH 3/3] Rename "poolParamPool" to "poolname" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fábián Tamás László --- pkg/driver/controller.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 913b0df9..af1d2805 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -892,7 +892,7 @@ func (cs *controller) GetCapacity( // ZFS pool names. This is why it always returns the capacitry of the whole // pool, even if the child dataset given as the "poolname" parameter has a // smaller capacity than the whole pool. - poolParamPool, _ := func() (string, string) { + poolname, _ := func() (string, string) { poolParamSliced := strings.SplitN(poolParam, "/", 2) if len(poolParamSliced) == 2 { return poolParamSliced[0], poolParamSliced[1] @@ -917,7 +917,7 @@ func (cs *controller) GetCapacity( // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1472-storage-capacity-tracking#available-capacity-vs-maximum-volume-size & // https://github.com/container-storage-interface/spec/issues/432 for more details for _, zpool := range zfsNode.Pools { - if zpool.Name != poolParamPool { + if zpool.Name != poolname { continue } freeCapacity := zpool.Free.Value()