From 957ce61b3cc601b6425b1b161b5ca0978ceb6d3b Mon Sep 17 00:00:00 2001 From: Dale Smith Date: Thu, 4 Jul 2024 14:20:57 +1200 Subject: [PATCH] Implement boot_volume_size label to override config file. Currently, all clusters inherit the Magnum config file value for disk size. This provides no way for a user to set their own disk size if they have a large number of container images to deploy. This change allows the label 'boot_volume_size' on the cluster to override the config file and permit larger root disks at creation time. Change-Id: I893f3bac3e6f7ea555d48643020bb39feeaa56a6 --- magnum_capi_helm/driver.py | 33 ++++-- magnum_capi_helm/tests/test_driver.py | 162 ++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 7 deletions(-) diff --git a/magnum_capi_helm/driver.py b/magnum_capi_helm/driver.py index 29585ef..0b4b24b 100644 --- a/magnum_capi_helm/driver.py +++ b/magnum_capi_helm/driver.py @@ -893,22 +893,41 @@ class Driver(driver.Driver): # Add boot disk details, if defined in config file. # Helm chart defaults to ephemeral disks, if unset. - if CONF.cinder.default_boot_volume_type: - disk_details = { + boot_volume_type = self._label( + cluster, "boot_volume_type", CONF.cinder.default_boot_volume_type + ) + if boot_volume_type: + disk_type_details = { "controlPlane": { "machineRootVolume": { - "volumeType": CONF.cinder.default_boot_volume_type, - "diskSize": CONF.cinder.default_boot_volume_size or "", + "volumeType": boot_volume_type, } }, "nodeGroupDefaults": { "machineRootVolume": { - "volumeType": CONF.cinder.default_boot_volume_type, - "diskSize": CONF.cinder.default_boot_volume_size or "", + "volumeType": boot_volume_type, } }, } - values = helm.mergeconcat(values, disk_details) + values = helm.mergeconcat(values, disk_type_details) + + boot_volume_size_gb = self._get_label_int( + cluster, "boot_volume_size", CONF.cinder.default_boot_volume_size + ) + if boot_volume_size_gb: + disk_size_details = { + "controlPlane": { + "machineRootVolume": { + "diskSize": boot_volume_size_gb, + } + }, + "nodeGroupDefaults": { + "machineRootVolume": { + "diskSize": boot_volume_size_gb, + } + }, + } + values = helm.mergeconcat(values, disk_size_details) # Sometimes you need to add an extra network # for things like Cinder CSI CephFS Native diff --git a/magnum_capi_helm/tests/test_driver.py b/magnum_capi_helm/tests/test_driver.py index 405c43f..43e3560 100644 --- a/magnum_capi_helm/tests/test_driver.py +++ b/magnum_capi_helm/tests/test_driver.py @@ -2981,3 +2981,165 @@ class ClusterAPIDriverTest(base.DbTestCase): self.assertEqual(ng.get("autoscale"), None) self.assertEqual(ng.get("machineCountMin"), None) self.assertEqual(ng.get("machineCountMax"), None) + + @mock.patch.object( + driver.Driver, + "_storageclass_definitions", + return_value=mock.ANY, + ) + @mock.patch.object(driver.Driver, "_validate_allowed_flavor") + @mock.patch.object(neutron, "get_network", autospec=True) + @mock.patch.object( + driver.Driver, "_ensure_certificate_secrets", autospec=True + ) + @mock.patch.object(driver.Driver, "_create_appcred_secret", autospec=True) + @mock.patch.object(kubernetes.Client, "load", autospec=True) + @mock.patch.object(driver.Driver, "_get_image_details", autospec=True) + @mock.patch.object(helm.Client, "install_or_upgrade", autospec=True) + def test_create_cluster_boot_volume_size_label_valid( + self, + mock_install, + mock_image, + mock_load, + mock_appcred, + mock_certs, + mock_get_net, + mock_validate_allowed_flavor, + mock_storageclasses, + ): + disk_size_configuration_value = 15 + disk_size_label_value = 32 + + CONF.cinder.default_boot_volume_size = disk_size_configuration_value + self.cluster_obj.labels = { + "boot_volume_size": str(disk_size_label_value) + } + + mock_image.return_value = ( + "imageid1", + "1.27.4", + "ubuntu", + ) + mock_client = mock.MagicMock(spec=kubernetes.Client) + mock_load.return_value = mock_client + + self.driver.create_cluster(self.context, self.cluster_obj, 10) + helm_install_values = mock_install.call_args[0][3] + self.assertEqual( + helm_install_values["controlPlane"]["machineRootVolume"][ + "diskSize" + ], + disk_size_label_value, + ) + self.assertEqual( + helm_install_values["nodeGroupDefaults"]["machineRootVolume"][ + "diskSize" + ], + disk_size_label_value, + ) + + @mock.patch.object( + driver.Driver, + "_storageclass_definitions", + return_value=mock.ANY, + ) + @mock.patch.object(driver.Driver, "_validate_allowed_flavor") + @mock.patch.object(neutron, "get_network", autospec=True) + @mock.patch.object( + driver.Driver, "_ensure_certificate_secrets", autospec=True + ) + @mock.patch.object(driver.Driver, "_create_appcred_secret", autospec=True) + @mock.patch.object(kubernetes.Client, "load", autospec=True) + @mock.patch.object(driver.Driver, "_get_image_details", autospec=True) + @mock.patch.object(helm.Client, "install_or_upgrade", autospec=True) + def test_create_cluster_boot_volume_size_label_default( + self, + mock_install, + mock_image, + mock_load, + mock_appcred, + mock_certs, + mock_get_net, + mock_validate_allowed_flavor, + mock_storageclasses, + ): + disk_size_configuration_value = 15 + + CONF.cinder.default_boot_volume_size = disk_size_configuration_value + self.cluster_obj.labels = {} + + mock_image.return_value = ( + "imageid1", + "1.27.4", + "ubuntu", + ) + mock_client = mock.MagicMock(spec=kubernetes.Client) + mock_load.return_value = mock_client + + self.driver.create_cluster(self.context, self.cluster_obj, 10) + helm_install_values = mock_install.call_args[0][3] + self.assertEqual( + helm_install_values["controlPlane"]["machineRootVolume"][ + "diskSize" + ], + disk_size_configuration_value, + ) + self.assertEqual( + helm_install_values["nodeGroupDefaults"]["machineRootVolume"][ + "diskSize" + ], + disk_size_configuration_value, + ) + + @mock.patch.object( + driver.Driver, + "_storageclass_definitions", + return_value=mock.ANY, + ) + @mock.patch.object(driver.Driver, "_validate_allowed_flavor") + @mock.patch.object(neutron, "get_network", autospec=True) + @mock.patch.object( + driver.Driver, "_ensure_certificate_secrets", autospec=True + ) + @mock.patch.object(driver.Driver, "_create_appcred_secret", autospec=True) + @mock.patch.object(kubernetes.Client, "load", autospec=True) + @mock.patch.object(driver.Driver, "_get_image_details", autospec=True) + @mock.patch.object(helm.Client, "install_or_upgrade", autospec=True) + def test_create_cluster_boot_volume_size_label_invalid( + self, + mock_install, + mock_image, + mock_load, + mock_appcred, + mock_certs, + mock_get_net, + mock_validate_allowed_flavor, + mock_storageclasses, + ): + disk_size_configuration_value = 15 + + CONF.cinder.default_boot_volume_size = disk_size_configuration_value + self.cluster_obj.labels = {"boot_volume_size": "NotANumber"} + + mock_image.return_value = ( + "imageid1", + "1.27.4", + "ubuntu", + ) + mock_client = mock.MagicMock(spec=kubernetes.Client) + mock_load.return_value = mock_client + + self.driver.create_cluster(self.context, self.cluster_obj, 10) + helm_install_values = mock_install.call_args[0][3] + self.assertEqual( + helm_install_values["controlPlane"]["machineRootVolume"][ + "diskSize" + ], + disk_size_configuration_value, + ) + self.assertEqual( + helm_install_values["nodeGroupDefaults"]["machineRootVolume"][ + "diskSize" + ], + disk_size_configuration_value, + )