diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java index 17cdee90d04..a5e57f1036f 100644 --- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -446,10 +446,11 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { } @VisibleForTesting - protected static final class NoopDbUpgrade implements DbUpgrade { + protected static final class NoopDbUpgrade implements DbUpgrade, DbUpgradeSystemVmTemplate { private final String upgradedVersion; private final String[] upgradeRange; + private SystemVmTemplateRegistration systemVmTemplateRegistration; private NoopDbUpgrade(final CloudStackVersion fromVersion, final CloudStackVersion toVersion) { @@ -490,5 +491,19 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { return new InputStream[0]; } + private void initSystemVmTemplateRegistration() { + systemVmTemplateRegistration = new SystemVmTemplateRegistration(""); + } + + @Override + public void updateSystemVmTemplates(Connection conn) { + s_logger.debug("Updating System Vm template IDs"); + initSystemVmTemplateRegistration(); + try { + systemVmTemplateRegistration.updateSystemVmTemplates(conn); + } catch (Exception e) { + throw new CloudRuntimeException("Failed to find / register SystemVM template(s)"); + } + } } } diff --git a/packaging/centos8/cloud.spec b/packaging/centos8/cloud.spec index a6b148afbe9..fdaf155ed73 100644 --- a/packaging/centos8/cloud.spec +++ b/packaging/centos8/cloud.spec @@ -392,6 +392,7 @@ install -D tools/whisker/LICENSE ${RPM_BUILD_ROOT}%{_defaultdocdir}/%{name}-inte %posttrans common +unalias cp python_dir=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))") if [ ! -z $python_dir ];then cp -f -r /usr/share/cloudstack-common/python-site/* $python_dir/ diff --git a/plugins/storage/volume/storpool/pom.xml b/plugins/storage/volume/storpool/pom.xml index de257d099a6..0914a4df262 100644 --- a/plugins/storage/volume/storpool/pom.xml +++ b/plugins/storage/volume/storpool/pom.xml @@ -61,6 +61,11 @@ mockito-inline 4.7.0 + + pl.project13.maven + git-commit-id-plugin + 4.9.10 + @@ -75,6 +80,35 @@ + + pl.project13.maven + git-commit-id-plugin + 4.9.10 + + + get-the-git-infos + + revision + + + + + ${project.basedir}/.git + git + false + true + ${project.build.outputDirectory}/git.properties + json + + git.*.email + + + false + false + -dirty + + + diff --git a/test/integration/plugins/storpool/MigrateVolumeToStorPool.py b/test/integration/plugins/storpool/MigrateVolumeToStorPool.py index a7f87d9fa87..5babdca094e 100644 --- a/test/integration/plugins/storpool/MigrateVolumeToStorPool.py +++ b/test/integration/plugins/storpool/MigrateVolumeToStorPool.py @@ -78,10 +78,19 @@ class TestMigrateVolumeToAnotherPool(cloudstackTestCase): @classmethod def setUpCloudStack(cls): - cls.spapi = spapi.Api(host="10.2.23.248", port="81", auth="6549874687", multiCluster=True) + config = cls.getClsConfig() + StorPoolHelper.logger = cls + + zone = config.zones[0] + assert zone is not None + + cls.spapi = spapi.Api(host=zone.spEndpoint, port=zone.spEndpointPort, auth=zone.spAuthToken, multiCluster=True) testClient = super(TestMigrateVolumeToAnotherPool, cls).getClsTestClient() cls.apiclient = testClient.getApiClient() + cls.zone = list_zones(cls.apiclient, name=zone.name)[0] + assert cls.zone is not None + cls._cleanup = [] cls.unsupportedHypervisor = False @@ -93,14 +102,6 @@ class TestMigrateVolumeToAnotherPool(cloudstackTestCase): cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates cls.domain = get_domain(cls.apiclient) - cls.zone = None - zones = list_zones(cls.apiclient) - - for z in zones: - if z.name == cls.getClsConfig().mgtSvr[0].zone: - cls.zone = z - - assert cls.zone is not None td = TestData() cls.testdata = td.testdata diff --git a/test/integration/plugins/storpool/TestStorPoolVolumes.py b/test/integration/plugins/storpool/TestStorPoolVolumes.py index 68e2a705440..640a2f9d2bc 100644 --- a/test/integration/plugins/storpool/TestStorPoolVolumes.py +++ b/test/integration/plugins/storpool/TestStorPoolVolumes.py @@ -77,6 +77,13 @@ class TestStoragePool(cloudstackTestCase): @classmethod def setUpCloudStack(cls): + config = cls.getClsConfig() + StorPoolHelper.logger = cls + + zone = config.zones[0] + assert zone is not None + + cls.spapi = spapi.Api(host=zone.spEndpoint, port=zone.spEndpointPort, auth=zone.spAuthToken, multiCluster=True) testClient = super(TestStoragePool, cls).getClsTestClient() cls._cleanup = [] @@ -94,20 +101,16 @@ class TestStoragePool(cloudstackTestCase): # Get Zone, Domain and templates cls.domain = get_domain(cls.apiclient) - cls.zone = None - zones = list_zones(cls.apiclient) - - for z in zones: - if z.name == cls.getClsConfig().mgtSvr[0].zone: - cls.zone = z - + cls.zone = list_zones(cls.apiclient, name=zone.name)[0] + cls.debug(cls.zone) + cls.debug(list_zones(cls.apiclient, name=zone.name)) assert cls.zone is not None cls.sp_template_1 = "ssd" storpool_primary_storage = { "name" : cls.sp_template_1, "zoneid": cls.zone.id, - "url": "SP_API_HTTP=10.2.23.248:81;SP_AUTH_TOKEN=6549874687;SP_TEMPLATE=%s" % cls.sp_template_1, + "url": "SP_API_HTTP=%s:%s;SP_AUTH_TOKEN=%s;SP_TEMPLATE=%s" % (zone.spEndpoint, zone.spEndpointPort, zone.spAuthToken, cls.sp_template_1), "scope": "zone", "capacitybytes": 564325555333, "capacityiops": 155466, @@ -117,8 +120,6 @@ class TestStoragePool(cloudstackTestCase): } cls.storpool_primary_storage = storpool_primary_storage - host, port, auth = cls.getCfgFromUrl(url = storpool_primary_storage["url"]) - cls.spapi = spapi.Api(host=host, port=port, auth=auth, multiCluster=True) storage_pool = list_storage_pools( cls.apiclient, @@ -166,7 +167,7 @@ class TestStoragePool(cloudstackTestCase): storpool_primary_storage2 = { "name" : cls.sp_template_2, "zoneid": cls.zone.id, - "url": "SP_API_HTTP=10.2.23.248:81;SP_AUTH_TOKEN=6549874687;SP_TEMPLATE=%s" % cls.sp_template_2, + "url": "SP_API_HTTP=%s:%s;SP_AUTH_TOKEN=%s;SP_TEMPLATE=%s" % (zone.spEndpoint, zone.spEndpointPort, zone.spAuthToken, cls.sp_template_2), "scope": "zone", "capacitybytes": 564325555333, "capacityiops": 1554, diff --git a/test/integration/plugins/storpool/TestTagsOnStorPool.py b/test/integration/plugins/storpool/TestTagsOnStorPool.py index 554e905d2f3..6d13e2081d9 100644 --- a/test/integration/plugins/storpool/TestTagsOnStorPool.py +++ b/test/integration/plugins/storpool/TestTagsOnStorPool.py @@ -77,7 +77,13 @@ class TestStoragePool(cloudstackTestCase): @classmethod def setUpCloudStack(cls): - cls.spapi = spapi.Api(host="10.2.23.248", port="81", auth="6549874687", multiCluster=True) + config = cls.getClsConfig() + StorPoolHelper.logger = cls + + zone = config.zones[0] + assert zone is not None + + cls.spapi = spapi.Api(host=zone.spEndpoint, port=zone.spEndpointPort, auth=zone.spAuthToken, multiCluster=True) testClient = super(TestStoragePool, cls).getClsTestClient() cls.apiclient = testClient.getApiClient() cls.unsupportedHypervisor = False @@ -91,12 +97,10 @@ class TestStoragePool(cloudstackTestCase): cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates cls.domain = get_domain(cls.apiclient) - cls.zone = None - zones = list_zones(cls.apiclient) - - for z in zones: - if z.name == cls.getClsConfig().mgtSvr[0].zone: - cls.zone = z + cls.zone = list_zones(cls.apiclient, name=zone.name)[0] + cls.debug(cls.zone) + cls.debug(list_zones(cls.apiclient, name=zone.name)) + assert cls.zone is not None assert cls.zone is not None diff --git a/test/integration/plugins/storpool/TestVmSnapshots.py b/test/integration/plugins/storpool/TestVmSnapshots.py index b1daa93edad..ab35c076b4e 100644 --- a/test/integration/plugins/storpool/TestVmSnapshots.py +++ b/test/integration/plugins/storpool/TestVmSnapshots.py @@ -60,6 +60,12 @@ class TestVmSnapshot(cloudstackTestCase): @classmethod def setUpCloudStack(cls): + config = cls.getClsConfig() + StorPoolHelper.logger = cls + + zone = config.zones[0] + assert zone is not None + testClient = super(TestVmSnapshot, cls).getClsTestClient() cls.apiclient = testClient.getApiClient() cls._cleanup = [] @@ -74,13 +80,9 @@ class TestVmSnapshot(cloudstackTestCase): cls.services = testClient.getParsedTestDataConfig() # Get Zone, Domain and templates cls.domain = get_domain(cls.apiclient) - cls.zone = None - zones = list_zones(cls.apiclient) - - for z in zones: - if z.name == cls.getClsConfig().mgtSvr[0].zone: - cls.zone = z - + cls.zone = list_zones(cls.apiclient, name=zone.name)[0] + cls.debug(cls.zone) + cls.debug(list_zones(cls.apiclient, name=zone.name)) assert cls.zone is not None cls.cluster = list_clusters(cls.apiclient)[0] diff --git a/test/integration/plugins/storpool/sp_util.py b/test/integration/plugins/storpool/sp_util.py index 6517841354a..569aa4a2539 100644 --- a/test/integration/plugins/storpool/sp_util.py +++ b/test/integration/plugins/storpool/sp_util.py @@ -301,6 +301,12 @@ class TestData(): }, } class StorPoolHelper(): + def setUpClass(cls): + cls.logger = None + + @classmethod + def logging(cls): + return cls.logger @classmethod def create_template_from_snapshot(self, apiclient, services, snapshotid=None, volumeid=None): diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 2f6f335de7d..338ef3968ca 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -780,7 +780,6 @@ "label.egressdefaultpolicy": "Default egress policy", "label.elastic": "Elastic", "label.email": "Email", -"label.enabled": "Enabled", "label.enable.autoscale.vmgroup": "Enable AutoScale VM Group", "label.enable.host": "Enable Host", "label.enable.network.offering": "Enable network offering", @@ -2058,6 +2057,7 @@ "label.uk.keyboard": "UK keyboard", "label.unauthorized": "Unauthorized", "label.unavailable": "Unavailable", +"label.undefined": "Undefined", "label.unit": "Usage unit", "label.unknown": "Unknown", "label.unlimited": "Unlimited", diff --git a/ui/src/components/view/DetailSettings.vue b/ui/src/components/view/DetailSettings.vue index 57c5343ab7d..ba96ad6ee8b 100644 --- a/ui/src/components/view/DetailSettings.vue +++ b/ui/src/components/view/DetailSettings.vue @@ -170,7 +170,11 @@ export default { return [] } if (!Array.isArray(this.detailOptions[this.newKey])) { - return { value: this.detailOptions[this.newKey] } + if (this.detailOptions[this.newKey]) { + return { value: this.detailOptions[this.newKey] } + } else { + return '' + } } return this.detailOptions[this.newKey].map(value => { return { value: value } diff --git a/ui/src/views/compute/EditVM.vue b/ui/src/views/compute/EditVM.vue index 4288bc3531b..3601901252b 100644 --- a/ui/src/views/compute/EditVM.vue +++ b/ui/src/views/compute/EditVM.vue @@ -283,6 +283,10 @@ export default { this.$notifyError(error) }).finally(() => { this.groups.loading = false }) }, + decodeUserData (userdata) { + const decodedData = Buffer.from(userdata, 'base64') + return decodedData.toString('utf-8') + }, fetchUserData () { const params = { id: this.resource.id, @@ -290,7 +294,7 @@ export default { } api('listVirtualMachines', params).then(json => { - this.form.userdata = atob(json.listvirtualmachinesresponse.virtualmachine[0].userdata || '') + this.form.userdata = this.decodeUserData(json.listvirtualmachinesresponse.virtualmachine[0].userdata || '') }) }, handleSubmit () { diff --git a/ui/tests/unit/views/AutogenView.spec.js b/ui/tests/unit/views/AutogenView.spec.js index daac26da0d4..d22c9a267ab 100644 --- a/ui/tests/unit/views/AutogenView.spec.js +++ b/ui/tests/unit/views/AutogenView.spec.js @@ -1146,10 +1146,9 @@ describe('Views > AutogenView.vue', () => { ]) expect(wrapper.vm.showAction).toBeTruthy() expect(listUuidOpts).toHaveBeenCalledTimes(4) - expect(listUuidOpts).toHaveBeenCalledWith({ name: 'id', type: 'uuid' }) - expect(listUuidOpts).toHaveBeenCalledWith({ name: 'column1', type: 'list' }) - expect(listUuidOpts).toHaveBeenCalledWith({ name: 'column2', type: 'string' }) - expect(listUuidOpts).toHaveBeenCalledWith({ name: 'account', type: 'string' }) + expect(listUuidOpts).toHaveBeenCalledWith({ name: 'id', type: 'uuid' }, undefined) + expect(listUuidOpts).toHaveBeenCalledWith({ name: 'column1', type: 'list' }, undefined) + expect(listUuidOpts).toHaveBeenCalledWith({ name: 'column2', type: 'string' }, undefined) done() })