From 12b2e80d82abd90e17d233c34b4f3bf7847a1d6d Mon Sep 17 00:00:00 2001 From: Harikrishna Date: Fri, 11 Jun 2021 20:06:06 +0530 Subject: [PATCH 001/120] vmware: Fix fetching chain_info of the volumes. It is used to assume datastore names are in the form of UUIDs but it can be any name. So fetch chain_info based on the datastore name. (#5097) his PR fixes the problem of not updating the chain info or setting chain info to null after volume migrations. Problem: While fetching the volume chain info, management server assumes datastore name to be a UUID (this is true only for NFS storages added by CloudStack) but datastore name can be with any name. Solution: To fetch the volume chain info, use datastore name instead of UUID. The fix is made in the flow of following API operations migrateVirtualMachine migrateVirtualMachineWithVolume migrateVolume --- .../com/cloud/vm/VirtualMachineManagerImpl.java | 3 +++ .../hypervisor/vmware/resource/VmwareResource.java | 14 ++++++++------ .../java/com/cloud/storage/StorageManagerImpl.java | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index a29c0497bb2e..3f435e95544c 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -2307,6 +2307,9 @@ private void markVolumesInPool(VMInstanceVO vm, StoragePool destPool, Answer[] h VolumeVO volume = _volsDao.findById(result.getId()); volume.setPath(result.getPath()); volume.setPoolId(destPool.getId()); + if (result.getChainInfo() != null) { + volume.setChainInfo(result.getChainInfo()); + } _volsDao.update(volume.getId(), volume); } } diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 870863d12fd6..f8fe2d6ccebd 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -4429,7 +4429,8 @@ private Answer migrateAndAnswer(VirtualMachineMO vmMo, String poolUuid, } else { s_logger.debug("Successfully consolidated disks of VM " + vmMo.getVmName() + "."); } - return createAnswerForCmd(vmMo, poolUuid, cmd, volumeDeviceKey); + DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDs); + return createAnswerForCmd(vmMo, dsMo, cmd, volumeDeviceKey); } else { return new Answer(cmd, false, "failed to changes data store for VM" + vmMo.getVmName()); } @@ -4440,7 +4441,7 @@ private Answer migrateAndAnswer(VirtualMachineMO vmMo, String poolUuid, } } - Answer createAnswerForCmd(VirtualMachineMO vmMo, String poolUuid, Command cmd, Map volumeDeviceKey) throws Exception { + Answer createAnswerForCmd(VirtualMachineMO vmMo, DatastoreMO dsMo, Command cmd, Map volumeDeviceKey) throws Exception { List volumeToList = new ArrayList<>(); VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder(); VirtualDisk[] disks = vmMo.getAllDiskDevice(); @@ -4458,7 +4459,7 @@ Answer createAnswerForCmd(VirtualMachineMO vmMo, String poolUuid, Command cmd, M for (VirtualDisk disk : disks) { VolumeObjectTO newVol = new VolumeObjectTO(); String newPath = vmMo.getVmdkFileBaseName(disk); - VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, poolUuid); + VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, dsMo.getName()); newVol.setId(volumeDeviceKey.get(disk.getKey())); newVol.setPath(newPath); newVol.setChainInfo(_gson.toJson(diskInfo)); @@ -4804,8 +4805,9 @@ protected Answer execute(MigrateWithStorageCommand cmd) { if (volumeDeviceKey.get(volumeId) == disk.getKey()) { VolumeObjectTO newVol = new VolumeObjectTO(); String newPath = vmMo.getVmdkFileBaseName(disk); - String poolName = entry.second().getUuid().replace("-", ""); - VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, poolName); + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(tgtHyperHost, entry.second().getUuid()); + DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDs); + VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, dsMo.getName()); newVol.setId(volumeId); newVol.setPath(newPath); newVol.setChainInfo(_gson.toJson(diskInfo)); @@ -5100,7 +5102,7 @@ private Answer execute(MigrateVolumeCommand cmd) { } } VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder(); - String chainInfo = _gson.toJson(diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumePath, poolTo.getUuid().replace("-", ""))); + String chainInfo = _gson.toJson(diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumePath, targetDsMo.getName())); MigrateVolumeAnswer answer = new MigrateVolumeAnswer(cmd, true, null, volumePath); answer.setVolumeChainInfo(chainInfo); return answer; diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 2e22003b9c1d..a3eb1d4966ce 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -1745,7 +1745,7 @@ public void syncDatastoreClusterStoragePool(long datastoreClusterPoolId, List Date: Fri, 11 Jun 2021 20:07:07 +0530 Subject: [PATCH 002/120] ui: add action syncStoragePool (#5098) Added action in UI for syncStoragePool API for DatastoreCluster type primary storages. Fixes #5086 Signed-off-by: Abhishek Kumar --- ui/public/locales/en.json | 2 ++ ui/src/config/section/infra/primaryStorages.js | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index d13758ba5853..1f835756b6fe 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -2063,6 +2063,7 @@ "label.supportsstrechedl2subnet": "Supports Streched L2 Subnet", "label.suspend.project": "Suspend Project", "label.switch.type": "Switch Type", +"label.sync.storage": "Sync Storage Pool", "label.system.capacity": "System Capacity", "label.system.offering": "System Offering", "label.system.offering.for.router": "System Offering for Router", @@ -2627,6 +2628,7 @@ "message.confirm.start.lb.vm": "Please confirm you want to start LB VM", "message.confirm.stop.kubernetes.cluster": "Please confirm that you want to stop this Kubernetes cluster.", "message.confirm.stop.lb.vm": "Please confirm you want to stop LB VM", +"message.confirm.sync.storage": "Please confirm you want to sync the storage pool", "message.confirm.upgrade.router.newer.template": "Please confirm that you want to upgrade router to use newer template", "message.confirm.upgrade.routers.account.newtemplate": "Please confirm that you want to upgrade all routers in this account to use newer template", "message.confirm.upgrade.routers.cluster.newtemplate": "Please confirm that you want to upgrade all routers in this cluster to use newer template", diff --git a/ui/src/config/section/infra/primaryStorages.js b/ui/src/config/section/infra/primaryStorages.js index 9f78ab95768d..eda571766681 100644 --- a/ui/src/config/section/infra/primaryStorages.js +++ b/ui/src/config/section/infra/primaryStorages.js @@ -81,6 +81,14 @@ export default { defaultArgs: { enabled: true }, show: (record) => { return record.state === 'Disabled' } }, + { + api: 'syncStoragePool', + icon: 'sync', + label: 'label.sync.storage', + message: 'message.confirm.sync.storage', + dataView: true, + show: (record) => { return record.state === 'Up' && record.type === 'DatastoreCluster' } + }, { api: 'enableStorageMaintenance', icon: 'plus-square', From bc12833ccfa20eaa4a3e3379ae279e1bbb306021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Beims=20Br=C3=A4scher?= Date: Mon, 14 Jun 2021 04:19:55 -0300 Subject: [PATCH 003/120] server: Failed to scale between Service Offerings with the same root disk size (#5095) * Cover a case where resizing root disk failed; add isNotPossibleToResize method. * remove format from resize validation * Revert if-conditional changes that removed ImageFormat.ISO validation * Add JUnit tests for VolumeApiServiceImpl.isNotPossibleToResize * Fix checkstyle of test Class * Use _templateDao.findByIdIncludingRemoved instead of _templateDao.findById * Prevent null serviceOfferingView and Mock findByIdIncludingRemoved instead of findById --- .../cloud/storage/VolumeApiServiceImpl.java | 45 ++++++++++----- .../storage/VolumeApiServiceImplTest.java | 56 ++++++++++++++++++- 2 files changed, 86 insertions(+), 15 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 08c473b60b12..ccb91f180edd 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -31,6 +31,8 @@ import javax.inject.Inject; +import com.cloud.api.query.dao.ServiceOfferingJoinDao; +import com.cloud.api.query.vo.ServiceOfferingJoinVO; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; @@ -218,6 +220,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Inject private ServiceOfferingDetailsDao _serviceOfferingDetailsDao; @Inject + private ServiceOfferingJoinDao serviceOfferingJoinDao; + @Inject private UserVmDao _userVmDao; @Inject private UserVmDetailsDao userVmDetailsDao; @@ -920,20 +924,7 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep } // if we are to use the existing disk offering - ImageFormat format = null; if (newDiskOffering == null) { - Long templateId = volume.getTemplateId(); - if (templateId != null) { - VMTemplateVO template = _templateDao.findById(templateId); - format = template.getFormat(); - } - - if (volume.getVolumeType().equals(Volume.Type.ROOT) && diskOffering.getDiskSize() > 0 && format != null && format != ImageFormat.ISO) { - throw new InvalidParameterValueException( - "Failed to resize Root volume. The service offering of this Volume has been configured with a root disk size; " - + "on such case a Root Volume can only be resized when changing to another Service Offering with a Root disk size. " - + "For more details please check out the Official Resizing Volumes documentation."); - } newSize = cmd.getSize(); newHypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve(); @@ -944,6 +935,13 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep + "customizable or it must be a root volume (if providing a disk offering, make sure it is different from the current disk offering)."); } + if (isNotPossibleToResize(volume, diskOffering)) { + throw new InvalidParameterValueException( + "Failed to resize Root volume. The service offering of this Volume has been configured with a root disk size; " + + "on such case a Root Volume can only be resized when changing to another Service Offering with a Root disk size. " + + "For more details please check out the Official Resizing Volumes documentation."); + } + // convert from bytes to GiB newSize = newSize << 30; } else { @@ -1167,6 +1165,27 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep shrinkOk); } + /** + * A volume should not be resized if it covers ALL the following scenarios:
+ * 1 - Root volume
+ * 2 - && Current Disk Offering enforces a root disk size (in this case one can resize only by changing the Service Offering) + */ + protected boolean isNotPossibleToResize(VolumeVO volume, DiskOfferingVO diskOffering) { + Long templateId = volume.getTemplateId(); + ImageFormat format = null; + if (templateId != null) { + VMTemplateVO template = _templateDao.findByIdIncludingRemoved(templateId); + format = template.getFormat(); + } + boolean isNotIso = format != null && format != ImageFormat.ISO; + boolean isRoot = Volume.Type.ROOT.equals(volume.getVolumeType()); + + ServiceOfferingJoinVO serviceOfferingView = serviceOfferingJoinDao.findById(diskOffering.getId()); + boolean isOfferingEnforcingRootDiskSize = serviceOfferingView != null && serviceOfferingView.getRootDiskSize() > 0; + + return isOfferingEnforcingRootDiskSize && isRoot && isNotIso; + } + private void checkIfVolumeIsRootAndVmIsRunning(Long newSize, VolumeVO volume, VMInstanceVO vmInstanceVO) { if (!volume.getSize().equals(newSize) && volume.getVolumeType().equals(Volume.Type.ROOT) && !State.Stopped.equals(vmInstanceVO.getState())) { throw new InvalidParameterValueException(String.format("Cannot resize ROOT volume [%s] when VM is not on Stopped State. VM %s is in state %s", volume.getName(), vmInstanceVO diff --git a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java index 8ec24afe9385..f317ea8acf3b 100644 --- a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java +++ b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java @@ -35,6 +35,9 @@ import java.util.UUID; import java.util.concurrent.ExecutionException; +import com.cloud.api.query.dao.ServiceOfferingJoinDao; +import com.cloud.api.query.vo.ServiceOfferingJoinVO; +import com.cloud.storage.dao.VMTemplateDao; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; @@ -78,7 +81,6 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.org.Grouping; import com.cloud.serializer.GsonHelper; import com.cloud.server.TaggedResourceService; @@ -153,7 +155,9 @@ public class VolumeApiServiceImplTest { @Mock private StoragePoolTagsDao storagePoolTagsDao; @Mock - private HypervisorCapabilitiesDao hypervisorCapabilitiesDao; + private VMTemplateDao templateDao; + @Mock + private ServiceOfferingJoinDao serviceOfferingJoinDao; private DetachVolumeCmd detachCmd = new DetachVolumeCmd(); private Class _detachCmdClass = detachCmd.getClass(); @@ -1079,4 +1083,52 @@ public void doesTargetStorageSupportDiskOfferingTestDiskOfferingTagsEqualsStorag Assert.assertTrue(result); } + + @Test + public void isNotPossibleToResizeTestAllFormats() { + Storage.ImageFormat[] imageFormat = Storage.ImageFormat.values(); + for (int i = 0; i < imageFormat.length - 1; i++) { + if (imageFormat[i] != Storage.ImageFormat.ISO) { + prepareAndRunTestOfIsNotPossibleToResize(Type.ROOT, 10l, imageFormat[i], true); + } else { + prepareAndRunTestOfIsNotPossibleToResize(Type.ROOT, 10l, imageFormat[i], false); + } + } + } + + @Test + public void isNotPossibleToResizeTestAllTypes() { + Type[] types = Type.values(); + for (int i = 0; i < types.length - 1; i++) { + if (types[i] != Type.ROOT) { + prepareAndRunTestOfIsNotPossibleToResize(types[i], 10l, Storage.ImageFormat.QCOW2, false); + } else { + prepareAndRunTestOfIsNotPossibleToResize(types[i], 10l, Storage.ImageFormat.QCOW2, true); + } + } + } + + @Test + public void isNotPossibleToResizeTestNoRootDiskSize() { + prepareAndRunTestOfIsNotPossibleToResize(Type.ROOT, 0l, Storage.ImageFormat.QCOW2, false); + } + + private void prepareAndRunTestOfIsNotPossibleToResize(Type volumeType, Long rootDisk, Storage.ImageFormat imageFormat, boolean expectedIsNotPossibleToResize) { + VolumeVO volume = Mockito.mock(VolumeVO.class); + when(volume.getVolumeType()).thenReturn(volumeType); + + when(volume.getTemplateId()).thenReturn(1l); + DiskOfferingVO diskOffering = Mockito.mock(DiskOfferingVO.class); + + ServiceOfferingJoinVO serviceOfferingJoinVO = Mockito.mock(ServiceOfferingJoinVO.class); + when(serviceOfferingJoinVO.getRootDiskSize()).thenReturn(rootDisk); + when(serviceOfferingJoinDao.findById(Mockito.anyLong())).thenReturn(serviceOfferingJoinVO); + + VMTemplateVO template = Mockito.mock(VMTemplateVO.class); + when(template.getFormat()).thenReturn(imageFormat); + when(templateDao.findByIdIncludingRemoved(Mockito.anyLong())).thenReturn(template); + + boolean result = volumeApiServiceImpl.isNotPossibleToResize(volume, diskOffering); + Assert.assertEquals(expectedIsNotPossibleToResize, result); + } } From b6e4329aa34e5378865612fb6cf27fbda1794e0a Mon Sep 17 00:00:00 2001 From: fermosan <78906279+fermosan@users.noreply.github.com> Date: Tue, 15 Jun 2021 13:01:49 +0300 Subject: [PATCH 004/120] ui: Greek (Hellenic) translation (#5109) Modifications in TranslationMenu.vue as well --- ui/public/locales/el_GR.json | 3332 ++++++++++++++++++ ui/src/components/header/TranslationMenu.vue | 1 + 2 files changed, 3333 insertions(+) create mode 100644 ui/public/locales/el_GR.json diff --git a/ui/public/locales/el_GR.json b/ui/public/locales/el_GR.json new file mode 100644 index 000000000000..07edb492e18c --- /dev/null +++ b/ui/public/locales/el_GR.json @@ -0,0 +1,3332 @@ +{ +"alert.service.domainrouter" : "Δρομολογητής τομέα", +"changed.item.properties" : "Τροποποιημένες ιδιότητες στοιχείου", +"confirm.enable.s3" : "Συμπληρώστε τις ακόλουθες πληροφορίες για να ενεργοποιήσετε την υποστήριξη για δευτερεύοντα χώρο αποθήκευσης με υποστήριξη S3", +"confirm.enable.swift" : "Παρακαλούμε συμπληρώστε τις ακόλουθες πληροφορίες για να ενεργοποιήσετε την υποστήριξη για swift", +"error.could.not.change.your.password.because.non.native.user" : "Το σφάλμα δεν ήταν δυνατό να αλλάξει τον κωδικό πρόσβασής σας, επειδή ο χρήστης δεν είναι εγγενής χρήστης cloudstack.", +"error.could.not.enable.zone" : "Δεν ήταν δυνατή η ενεργοποίηση της ζώνης", +"error.dedicate.cluster.failed" : "Απέτυχε η αποκλειστική διάθεση της συστοιχία (cluster)", +"error.dedicate.host.failed" : "Απέτυχε η αποκλειστική διάθεση του κεντρικού υπολογιστή", +"error.dedicate.pod.failed" : "Απέτυχε η αποκλειστική διάθεση pod", +"error.dedicate.zone.failed" : "Απέτυχε η αποκλειστική διάθεση ζώνης", +"error.execute.api.failed" : "Απέτυχε η εκτέλεση του API", +"error.fetching.async.job.result" : "Παρουσιάστηκε σφάλμα κατά τη λήψη αποτελέσματος ασύγχρονης εργασίας", +"error.form.message" : "Υπάρχουν λάθη στη φόρμα. Παρακαλώ διορθώστε τα.", +"error.installwizard.message" : "Κάτι πήγε στραβά. Μπορείτε να επιστρέψετε και να διορθώσετε τυχόν σφάλματα", +"error.invalid.username.password" : "Το όνομα χρήστη ή ο κωδικός πρόσβασης δεν είναι έγκυρα.

Αυτό μπορεί επίσης να είναι ένας περιορισμός στη διεύθυνση IP από την οποία συνδέεστε.", +"error.login" : "Το όνομα χρήστη/ο κωδικός πρόσβασής σας δεν ταιριάζει με τα αρχεία μας.", +"error.menu.select" : "Δεν είναι δυνατή η εκτέλεση ενέργειας λόγω επιλογής στοιχείων.", +"error.mgmt.server.inaccessible" : "Δεν είναι δυνατή η πρόσβαση στο διακομιστή διαχείρισης. Προσπαθήστε ξανά αργότερα.", +"error.password.not.match" : "Τα πεδία κωδικού πρόσβασης δεν ταιριάζουν", +"error.please.specify.physical.network.tags" : "Οι προσφορές υπηρεσίας δικτύου δεν είναι διαθέσιμες μέχρι να καθορίσετε ετικέτες για αυτό το φυσικό δίκτυο.", +"error.release.dedicate.cluster" : "Απέτυχε η αποδεύσμευση της αποκλειστικής ομοταξίας (cluster)", +"error.release.dedicate.host" : "Απέτυχε η αποδεύσμευση του αποκλειστικού κεντρικού υπολογιστή", +"error.release.dedicate.pod" : "Απέτυχε η αποδεύσμευση της υποομάδας (pod)", +"error.release.dedicate.zone" : "Απέτυχε η αποδέσμευση της αποκλειστικής ζώνης", +"error.session.expired" : "Η περίοδος λειτουργίας σας έχει λήξει.", +"error.unable.to.reach.management.server" : "Δεν είναι δυνατή η πρόσβαση στο διακομιστή διαχείρισης", +"error.unable.to.proceed" : "Δεν είναι δυνατή η συνέχιση. Επικοινωνήστε με το διαχειριστή σας", +"error.unresolved.internet.name" : "Δεν είναι δυνατή η επίλυση του ονόματος Internet.", +"firewall.close" : "Τείχος προστασίας", +"force.delete.domain.warning" : "Προειδοποίηση: Επιλέγοντας την ενέργεια αυτή όλα τα δεδομένα (accounts,resources,child domains) κάτω απο το παρόν θα διαγραφούν", +"force.remove" : "Επιβολή κατάργησης", +"force.remove.host.warning" : "Προειδοποίηση: Επιλέγοντας την ενέργεια αυτή το Cloudstack θα τερματήσει την εκτέλεση όλων των εικονικών μηχανών πριν την κατάργηση του διακομιστή απο την συστοιχία.", +"force.stop" : "Επιβολή διακοπής ", +"force.stop.instance.warning" : "Προειδοποίηση: Η επιλογή του τερμαστισμού δια της βίας της εικονικής μηχανής πρέπει να είναι η τελευταία επιλογή. Μπορεί να οδηγήσει σε απώλεια δεδομένων ή/και σε απρόβλεπτη συμπεριφορά της εικονικής μηχανής ", +"hint.no.host.tags" : "Δεν βρέθηκαν ετικέτες κεντρικού υπολογιστή", +"hint.no.storage.tags" : "Δεν βρέθηκαν ετικέτες αποθήκευσης", +"hint.type.part.host.tag" : "Πληκτρολόγηση σε μέρος ετικέτας κεντρικού υπολογιστή", +"hint.type.part.storage.tag" : "Πληκτρολόγηση σε μέρος ετικέτας χώρου αποθήκευσης", +"icmp.code.desc" : "Καθορίστε -1 εάν θέλετε να επιτρέψετε όλους τους κωδικούς ICMP", +"icmp.type.desc" : "Καθορίστε -1 εάν θέλετε να επιτρέψετε όλους τους τύπους ICMP.", +"image.directory" : "Κατάλογος εικόνων", +"inline" : "Ενσωματωμένη", +"label.about" : "Για", +"label.about.app" : "Πληροφορίες για το CloudStack", +"label.accept" : "Αποδεχθεί", +"label.accept.project.invitation" : "Αποδοχή πρόσκλησης έργου", +"label.access" : "Πρόσβαση", +"label.accesskey" : "Κλειδί πρόσβασης", +"label.account" : "Λογαριασμό", +"label.account.and.security.group" : "Λογαριασμός - Ομάδα ασφαλείας", +"label.account.details" : "Λεπτομέρειες λογαριασμού", +"label.account.id" : "Αναγνωριστικό λογαριασμού", +"label.account.name" : "Όνομα λογαριασμού", +"label.account.specific" : "Συγκεκριμένα χαρακτηριστικά του λογαριασμού", +"label.accounts" : "Λογαριασμούς", +"label.accounttype" : "Τύπος λογαριασμού", +"label.acl.export" : "Εξαγωγή ACL", +"label.acl.id" : "Αναγνωριστικό ACL", +"label.acl.list.rules" : "Κανόνες λίστας ACL", +"label.acl.reason.description" : "Εισαγάγετε την αιτία πίσω από έναν κανόνα ACL.", +"label.acl.replaced" : "Αντικατάσταση ACL", +"label.aclid" : "ACL", +"label.aclname" : "Όνομα ACL", +"label.acltotal" : "Σύνολο ACL δικτύου", +"label.acquire.new.ip" : "Απόκτηση νέας IP", +"label.acquire.new.secondary.ip" : "Απόκτηση νέας δευτερεύουσας ΔΙΕΎΘΥΝΣΗΣ IP", +"label.acquiring.ip" : "Απόκτηση IP", +"label.action" : "Δράση", +"label.action.attach.disk" : "Επισύναψη δίσκου", +"label.action.attach.disk.processing" : "Επισύναψη δίσκου....", +"label.action.attach.iso" : "Επισύναψη ISO", +"label.action.attach.iso.processing" : "Συνδέοντας iso ....", +"label.action.cancel.maintenance.mode" : "Ακύρωση λειτουργίας συντήρησης", +"label.action.cancel.maintenance.mode.processing" : "Ακύρωση λειτουργίας συντήρησης....", +"label.action.change.password" : "Αλλαγή κωδικού πρόσβασης", +"label.action.change.service" : "Αλλαγή υπηρεσίας", +"label.action.change.service.processing" : "Αλλαγή υπηρεσίας....", +"label.action.configure.samlauthorization" : "Ρύθμιση παραμέτρων εξουσιοδότησης SAML SSO", +"label.action.configure.stickiness" : "Stickiness", +"label.action.copy.iso" : "Αντιγραφή ISO", +"label.action.copy.iso.processing" : "Αντιγραφή ISO ....", +"label.action.copy.template" : "Αντιγραφή προτύπου", +"label.action.copy.template.processing" : "Αντιγραφή προτύπου....", +"label.action.create.template.from.vm" : "Δημιουργία προτύπου από vm", +"label.action.create.template.from.volume" : "Δημιουργία προτύπου από τόμο", +"label.action.create.template.processing" : "Δημιουργία προτύπου....", +"label.action.create.snapshot.from.vmsnapshot" : "Δημιουργία στιγμιότυπου από στιγμιότυπο εικονικής μηχανής", +"label.action.create.vm" : "Δημιουργία εικονικής μηχανής", +"label.action.create.vm.processing" : "Δημιουργία VM....", +"label.action.create.volume" : "Δημιουργία τόμου", +"label.action.create.volume.processing" : "Δημιουργία τόμου....", +"label.action.delete.account" : "Διαγραφή λογαριασμού", +"label.action.delete.account.processing" : "Διαγραφή λογαριασμού....", +"label.action.delete.backup.offering" : "Διαγραφή προσφοράς δημιουργίας αντιγράφων ασφαλείας", +"label.action.delete.cluster" : "Διαγραφή ομοταξίας", +"label.action.delete.cluster.processing" : "Διαγραφή ομοταξίας....", +"label.action.delete.disk.offering" : "Διαγραφή προσφοράς υπηρεσίας δίσκου", +"label.action.delete.disk.offering.processing" : "Διαγραφή προσφοράς υπηρεσίας δίσκου....", +"label.action.delete.domain" : "Διαγραφή τομέα", +"label.action.delete.domain.processing" : "Διαγραφή τομέα....", +"label.action.delete.firewall" : "Διαγραφή κανόνα τείχους προστασίας", +"label.action.delete.firewall.processing" : "Διαγραφή τείχους προστασίας....", +"label.action.delete.ingress.rule" : "Διαγραφή κανόνα εισόδου", +"label.action.delete.ingress.rule.processing" : "Διαγραφή κανόνα εισόδου....", +"label.action.delete.ip.range" : "Διαγραφή περιοχής IP", +"label.action.delete.ip.range.processing" : "Διαγραφή περιοχής IP....", +"label.action.delete.iso" : "Διαγραφή ISO", +"label.action.delete.iso.processing" : "Διαγραφή ISO....", +"label.action.delete.load.balancer" : "Διαγραφή κανόνα εξισορρόπησης φόρτου", +"label.action.delete.load.balancer.processing" : "Διαγραφή εξισορρόπησης φόρτου....", +"label.action.delete.network" : "Διαγραφή δικτύου", +"label.action.delete.network.processing" : "Διαγραφή δικτύου....", +"label.action.delete.nexusvswitch" : "Διαγραφή Nexus 1000v", +"label.action.delete.nic" : "Κατάργηση nic", +"label.action.delete.physical.network" : "Διαγραφή φυσικού δικτύου", +"label.action.delete.pod" : "Διαγραφή υποομάδας", +"label.action.delete.pod.processing" : "Η υποομάδα διαγραφεται ....", +"label.action.delete.primary.storage" : "Διαγραφή πρωτεύοντος χώρου αποθήκευσης", +"label.action.delete.primary.storage.processing" : "Διαγραφή πρωτεύοντος χώρου αποθήκευσης....", +"label.action.delete.secondary.storage" : "Διαγραφή δευτερεύοντος χώρου αποθήκευσης", +"label.action.delete.secondary.storage.processing" : "Διαγραφή δευτερεύοντος χώρου αποθήκευσης....", +"label.action.delete.security.group" : "Διαγραφή ομάδας ασφαλείας", +"label.action.delete.security.group.processing" : "Διαγραφή ομάδας ασφαλείας....", +"label.action.delete.service.offering" : "Διαγραφή προσφοράς υπηρεσίας υπηρεσίας", +"label.action.delete.service.offering.processing" : "Διαγραφή προσφοράς υπηρεσίας υπηρεσίας....", +"label.action.delete.snapshot" : "Διαγραφή στιγμιότυπου", +"label.action.delete.snapshot.processing" : "Διαγραφή στιγμιότυπου....", +"label.action.delete.system.service.offering" : "Διαγραφή προσφοράς υπηρεσίας, υπηρεσίας συστήματος", +"label.action.delete.template" : "Διαγραφή προτύπου", +"label.action.delete.template.processing" : "Διαγραφή προτύπου....", +"label.action.delete.user" : "Διαγραφή χρήστη", +"label.action.delete.user.processing" : "Διαγραφή χρήστη....", +"label.action.delete.volume" : "Διαγραφή τόμου", +"label.action.delete.volume.processing" : "Διαγραφή τόμου....", +"label.action.delete.zone" : "Διαγραφή ζώνης", +"label.action.delete.zone.processing" : "Διαγραφή ζώνης....", +"label.action.destroy.instance" : "Καταστροφή εικονική μηχανής", +"label.action.destroy.instance.processing" : "Καταστροφή εικονική μηχανής ....", +"label.action.destroy.systemvm" : "Καταστρέψτε το σύστημα VM", +"label.action.destroy.systemvm.processing" : "Καταστρέφοντας VM συστήματος ....", +"label.action.destroy.volume" : "Καταστροφή τόμου", +"label.action.detach.disk" : "Αποσύνδεση δίσκου", +"label.action.detach.disk.processing" : "Αποσύνδεση δίσκου....", +"label.action.detach.iso" : "Αποσύνδεση ISO", +"label.action.detach.iso.processing" : "Αποσύνδεση iso....", +"label.action.disable.account" : "Απενεργοποίηση λογαριασμού", +"label.action.disable.account.processing" : "Απενεργοποίηση λογαριασμού....", +"label.action.disable.cluster" : "Απενεργοποίηση ομοταξίας", +"label.action.disable.cluster.processing" : "Απενεργοποίηση ομοταξίας....", +"label.action.disable.nexusvswitch" : "Απενεργοποίηση του Nexus 1000v", +"label.action.disable.physical.network" : "Απενεργοποίηση φυσικού δικτύου", +"label.action.disable.pod" : "Απενεργοποίηση υποομάδας", +"label.action.disable.pod.processing" : "Η υποομάδα απενεργοποίείται (Pod) ....", +"label.action.disable.static.nat" : "Απενεργοποίηση στατικού NAT", +"label.action.disable.static.nat.processing" : "Απενεργοποίηση του στατικού NAT....", +"label.action.disable.user" : "Απενεργοποίηση χρήστη", +"label.action.disable.user.processing" : "Απενεργοποίηση χρήστη....", +"label.action.disable.zone" : "Απενεργοποίηση ζώνης", +"label.action.disable.zone.processing" : "Απενεργοποίηση ζώνης....", +"label.action.download.iso" : "Κατεβάστε το ISO", +"label.action.download.template" : "Λήψη προτύπου", +"label.action.download.volume" : "Λήψη τόμου", +"label.action.download.volume.processing" : "Λήψη τόμου....", +"label.action.edit.account" : "Επεξεργασία λογαριασμού", +"label.action.edit.disk.offering" : "Επεξεργασία προσφοράς υπηρεσίας δίσκου", +"label.action.edit.domain" : "Επεξεργασία τομέα", +"label.action.edit.global.setting" : "Επεξεργασία καθολικής ρύθμισης", +"label.action.edit.host" : "Επεξεργασία κεντρικού υπολογιστή", +"label.action.edit.instance" : "Επεξεργασία εικονική μηχανής", +"label.action.edit.iso" : "Επεξεργασία ISO", +"label.action.edit.network" : "Επεξεργασία δικτύου", +"label.action.edit.network.offering" : "Επεξεργασία προσφοράς υπηρεσίας δικτύου", +"label.action.edit.network.processing" : "Επεξεργασία δικτύου....", +"label.action.edit.pod" : "Επεξεργασία pod", +"label.action.edit.primary.storage" : "Επεξεργασία πρωτεύοντος χώρου αποθήκευσης", +"label.action.edit.resource.limits" : "Επεξεργασία ορίων πόρων", +"label.action.edit.service.offering" : "Επεξεργασία προσφοράς υπηρεσίας υπηρεσιών", +"label.action.edit.template" : "Επεξεργασία προτύπου", +"label.action.edit.user" : "Επεξεργασία χρήστη", +"label.action.edit.zone" : "Επεξεργασία ζώνης", +"label.action.enable.account" : "Ενεργοποίηση λογαριασμού", +"label.action.enable.account.processing" : "Ενεργοποίηση λογαριασμού....", +"label.action.enable.cluster" : "Ενεργοποίηση ομοταξίας", +"label.action.enable.cluster.processing" : "Ενεργοποίηση ομοταξίας....", +"label.action.enable.maintenance.mode" : "Ενεργοποίηση λειτουργίας συντήρησης", +"label.action.enable.maintenance.mode.processing" : "Ενεργοποίηση λειτουργίας συντήρησης....", +"label.action.enable.nexusvswitch" : "Ενεργοποίηση nexus 1000v", +"label.action.enable.physical.network" : "Ενεργοποίηση φυσικού δικτύου", +"label.action.enable.pod" : "Ενεργοποίηση pod", +"label.action.enable.pod.processing" : "Ενεργοποίηση Pod ....", +"label.action.enable.static.nat" : "Ενεργοποίηση στατικού NAT", +"label.action.enable.static.nat.processing" : "Ενεργοποίηση στατικού NAT....", +"label.action.enable.user" : "Ενεργοποίηση χρήστη", +"label.action.enable.user.processing" : "Ενεργοποίηση χρήστη....", +"label.action.enable.zone" : "Ενεργοποίηση ζώνης", +"label.action.enable.zone.processing" : "Ενεργοποίηση ζώνης....", +"label.action.expunge.instance" : "διαγραφή εικονική μηχανής", +"label.action.expunge.instance.processing" : "Παράδειγμα διαγραφής....", +"label.action.force.reconnect" : "Επιβολή επανασύνδεσης", +"label.action.force.reconnect.processing" : "Επανασύνδεση....", +"label.action.generate.keys" : "Δημιουργία κλειδιών", +"label.action.generate.keys.processing" : "Δημιουργία κλειδιών....", +"label.action.get.diagnostics" : "Λήψη διαγνωστικών δεδομένων", +"label.action.image.store.read.only" : "Μετατροπή χώρου αποθήκευσης ειδώλων σε κατάσταση μόνο ανάγωνσης read-only", +"label.action.image.store.read.write" : "Μετατροπή χώρου αποθήκευσης ειδώλων σε κατάσταση μόνο ανάγωνσης read-write", +"label.action.iso.permission" : "Ενημέρωση δικαιωμάτων ISO", +"label.action.iso.share" : "Ενημέρωση κοινής χρήσης ISO", +"label.action.list.nexusvswitch" : "Λίστα Nexus 1000v", +"label.action.lock.account" : "Κλείδωμα λογαριασμού", +"label.action.lock.account.processing" : "Κλείδωμα λογαριασμού....", +"label.action.manage.cluster" : "Διαχείριση ομοταξίας", +"label.action.manage.cluster.processing" : "Διαχείριση ομοταξίας....", +"label.action.migrate.instance" : "Μετεγκατάσταση εικονική μηχανής", +"label.action.migrate.instance.processing" : "Μετεγκατάσταση εικονική μηχανής....", +"label.action.migrate.router" : "Μετεγκατάσταση δρομολογητή", +"label.action.migrate.router.processing" : "Μετεγκατάσταση δρομολογητή....", +"label.action.migrate.router.to.ps" : "Μετεγκατάσταση δρομολογητή σε άλλο πρωτεύον αποθηκευτικό χώρο", +"label.action.migrate.systemvm" : "Μετεγκατάσταση εικονικής μηχανής συστήματος", +"label.action.migrate.systemvm.processing" : "Μετεγκατάσταση VM συστήματος....", +"label.action.migrate.systemvm.to.ps" : "Μετεγκατάσταση συστημικής εικονικής μηχανής σε άλλο πρωτεύον αποθηκευτικό χώρο", +"label.action.project.add.account" : "Προσθήκη λογαριασμού στο Project", +"label.action.project.add.user" : "Προσθήκη χρήστη στο Project", +"label.action.reboot.instance" : "Επανεκκίνηση εικονική μηχανής", +"label.action.reboot.instance.processing" : "Επανεκκίνηση εικονική μηχανής....", +"label.action.reboot.router" : "Επανεκκίνηση δρομολογητή", +"label.action.reboot.router.processing" : "Επανεκκίνηση δρομολογητή ....", +"label.action.reboot.systemvm" : "Επανεκκίνηση της εικονικής μηχανής συστήματος", +"label.action.reboot.systemvm.processing" : "Επανεκκίνηση του συστήματος VM ....", +"label.action.recover.volume" : "Ανάκτηση τόμου", +"label.action.recurring.snapshot" : "Επαναλαμβανόμενα στιγμιότυπα", +"label.action.register.iso" : "Καταχώρηση ISO", +"label.action.register.ncc" : "Καταχώρηση NCC", +"label.action.register.template" : "Καταχώρηση προτύπου από τη διεύθυνση URL", +"label.action.release.ip" : "Έκδοση IP", +"label.action.release.ip.processing" : "Αποδεσμεύεται η IP ....", +"label.action.remove.host" : "Κατάργηση κεντρικού υπολογιστή", +"label.action.remove.host.processing" : "Κατάργηση κεντρικού υπολογιστή....", +"label.action.remove.vm" : "Αποδέσμευση VM", +"label.action.reset.password" : "Επαναφορά κωδικού πρόσβασης", +"label.action.reset.password.processing" : "Επαναφορά κωδικού πρόσβασης....", +"label.action.resize.volume" : "Αλλαγή μεγέθους τόμου", +"label.action.resize.volume.processing" : "Αλλαγή μεγέθους τόμου....", +"label.action.resource.limits" : "Όρια πόρων", +"label.action.restore.instance" : "Επαναφορά εικονική μηχανής", +"label.action.restore.instance.processing" : "Επαναφορά εικονική μηχανής....", +"label.action.revert.snapshot" : "Επαναφορά στο στιγμιότυπο", +"label.action.revert.snapshot.processing" : "Επαναφορά στο στιγμιότυπο...", +"label.action.router.health.checks" : "Λήψη αποτελεσμάτων υγειονομικών ελέγχων", +"label.action.run.diagnostics" : "Εκτέλεση διαγνωστικών", +"label.action.secure.host" : "Παροχή κλειδιών ασφαλείας κεντρικού υπολογιστή", +"label.action.start.instance" : "Έναρξη εικονική μηχανής", +"label.action.start.instance.processing" : "Έναρξη εικονική μηχανής....", +"label.action.start.router" : "Εκκίνηση δρομολογητή", +"label.action.start.router.processing" : "Εκκίνηση δρομολογητή....", +"label.action.start.systemvm" : "Έναρξη εικονικής μηχανής συστήματος", +"label.action.start.systemvm.processing" : "Εκκίνηση του συστήματος VM ....", +"label.action.stop.instance" : "Διακοπή εικονική μηχανής", +"label.action.stop.instance.processing" : "Διακοπή εικονική μηχανής....", +"label.action.stop.router" : "Διακοπή δρομολογητή", +"label.action.stop.router.processing" : "Διακοπή δρομολογητή....", +"label.action.stop.systemvm" : "Διακοπή της εικονικής μηχανής συστήματος", +"label.action.stop.systemvm.processing" : "Διακοπή του συστήματος VM ....", +"label.action.take.snapshot" : "Λήψη στιγμιότυπου", +"label.action.take.snapshot.processing" : "Λήψη στιγμιότυπου....", +"label.action.template.permission" : "Ενημέρωση δικαιωμάτων προτύπου", +"label.action.template.share" : "Ενημέρωση κοινής χρήσης προτύπων", +"label.action.unmanage.cluster" : "Μη διαχείριση ομοταξίας", +"label.action.unmanage.cluster.processing" : "Μη διαχείριση ομοταξίας ....", +"label.action.unmanage.virtualmachine" : "Μη διαχείριση VM", +"label.action.update.offering.access" : "Ενημέρωση που προσφέρει πρόσβαση", +"label.action.update.os.preference" : "Ενημέρωση προτίμησης λειτουργικού συστήματος", +"label.action.update.os.preference.processing" : "Ενημέρωση προτίμησης λειτουργικού συστήματος....", +"label.action.update.resource.count" : "Ενημέρωση πλήθους πόρων", +"label.action.update.resource.count.processing" : "Ενημέρωση πλήθους πόρων....", +"label.action.vmsnapshot.create" : "Λήψη στιγμιότυπου VM", +"label.action.vmsnapshot.delete" : "Διαγραφή στιγμιότυπου VM", +"label.action.vmsnapshot.revert" : "Επαναφορά στο στιγμιότυπο VM", +"label.action.vmstoragesnapshot.create" : "Λήψη στιγμιότυπου τόμου VM", +"label.actions" : "Ενέργειες", +"label.activate.project" : "Ενεργοποίηση έργου", +"label.activeviewersessions" : "Ενεργές περίοδοι λειτουργίας", +"label.add" : "Προσθέσετε", +"label.add.account" : "Προσθήκη λογαριασμού", +"label.add.accounts" : "Προσθήκη λογαριασμών", +"label.add.accounts.to" : "Προσθήκη λογαριασμών σε", +"label.add.acl" : "Προσθήκη ACL", +"label.add.acl.list" : "Προσθήκη λίστας ACL", +"label.add.affinity.group" : "Προσθήκη νέας ομάδας συνάφειας", +"label.add.baremetal.dhcp.device" : "Προσθήκη συσκευής DHCP baremetal", +"label.add.baremetal.rack.configuration" : "Προσθήκη ρύθμισης παραμέτρων rack baremetal", +"label.add.bigswitchbcf.device" : "Προσθήκη ελεγκτή BCF BigSwitch", +"label.add.brocadevcs.device" : "Προσθήκη εναλλάκτη Brocade Vcs", +"label.add.by" : "Προσθήκη κατά", +"label.add.by.cidr" : "Προσθήκη κατά CIDR", +"label.add.by.group" : "Προσθήκη κατά ομάδα", +"label.add.certificate" : "Προσθήκη πιστοποιητικού", +"label.add.ciscoasa1000v" : "Προσθήκη πόρου CiscoASA1000v", +"label.add.cluster" : "Προσθήκη ομοταξίας", +"label.add.compute.offering" : "Προσθήκη προσφοράς υπηρεσίας υπολογισμού", +"label.add.direct.iprange" : "Προσθήκη περιοχής άμεσης ip", +"label.add.disk.offering" : "Προσθήκη προσφοράς υπηρεσίας δίσκου", +"label.add.domain" : "Προσθήκη τομέα", +"label.add.egress.rule" : "Προσθήκη κανόνα εξόδου", +"label.add.f5.device" : "Προσθήκη συσκευής F5", +"label.add.firewall" : "Προσθήκη κανόνα τείχους προστασίας", +"label.add.globo.dns" : "Προσθήκη GloboDNS", +"label.add.gslb" : "Προσθήκη GSLB", +"label.add.guest.network" : "Προσθήκη δικτύου επισκεπτών", +"label.add.host" : "Προσθήκη κεντρικού υπολογιστή", +"label.add.ingress.rule" : "Προσθήκη κανόνα εισόδου", +"label.add.intermediate.certificate" : "Προσθήκη ενδιάμεσου πιστοποιητικού", +"label.add.internal.lb" : "Προσθήκη εσωτερικού LB", +"label.add.ip.range" : "Προσθήκη περιοχής IP", +"label.add.isolated.guest.network" : "Προσθήκη απομονωμένου δικτύου επισκεπτών", +"label.add.isolated.guest.network.with.sourcenat" : "Προσθήκη απομονωμένου δικτύου επισκεπτών με SourceNat", +"label.add.isolated.network" : "Προσθήκη απομονωμένου δικτύου", +"label.add.kubernetes.cluster" : "Προσθήκη ομοταξίας Kubernetes", +"label.add.l2.guest.network" : "Προσθήκη δικτύου επισκεπτών L2", +"label.add.ldap.account" : "Προσθήκη λογαριασμού LDAP", +"label.add.ldap.list.users" : "Λίστα χρηστών LDAP", +"label.add.list.name" : "Όνομα λίστας ACL", +"label.add.load.balancer" : "Προσθήκη εξισορρόπησης φόρτου", +"label.add.management.ip.range" : "Προσθήκη περιοχής IP διαχείρισης", +"label.add.more" : "Προσθήκη περισσότερων", +"label.add.netscaler.device" : "Προσθήκη συσκευής Netsccaler", +"label.add.network" : "Προσθήκη δικτύου", +"label.add.network.acl" : "Προσθήκη ACL δικτύου", +"label.add.network.acl.list" : "Προσθήκη λίστας ACL δικτύου", +"label.add.network.device" : "Προσθήκη συσκευής δικτύου", +"label.add.network.offering" : "Προσθήκη προσφοράς υπηρεσίας δικτύου", +"label.add.new.f5" : "Προσθήκη νέου F5", +"label.add.new.gateway" : "Προσθήκη νέας πύλης", +"label.add.new.iso" : "Προσθήκη νέου ISO", +"label.add.new.netscaler" : "Προσθήκη νέου netsccaler", +"label.add.new.pa" : "Προσθήκη νέου Palo Alto", +"label.add.new.srx" : "Προσθήκη νέου SRX", +"label.add.new.tier" : "Προσθήκη νέας βαθμίδας", +"label.add.nfs.secondary.staging.store" : "Προσθήκη δευτερεύοντος χώρου αποθήκευσης ανασυγκρότησης NFS", +"label.add.niciranvp.device" : "Προσθήκη ελεγκτή Nvp", +"label.add.note" : "Προσθήκη σημείωσης", +"label.add.opendaylight.device" : "Προσθήκη ελεγκτή opendaylight", +"label.add.pa.device" : "Προσθήκη συσκευής Palo Alto", +"label.add.physical.network" : "Προσθήκη φυσικού δικτύου", +"label.add.pod" : "Προσθήκη pod", +"label.add.port.forwarding.rule" : "Προσθήκη κανόνα προώθησης θυρών", +"label.add.portable.ip.range" : "Προσθήκη φορητής περιοχής IP", +"label.add.primary.storage" : "Προσθήκη πρωτεύοντος χώρου αποθήκευσης", +"label.add.private.gateway" : "Προσθήκη ιδιωτικής πύλης", +"label.add.project.role" : "Προσθήκη ρόλου έργου", +"label.add.region" : "Προσθήκη περιοχής", +"label.add.resources" : "Προσθήκη πόρων", +"label.add.role" : "Προσθήκη ρόλου", +"label.add.route" : "Προσθήκη διαδρομής", +"label.add.rule" : "Προσθήκη κανόνα", +"label.add.rule.desc" : "Δημιουργία νέου κανόνα ACL", +"label.add.secondary.ip" : "Προσθήκη δευτερεύουσας διεύθυνσης IP", +"label.add.secondary.storage" : "Προσθήκη δευτερεύοντος χώρου αποθήκευσης", +"label.add.security.group" : "Προσθήκη ομάδας ασφαλείας", +"label.add.service.offering" : "Προσθήκη προσφοράς υπηρεσίας υπηρεσιών", +"label.add.setting" : "Προσθήκη ρύθμισης", +"label.add.srx.device" : "Προσθήκη συσκευής SRX", +"label.add.static.nat.rule" : "Προσθήκη στατικού κανόνα NAT", +"label.add.static.route" : "Προσθήκη στατικής διαδρομής", +"label.add.system.service.offering" : "Προσθήκη προσφοράς υπηρεσίας υπηρεσιών συστήματος", +"label.add.template" : "Προσθήκη προτύπου", +"label.add.to.group" : "Προσθήκη στην ομάδα", +"label.add.traffic" : "Προσθήκη κίνησης", +"label.add.traffic.type" : "Προσθήκη τύπου κίνησης", +"label.add.ucs.manager" : "Προσθήκη διαχειριστή UCS", +"label.add.user" : "Προσθήκη χρήστη", +"label.add.vlan" : "Προσθήκη VLAN", +"label.add.vm" : "Προσθήκη εικονικής μηχανής", +"label.add.vm.to.tier" : "Προσθήκη εικονικής μηχανής στη βαθμίδα", +"label.add.vms" : "Προσθήκη VM", +"label.add.vms.to.lb" : "Προσθήκη vm(s) σε κανόνα εξισορρόπησης φόρτου", +"label.add.vmware.datacenter" : "Προσθήκη κέντρου δεδομένων VMware", +"label.add.vnmc.device" : "Προσθήκη συσκευής VNMC", +"label.add.vnmc.provider" : "Προσθήκη υπηρεσίας παροχής VNMC", +"label.add.volume" : "Προσθήκη τόμου", +"label.add.vpc" : "Προσθήκη VPC", +"label.add.vpc.offering" : "Προσθήκη προσφοράς υπηρεσίας VPC", +"label.add.vpn.customer.gateway" : "Προσθήκη πύλης πελατών VPN", +"label.add.vpn.gateway" : "Προσθήκη πύλης VPN", +"label.add.vpn.user" : "Προσθήκη χρήστη VPN", +"label.add.vxlan" : "Προσθήκη VXLAN", +"label.add.zone" : "Προσθήκη ζώνης", +"label.addanothernetwork" : "Προσθήκη άλλου δικτύου", +"label.added.brocade.vcs.switch" : "Προστέθηκε νέος εναλλάκτης Μπροκάρ Vcs", +"label.added.network.offering" : "Προστέθηκε προσφορά δικτύου", +"label.added.new.bigswitch.bcf.controller" : "Προστέθηκε νέος ελεγκτής BigSwitch BCF", +"label.added.nicira.nvp.controller" : "Προστέθηκε νέος ελεγκτής NVP Nicira", +"label.addes.new.f5" : "Προστέθηκε νέο F5", +"label.adding" : "Προσθήκη", +"label.adding.cluster" : "Προσθήκη ομοταξίας", +"label.adding.failed" : "Η προσθήκη απέτυχε", +"label.adding.pod" : "Προσθήκη pod", +"label.adding.processing" : "Προσθήκη....", +"label.adding.succeeded" : "Η προσθήκη ολοκληρώθηκε με επιτυχία", +"label.adding.user" : "Προσθήκη χρήστη", +"label.adding.zone" : "Προσθήκη ζώνης", +"label.additional.networks" : "Πρόσθετα δίκτυα", +"label.addnewnetworks" : "Προσθήκη νέων δικτύων", +"label.address" : "Διεύθυνση", +"label.admin" : "Διαχειριστής τομέα", +"label.admin.accounts" : "Λογαριασμοί διαχειριστή", +"label.advanced" : "Προηγμένη", +"label.advanced.mode" : "Λειτουργία για προχωρημένους", +"label.advanced.search" : "Σύνθετη αναζήτηση", +"label.affinity" : "Συγγένεια", +"label.affinity.groups" : "Ομάδες συγγένειας", +"label.affinitygroup" : "Ομάδα συνάφειας", +"label.agent.password" : "Κωδικός πρόσβασης agent", +"label.agent.username" : "Όνομα χρήστη agent", +"label.agentport" : "Θύρα agent", +"label.agentstate" : "Κατάσταση agent", +"label.agree" : "Συμφωνούν", +"label.alert" : "Ειδοποίηση", +"label.alert.archived" : "Αρχειοθετηθεί ειδοποίηση", +"label.alert.deleted" : "Η ειδοποίηση διαγράφηκε", +"label.alert.details" : "Λεπτομέρειες ειδοποίησης", +"label.alerts" : "Ειδοποιήσεις", +"label.algorithm" : "Αλγόριθμο", +"label.all" : "Όλα", +"label.all.zone" : "Όλες οι ζώνες", +"label.allocated" : "Εκχωρηθεί", +"label.allocatediops" : "Εκχωρήθηκε IOPS", +"label.allocationstate" : "Κράτος κατανομής", +"label.allow" : "Επιτρέψει", +"label.allowuserdrivenbackups" : "Να επιτρέπονται αντίγραφα ασφαλείας που οδηγούνται από το χρήστη", +"label.annotated.by" : "Σχολιαστής", +"label.annotation" : "Σχολιασμός", +"label.anti.affinity" : "εκτος συνάφειας", +"label.anti.affinity.group" : "Ομάδα εκτος συνάφειας", +"label.anti.affinity.groups" : "Ομάδες εκτος συνάφειας", +"label.api.version" : "Έκδοση API", +"label.apikey" : "Κλειδί API", +"label.app.cookie" : "AppCookie", +"label.app.name" : "CloudStack", +"label.apply" : "Εφαρμόσετε", +"label.archive" : "Αρχείο", +"label.archive.alerts" : "Αρχειοθέτηση ειδοποιήσεων", +"label.archive.events" : "Αρχειοθέτηση συμβάντων", +"label.as.default" : "ως προεπιλογή", +"label.assign" : "Αντιστοιχίσετε", +"label.assign.instance.another" : "Αντιστοίχιση εικονική μηχανής σε άλλο λογαριασμό", +"label.assign.to.load.balancer" : "Αντιστοίχιση εικονική μηχανής στην εξισορρόπηση φόρτου", +"label.assign.vms" : "Αντιστοίχιση VM", +"label.assigning.vms" : "Αντιστοίχιση VM", +"label.associatednetwork" : "Συσχετισμένο δίκτυο", +"label.associatednetworkid" : "Συσχετισμένο αναγνωριστικό δικτύου", +"label.associatednetworkname" : "Όνομα δικτύου", +"label.asyncbackup" : "Ασύγχρονη δημιουργία αντιγράφων ασφαλείας", +"label.author.email" : "Συντάκτης ηλεκτρονικού ταχυδρομείου", +"label.author.name" : "Όνομα συντάκτη", +"label.autoscale" : "Αυτόματη κλίμακα", +"label.autoscale.configuration.wizard" : "Οδηγός ρύθμισης παραμέτρων αυτόματης κλίμακας", +"label.availability" : "Διαθεσιμότητα", +"label.availabilityzone" : "Ζώνη Διαθεσιμότητας", +"label.available" : "Διαθέσιμα", +"label.available.public.ips" : "Διαθέσιμες δημόσιες διευθύνσεις IP", +"label.back" : "Bck", +"label.backup" : "Αντίγραφα ασφαλείας", +"label.backup.attach.restore" : "Επαναφορά και επισύναψη τόμου αντιγράφου ασφαλείας", +"label.backup.offering.assign" : "Αντιστοίχιση εικονικής μηχανής σε προσφορά δημιουργίας αντιγράφων ασφαλείας", +"label.backup.offering.remove" : "Κατάργηση εικονικής μηχανής από την προσφορά δημιουργίας αντιγράφων ασφαλείας", +"label.backup.offerings" : "προσφορές υπηρεσίας δημιουργίας αντιγράφων ασφαλείας", +"label.backup.restore" : "Επαναφορά αντιγράφου ασφαλείας VM", +"label.backupofferingid" : "Προσφορά δημιουργίας αντιγράφων ασφαλείας", +"label.backupofferingname" : "Προσφορά δημιουργίας αντιγράφων ασφαλείας", +"label.balance" : "Ισορροπία", +"label.bandwidth" : "Εύρος ζώνης", +"label.baremetal.dhcp.devices" : "Συσκευές DHCP baremetal", +"label.baremetal.dhcp.provider" : "Υπηρεσία παροχής DHCP baremetal", +"label.baremetal.pxe.device" : "Προσθήκη συσκευής Baremetal PXE", +"label.baremetal.pxe.devices" : "Συσκευές Baremetal PXE", +"label.baremetal.pxe.provider" : "Υπηρεσία παροχής Baremetal PXE", +"label.baremetal.rack.configuration" : "Ρύθμιση παραμέτρων rack baremetal", +"label.baremetalcpu" : "CPU (σε MHz)", +"label.baremetalcpucores" : "# των πυρήνων cpu", +"label.baremetalmac" : "Κεντρικός υπολογιστής MAC", +"label.baremetalmemory" : "Μνήμη (σε MB)", +"label.based.on" : "Με βάση", +"label.based.on.role.id.or.type" : "Δημιουργεί έναν ρόλο με βάση το role id ή το type", +"label.basic" : "Βασικές", +"label.basic.mode" : "Βασική λειτουργία", +"label.basicsetup" : "Βασική ρύθμιση", +"label.bcfdeviceid" : "Αναγνωριστικό", +"label.bigswitch.bcf.details" : "Λεπτομέρειες για το BigSwitch BCF", +"label.bigswitch.controller.address" : "Διεύθυνση ελεγκτή BigSwitch BCF", +"label.bladeid" : "Αναγνωριστικό Blade", +"label.blades" : "Blades", +"label.bootable" : "Bootable", +"label.bootintosetup" : "Εκκίνηση στην εγκατάσταση υλικού", +"label.bootmode" : "Λειτουργία εκκίνησης", +"label.boottype" : "Τύπος εκκίνησης", +"label.broadcastdomainrange" : "Περιοχή τομέα μετάδοσης", +"label.broadcastdomaintype" : "Τύπος τομέα μετάδοσης", +"label.broadcasturi" : "URI μετάδοσης", +"label.brocade.vcs.address" : "Διεύθυνση εναλλαγής Vcs", +"label.brocade.vcs.details" : "Brocade Vcs εναλλάκτη λεπτομέρειες", +"label.bucket" : "Κουβά", +"label.by.account" : "Ανά λογαριασμό", +"label.by.alert.type" : "Κατά τύπο ειδοποίησης", +"label.by.availability" : "Κατά διαθεσιμότητα", +"label.by.domain" : "Κατά τομέα", +"label.by.end.date" : "Κατά ημερομηνία λήξης", +"label.by.event.type" : "Κατά τύπο συμβάντος", +"label.by.level" : "Κατά επίπεδο", +"label.by.pod" : "Με Pod", +"label.by.role" : "Κατά ρόλο", +"label.by.start.date" : "Κατά ημερομηνία έναρξης", +"label.by.state" : "Ανά κράτος", +"label.by.traffic.type" : "Κατά τύπο κίνησης", +"label.by.type" : "Κατά τύπο", +"label.by.type.id" : "Κατά αναγνωριστικό τύπου", +"label.by.zone" : "Ανά ζώνη", +"label.bypassvlanoverlapcheck" : "Παράκαμψη επικάλυψης ταυτότητας/περιοχής VLAN", +"label.cachemode" : "Τύπος cache εγγραφής", +"label.cancel" : "Ακυρώσετε", +"label.capacity" : "Ικανότητα", +"label.capacity.iops" : "IOPS χωρητικότητας", +"label.capacitybytes" : "Byte χωρητικότητας", +"label.capacityiops" : "Σύνολο IOPS", +"label.category" : "Κατηγορία", +"label.certchain" : "Αλυσίδα", +"label.certificate" : "Πιστοποιητικό", +"label.certificate.details" : "Λεπτομέρειες πιστοποιητικού", +"label.certificate.upload" : "Το πιστοποιητικό που φορτώθηκε", +"label.certificate.upload.failed" : "Η αποστολή πιστοποιητικού απέτυχε", +"label.certificate.upload.failed.description" : "Απέτυχε η ενημέρωση του πιστοποιητικού SSL. Απέτυχε η επιτυχία του ελέγχου επικύρωσης πιστοποιητικού", +"label.certificateid" : "Αναγνωριστικό πιστοποιητικού", +"label.change.affinity" : "Αλλαγή συνάφειας", +"label.change.ip.addess" : "Αλλαγή διεύθυνσης IP", +"label.change.ipaddress" : "Αλλαγή διεύθυνσης IP για nic", +"label.change.service.offering" : "Αλλαγή προσφοράς υπηρεσίας υπηρεσιών", +"label.change.value" : "Αλλαγή τιμής", +"label.character" : "Χαρακτήρα", +"label.chassis" : "Πλαίσιο", +"label.checksum" : "Άθροισμα ελέγχου", +"label.choose.saml.indentity" : "Επιλογή υπηρεσίας παροχής ταυτότητας SAML", +"label.cidr" : "Cidr", +"label.cidr.account" : "CIDR ή ομάδα λογαριασμού/ασφάλειας", +"label.cidr.destination.network" : "Δίκτυο προορισμού CIDR", +"label.cidr.of.destination.network" : "CIDR του δικτύου προορισμού", +"label.cidrlist" : "Κατάλογος CIDR", +"label.cisco.nexus1000v.ip.address" : "Διεύθυνση IP Nexus 1000v", +"label.cisco.nexus1000v.password" : "Nexus 1000v Κωδικός πρόσβασης", +"label.cisco.nexus1000v.username" : "Όνομα χρήστη Nexus 1000v", +"label.ciscovnmc.resource.details" : "Λεπτομέρειες πόρων CiscoVNMC", +"label.cks.cluster.size" : "Μέγεθος ομοταξίας (κόμβοι εργασίας)", +"label.cleanup" : "Καθαρισμός", +"label.clear" : "Σαφές", +"label.clear.list" : "Απαλοιφή λίστας", +"label.close" : "Κλείσιμο", +"label.cloud.console" : "Κονσόλα διαχείρισης cloud", +"label.cloud.managed" : "Διαχείριση Cloud.com", +"label.cloudian.storage" : "Χωρος Αποθήκευσης cloudian", +"label.cluster" : "ομοταξίας", +"label.cluster.name" : "Όνομα ομοταξίας", +"label.cluster.size" : "Μέγεθος ομοταξίας", +"label.clusterid" : "ομοταξίας", +"label.clustername" : "Όνομα ομοταξίας", +"label.clusternamelabel" : "Όνομα ομοταξίας", +"label.clusters" : "Συμπλέγματα", +"label.clustertype" : "Τύπος ομοταξίας", +"label.clvm" : "CLVM", +"label.code" : "Κωδικός", +"label.comma.separated.list.description" : "Εισαγωγή λίστας εντολών διαχωρισμένων με κόμματα", +"label.comments" : "Σχόλια", +"label.community" : "Κοινότητα", +"label.complete" : "Ολοκληρωθεί", +"label.compute" : "Υπολογίσετε", +"label.compute.and.storage" : "Υπολογισμός και αποθήκευση", +"label.compute.offering.access" : "Υπολογισμός πρόσβασης προσφοράς υπηρεσίας", +"label.compute.offerings" : "Υπολογισμός προσφορών", +"label.configuration" : "Ρύθμισης παραμέτρων", +"label.configure" : "Ρυθμίσετε", +"label.configure.ldap" : "Ρύθμιση παραμέτρων LDAP", +"label.configure.network.acls" : "Ρύθμιση παραμέτρων ACL δικτύου", +"label.configure.ovs" : "Ρύθμιση παραμέτρων ovs", +"label.configure.sticky.policy" : "Ρύθμιση παραμέτρων πολιτικής sticky", +"label.configure.vpc" : "Ρύθμιση παραμέτρων VPC", +"label.confirmacceptinvitation" : "Επιβεβαιώστε ότι επιθυμείτε να συμμετάσχετε σε αυτό το έργο", +"label.confirmation" : "Επιβεβαίωση", +"label.confirmdeclineinvitation" : "Είστε βέβαιοι ότι θέλετε να απορρίψετε αυτήν την πρόσκληση έργου;", +"label.confirmpassword" : "Επιβεβαίωση κωδικού πρόσβασης", +"label.confirmpassword.description" : "Πληκτρολογήστε ξανά τον ίδιο κωδικό πρόσβασης", +"label.congratulations" : "Συγχαρητήρια!!", +"label.connectiontimeout" : "Χρονικό όριο σύνδεσης", +"label.conservemode" : "Λειτουργία εξοικονόμησης", +"label.console.proxy" : "Διακομιστής μεσολάβησης κονσόλας", +"label.console.proxy.vm" : "VM διακομιστή μεσολάβησης κονσόλας", +"label.continue" : "Συνεχίσει", +"label.continue.install" : "Συνεχίστε με την εγκατάσταση", +"label.copied.clipboard" : "Αντιγράφηκε στο Πρόχειρο", +"label.copy" : "Αντίγραφο", +"label.copy.clipboard" : "Αντιγραφή στο Πρόχειρο", +"label.copy.text" : "Αντιγραφή κειμένου", +"label.copyid" : "Αναγνωριστικό αντιγραφής", +"label.copying.iso" : "Αντιγραφή ISO", +"label.corrections.saved" : "Αποθηκευμένες διορθώσεις", +"label.counterid" : "Μετρητή", +"label.cpu" : "Cpu", +"label.cpu.allocated" : "Εκχωρήθηκε cpu", +"label.cpu.sockets" : "Υποδοχές CPU", +"label.cpuallocated" : "Cpu που έχει εκχωρηθεί για VM", +"label.cpuallocatedghz" : "Εκχωρήθηκε cpu", +"label.cpulimit" : "Όρια CPU", +"label.cpumaxdeviation" : "Απόκλιση", +"label.cpunumber" : "Πυρήνες CPU", +"label.cpusockets" : "Ο αριθμός των υποδοχών CPU", +"label.cpuspeed" : "CPU (σε MHz)", +"label.cputotal" : "Σύνολο CPU", +"label.cputotalghz" : "Σύνολο CPU", +"label.cpuused" : "Cpu που χρησιμοποιείται", +"label.cpuusedghz" : "Cpu που χρησιμοποιήθηκε", +"label.create.account" : "Δημιουργία λογαριασμού", +"label.create.backup" : "Έναρξη δημιουργίας αντιγράφων ασφαλείας", +"label.create.network" : "Δημιουργία νέου δικτύου", +"label.create.network.gateway.description" : "Η πύλη της βαθμίδας στην περιοχή super CIDR και δεν επικαλύπτει το CIDR οποιουδήποτε άλλου επιπέδου σε αυτό το VPC.", +"label.create.network.netmask.description" : "Μάσκα δικτύου της βαθμίδας. Για παράδειγμα, με το VPC CIDR 10.0.0.0/16 και το cidr επιπέδου δικτύου 10.1.1.0/24, η πύλη είναι 10.1.1.1 και η μάσκα δικτύου είναι 255.255.255.0", +"label.create.nfs.secondary.staging.storage" : "Δημιουργία δευτερεύοντος χώρου αποθήκευσης ανασυγκρότησης NFS", +"label.create.nfs.secondary.staging.store" : "Δημιουργία δευτερεύοντος χώρου αποθήκευσης ανασυγκρότησης NFS", +"label.create.project" : "Δημιουργία έργου", +"label.create.project.role" : "Δημιουργία ρόλου έργου", +"label.create.site.vpn.connection" : "Δημιουργία σύνδεσης VPN από τοποθεσία σε τοποθεσία", +"label.create.site.vpn.gateway" : "Δημιουργία πύλης VPN από τοποθεσία σε τοποθεσία", +"label.create.snapshot.for.volume" : "Στιγμιότυπο που δημιουργήθηκε για τόμο", +"label.create.ssh.key.pair" : "Δημιουργία ζεύγους κλειδιών SSH", +"label.create.template" : "Δημιουργία προτύπου", +"label.create.user" : "Δημιουργία χρήστη", +"label.create.vpc.tier" : "Δημιουργία επιπέδου VPC", +"label.create.vpn.connection" : "Δημιουργία σύνδεσης VPN", +"label.created" : "Δημιουργήθηκε", +"label.created.by.system" : "Δημιουργήθηκε από το σύστημα", +"label.createnfscache" : "Δημιουργία δευτερεύοντος χώρου αποθήκευσης ανασυγκρότησης NFS", +"label.creating.iprange" : "Δημιουργία περιοχών IP", +"label.credit" : "Πιστωτική", +"label.crosszones" : "Διασταυρωτικές Ζώνες", +"label.currency" : "Νόμισμα", +"label.current" : "Τρέχον", +"label.currentpassword" : "Τρέχων κωδικός πρόσβασης", +"label.custom" : "Προσαρμοσμένη", +"label.custom.disk.offering" : "Προσφορά προσαρμοσμένου δίσκου", +"label.customconstrained" : "Προσαρμοσμένο περιορισμένο", +"label.customdisksize" : "Προσαρμοσμένο μέγεθος δίσκου", +"label.customunconstrained" : "Προσαρμοσμένη χωρίς περιορισμούς", +"label.daily" : "Καθημερινά", +"label.dashboard" : "Ταμπλό", +"label.dashboard.endpoint" : "Τελικό σημείο πίνακα εργαλείων", +"label.data.disk" : "Δίσκος δεδομένων", +"label.data.disk.offering" : "Προσφορά δίσκου δεδομένων", +"label.date" : "Ημερομηνία", +"label.day" : "Ημέρα", +"label.day.of.month" : "Ημέρα του Μήνα", +"label.day.of.week" : "Ημέρα της Εβδομάδας", +"label.dc.name" : "Όνομα ελεγκτή τομέα", +"label.decline.invitation" : "Απόρριψη πρόσκλησης", +"label.dedicate" : "Αφιερώσω", +"label.dedicate.cluster" : "αποκλειστικής χρήσης σύμπλεγμα", +"label.dedicate.host" : "αποκλειστικής χρήσης κεντρικός υπολογιστής", +"label.dedicate.pod" : "αποκλειστικής χρήσης υποομάδας", +"label.dedicate.vlan.vni.range" : "αποκλειστικής χρήσης περιοχή VLAN/VNI", +"label.dedicate.zone" : "Ζώνη αποκλειστικής χρήσης", +"label.dedicated" : "αποκλειστικής χρήσης", +"label.dedicated.vlan.vni.ranges" : "Αποκλειστικής χρήσης σειρές VLAN/VNI", +"label.default" : "Προεπιλογή", +"label.default.use" : "Προεπιλεγμένη χρήση", +"label.default.view" : "Προεπιλεγμένη προβολή", +"label.defaultnetwork" : "Προεπιλεγμένο δίκτυο", +"label.delete" : "Διαγραφή", +"label.delete.acl.list" : "Διαγραφή λίστας ACL", +"label.delete.affinity.group" : "Διαγραφή ομάδας συνάφειας", +"label.delete.alerts" : "Διαγραφή ειδοποιήσεων", +"label.delete.backup" : "Διαγραφή αντιγράφου ασφαλείας", +"label.delete.baremetal.rack.configuration" : "Διαγραφή ρύθμισης παραμέτρων του συνόλου baremetal", +"label.delete.bigswitchbcf" : "Κατάργηση ελεγκτή BCF BigSwitch", +"label.delete.brocadevcs" : "Κατάργηση εναλλάκτης βίντεο μπροκάρ", +"label.delete.certificate" : "Διαγραφή πιστοποιητικού", +"label.delete.ciscoasa1000v" : "Διαγραφή CiscoASA1000v", +"label.delete.ciscovnmc.resource" : "Διαγραφή πόρου CiscoVNMC", +"label.delete.confirm" : "Διαγραφή?", +"label.delete.dedicated.vlan.range" : "Διαγραμμένη αποκλειστική περιοχή VLAN/VNI", +"label.delete.domain" : "Διαγραφή τομέα", +"label.delete.events" : "Διαγραφή συμβάντων", +"label.delete.f5" : "Διαγραφή F5", +"label.delete.gateway" : "Διαγραφή πύλης", +"label.delete.instance.group" : "Διαγραφή ομάδας εικονική μηχανής", +"label.delete.internal.lb" : "Διαγραφή εσωτερικού LB", +"label.delete.netscaler" : "Διαγραφή κλίμακας δικτύου", +"label.delete.niciranvp" : "Κατάργηση ελεγκτή Nvp", +"label.delete.opendaylight.device" : "Διαγραφή ελεγκτή opendaylight", +"label.delete.pa" : "Διαγραφή Πάλο Άλτο", +"label.delete.portable.ip.range" : "Διαγραφή φορητής περιοχής IP", +"label.delete.project" : "Διαγραφή έργου", +"label.delete.project.role" : "Διαγραφή ρόλου έργου", +"label.delete.role" : "Διαγραφή ρόλου", +"label.delete.rule" : "Διαγραφή κανόνα", +"label.delete.secondary.staging.store" : "Διαγραφή δευτερεύοντος χώρου αποθήκευσης ανασυγκρότησης", +"label.delete.setting" : "Διαγραφή ρύθμισης", +"label.delete.snapshot.policy" : "Διαγραφή πολιτικής στιγμιότυπου", +"label.delete.srx" : "Διαγραφή SRX", +"label.delete.sslcertificate" : "Διαγραφή πιστοποιητικού SSL", +"label.delete.ucs.manager" : "Διαγραφή διαχειριστή UCS", +"label.delete.volumes" : "Τόμοι δεδομένων που θα διαγραφούν", +"label.delete.vpn.connection" : "Διαγραφή σύνδεσης VPN", +"label.delete.vpn.customer.gateway" : "Διαγραφή πύλης πελάτη VPN", +"label.delete.vpn.gateway" : "Διαγραφή πύλης VPN", +"label.delete.vpn.user" : "Διαγραφή χρήστη VPN", +"label.deleteconfirm" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το", +"label.deleteprofile" : "Διαγραφή προφίλ", +"label.deleting" : "Διαγραφή", +"label.deleting.failed" : "Η διαγραφή απέτυχε", +"label.deleting.iso" : "Διαγραφή ISO", +"label.deleting.processing" : "Διαγραφή....", +"label.deleting.template" : "Διαγραφή προτύπου", +"label.demote.project.owner" : "Υποβιβασμός λογαριασμού σε κανονικό ρόλο", +"label.demote.project.owner.user" : "Υποβιβασμός χρήστη σε κανονικό ρόλο", +"label.deny" : "Άρνηση", +"label.deployasis" : "Ανάγωση ρυθμίσων VM απο OVA", +"label.deploymentplanner" : "Σχεδιασμός ανάπτυξης", +"label.description" : "Περιγραφή", +"label.destcidr" : "Προορισμός CIDR", +"label.destination" : "Προορισμού", +"label.destinationphysicalnetworkid" : "Αναγνωριστικό φυσικού δικτύου προορισμού", +"label.destinationzoneid" : "Ζώνη προορισμού", +"label.destroy" : "Καταστροφή", +"label.destroy.kubernetes.cluster" : "Καταστροφή του ομοταξίας Kubernetes", +"label.destroy.router" : "Καταστροφή του δρομολογητή", +"label.destroyvmgraceperiod" : "Καταστροφή περιόδου χάριτος VM", +"label.detaching.disk" : "Αποσύνδεση δίσκου", +"label.details" : "Λεπτομέρειες", +"label.deviceid" : "Αναγνωριστικό συσκευής", +"label.devices" : "Συσκευές", +"label.dhcp" : "Dhcp", +"label.dhcp.server.type" : "Τύπος διακομιστή DHCP", +"label.direct.attached.public.ip" : "Άμεση συνημμένη δημόσια IP", +"label.direct.ips" : "Υπηρεσίες ip κοινόχρηστου δικτύου", +"label.directdownload" : "Άμεση λήψη", +"label.disable.autoscale" : "Απενεργοποίηση αυτόματης κλίμακας", +"label.disable.host" : "Απενεργοποίηση κεντρικού υπολογιστή", +"label.disable.storage" : "Απενεργοποίηση χώρου συγκέντρωσης χώρου αποθήκευσης", +"label.disable.network.offering" : "Απενεργοποίηση προσφοράς υπηρεσίας δικτύου", +"label.disable.provider" : "Απενεργοποίηση υπηρεσίας παροχής", +"label.disable.vnmc.provider" : "Απενεργοποίηση υπηρεσίας παροχής VNMC", +"label.disable.vpc.offering" : "Απενεργοποίηση προσφοράς υπηρεσίας VPC", +"label.disable.vpn" : "Απενεργοποίηση VPN απομακρυσμένης πρόσβασης", +"label.disabled" : "Απενεργοποιημένη", +"label.disabling.vpn.access" : "Απενεργοποίηση πρόσβασης VPN", +"label.disassociate.profile.blade" : "Κατάργηση συσχέτισης προφίλ από το Blade", +"label.disbale.vnmc.device" : "Απενεργοποίηση συσκευής VNMC", +"label.disconnected" : "Τελευταία αποσύνδεση", +"label.disk" : "Δίσκο", +"label.disk.newoffering" : "Νέα προσφορά δίσκου", +"label.disk.newoffering.description" : "Νέα προσφορά δίσκου που θα χρησιμοποιηθεί από αυτόν τον τόμο μετά τη μετεγκατάσταση.", +"label.disk.offering.access" : "Δίσκος που προσφέρει πρόσβαση", +"label.disk.offering.details" : "Δίσκος που προσφέρει λεπτομέρειες", +"label.disk.offerings" : "προσφορές υπηρεσίας δίσκων", +"label.disk.size" : "Μέγεθος δίσκου", +"label.disk.volume" : "Τόμος δίσκου", +"label.diskbytesreadrate" : "Ρυθμός ανάγνωσης δίσκου (BPS)", +"label.diskbyteswriterate" : "Ρυθμός εγγραφής δίσκου (BPS)", +"label.diskiopsmax" : "Μέγιστο IOPS", +"label.diskiopsmin" : "Min IOPS", +"label.diskiopsreadrate" : "Ρυθμός ανάγνωσης δίσκου (IOPS)", +"label.diskiopstotal" : "IOPS δίσκου", +"label.diskiopswriterate" : "Ρυθμός εγγραφής δίσκου (IOPS)", +"label.diskioread" : "Ανάγνωση δίσκου (IO)", +"label.diskiowrite" : "Εγγραφή δίσκου (IO)", +"label.diskkbsread" : "Ανάγνωση δίσκου (byte)", +"label.diskkbswrite" : "Εγγραφή δίσκου (byte)", +"label.diskoffering" : "Προσφορά δίσκου", +"label.diskofferingdisplaytext" : "Προσφορά δίσκου", +"label.diskofferingid" : "Προσφορά δίσκου", +"label.disksize" : "Μέγεθος δίσκου (σε GB)", +"label.disksizeallocated" : "o δίσκος εκχωρήθηκε", +"label.disksizeallocatedgb" : "Εκχωρηθεί", +"label.disksizetotal" : "Σύνολο δίσκου", +"label.disksizetotalgb" : "Σύνολο", +"label.disksizeunallocatedgb" : "Μη εκχωρημένο", +"label.disksizeused" : "Μέγεθος δίσκου που χρησιμοποιείται", +"label.disksizeusedgb" : "Χρησιμοποιείται", +"label.display.text" : "Εμφάνιση κειμένου", +"label.displayname" : "Εμφανιζόμενο όνομα", +"label.displaytext" : "Περιγραφή", +"label.distributedvpcrouter" : "Κατανεμημένος δρομολογητής VPC", +"label.dns" : "Dns", +"label.dns.domain.for.guest.networks" : "Τομέας DNS για δίκτυα επισκεπτών", +"label.dns1" : "DNS 1", +"label.dns2" : "DNS 2", +"label.domain" : "Τομέα", +"label.domain.details" : "Λεπτομέρειες τομέα", +"label.domain.id" : "Αναγνωριστικό τομέα", +"label.domain.name" : "Όνομα τομέα", +"label.domain.router" : "Δρομολογητής τομέα", +"label.domain.suffix" : "Επίθημα τομέα DNS (π.χ. xyz.com)", +"label.domainid" : "Τομέα", +"label.domainname" : "Τομέα", +"label.domainpath" : "Τομέα", +"label.domains" : "Τομείς", +"label.done" : "Γίνει", +"label.double.quotes.are.not.allowed" : "Δεν επιτρέπονται διπλά εισαγωγικά", +"label.download" : "Κατέβασμα", +"label.download.kubeconfig.cluster" : "Κατεβάστε το kubeconfig για το σύμπλεγμα

Το kubectl εργαλείο γραμμής εντολών χρησιμοποιεί αρχεία kubeconfig για να βρει τις πληροφορίες που χρειάζεται για να επιλέξει ένα σύμπλεγμα και να επικοινωνήσει με το διακομιστή API ενός ομοταξίας.", +"label.download.kubectl" : "Κατεβάστε kubectl το εργαλείο για την έκδοση ομοταξίας Kubernetes", +"label.download.kubernetes.cluster.config" : "Κατεβάστε kubernetes σύμπλεγμα config", +"label.download.progress" : "Λήψη προόδου", +"label.dpd" : "Εντοπισμός αδρανών ομοτίμων", +"label.drag.new.position" : "Μεταφορά σε νέα θέση", +"label.driver" : "Πρόγραμμα οδήγησης", +"label.duration.in.sec" : "Διάρκεια (σε δευτερόλεπτα)", +"label.dynamicscalingenabled" : "Δυναμική αναπροσαρμογή Ενεργοποίημένη", +"label.dynamicscalingenabled.tooltip" : "To VM μπορεί να αναπροσαρμόζεται δυναμικά μόνο αν τα πρότυπο,προσφερόμενη υπηρεσία και γενικές ρυθμίσεις έχουν την επιλογή δυναμικής αναπροσαρμογής ενεργοποιήμενη.", +"label.edit" : "Επεξεργασία", +"label.edit.acl.list" : "Επεξεργασία λίστας ACL", +"label.edit.acl.rule" : "Επεξεργασία κανόνα ACL", +"label.edit.affinity.group" : "Επεξεργασία ομάδας συνάφειας", +"label.edit.lb.rule" : "Επεξεργασία κανόνα LB", +"label.edit.network.details" : "Επεξεργασία λεπτομερειών δικτύου", +"label.edit.project.details" : "Επεξεργασία λεπτομερειών έργου", +"label.edit.project.role" : "Επεξεργασία ρόλου έργου", +"label.edit.region" : "Επεξεργασία περιοχής", +"label.edit.role" : "Επεξεργασία ρόλου", +"label.edit.rule" : "Επεξεργασία κανόνα", +"label.edit.secondary.ips" : "Επεξεργασία δευτερευουσών ips", +"label.edit.tags" : "Επεξεργασία ετικετών", +"label.edit.traffic.type" : "Επεξεργασία τύπου κίνησης", +"label.edit.user" : "Επεξεργασία χρήστη", +"label.edit.vpc" : "Επεξεργασία VPC", +"label.egress" : "Έξοδος", +"label.egress.default.policy" : "Έξοδος προεπιλεγμένη πολιτική", +"label.egress.rule" : "Κανόνας εξόδου", +"label.egress.rules" : "Κανόνες εξόδου", +"label.egressdefaultpolicy" : "Προεπιλεγμένη πολιτική εξόδου", +"label.elastic" : "Elastic", +"label.email" : "Email", +"label.enable.autoscale" : "Ενεργοποίηση αυτόματης κλίμακας", +"label.enable.host" : "Ενεργοποίηση κεντρικού υπολογιστή", +"label.enable.network.offering" : "Ενεργοποίηση προσφοράς υπηρεσίας δικτύου", +"label.enable.provider" : "Ενεργοποίηση υπηρεσίας παροχής", +"label.enable.s3" : "Ενεργοποίηση δευτερεύοντος χώρου αποθήκευσης με υποστήριξη S3", +"label.enable.swift" : "Ενεργοποίηση γρήγορης ταχύτητας", +"label.enable.storage" : "Ενεργοποίηση χώρου συγκέντρωσης χώρου αποθήκευσης", +"label.enable.vnmc.device" : "Ενεργοποίηση συσκευής VNMC", +"label.enable.vnmc.provider" : "Ενεργοποίηση υπηρεσίας παροχής VNMC", +"label.enable.vpc.offering" : "Ενεργοποίηση προσφοράς υπηρεσίας VPC", +"label.enable.vpn" : "Ενεργοποίηση VPN απομακρυσμένης πρόσβασης", +"label.enabling.vpn" : "Ενεργοποίηση VPN", +"label.enabling.vpn.access" : "Ενεργοποίηση πρόσβασης VPN", +"label.end" : "Τέλος", +"label.end.ip" : "Τερματισμός IP", +"label.end.reserved.system.ip" : "Τερματισμός δεσμευμένου συστήματος IP", +"label.end.vlan" : "Τέλος VLAN", +"label.end.vxlan" : "Τέλος VXLAN", +"label.enddate" : "Κατά ημερομηνία (τέλος)", +"label.endip" : "Τερματισμός IP", +"label.endipv4" : "Τερματισμός IP IPv4", +"label.endipv6" : "Τερματισμός IP IPv6", +"label.endpoint" : "Τελικό σημείο", +"label.endpoint.or.operation" : "Τελικό σημείο ή λειτουργία", +"label.endport" : "Θύρα τέλους", +"label.enter.token" : "Εισαγωγή διακριτικού", +"label.error" : "Σφάλμα", +"label.error.caught" : "Εντοπίστηκε σφάλμα", +"label.error.code" : "Κωδικός σφάλματος", +"label.error.file.read" : "Δεν είναι δυνατή η ανάγνωση του αρχείου", +"label.error.file.upload" : "Η αποστολή του αρχείου απέτυχε", +"label.error.rules.file.import" : "Επιλέξτε ένα έγκυρο αρχείο κανόνων CSV", +"label.error.setting" : "Ρύθμιση σφάλματος", +"label.error.something.went.wrong.please.correct.the.following" : "Κάτι πήγε στραβά. Διορθώστε τα ακόλουθα", +"label.error.upper" : "Σφάλμα", +"label.error.volume.upload" : "Επιλέξτε ένα αρχείο", +"label.espencryption" : "Κρυπτογράφηση ESP", +"label.esphash" : " Hash ESP", +"label.esplifetime" : "Διάρκεια ζωής ESP (δεύτερη)", +"label.esppolicy" : "Πολιτική ESP", +"label.event" : "Συμβάν", +"label.event.archived" : "Αρχειοθετημένα συμβάντα", +"label.event.deleted" : "Τα συμβάντα διαγράφηκαν", +"label.event.timeline" : "χρονοδιάγραμμα συμβάντος", +"label.events" : "Εκδηλώσεις", +"label.every" : "Κάθε", +"label.example" : "Παράδειγμα", +"label.example.plugin" : "Παράδειγμα plugin", +"label.existingnetworks" : "Υφιστάμενα δίκτυα", +"label.expunge" : "Διαγραφή", +"label.expunged" : "Απόκρυψη", +"label.expunging" : "Διαγραφή", +"label.external.link" : "Εξωτερική σύνδεση", +"label.externalid" : "Εξωτερικό αναγνωριστικό", +"label.externalloadbalanceripaddress" : "Διεύθυνση IP της εξωτερικής εξισορρόπησης φόρτου", +"label.extra" : "Επιπλέον ορίσματα", +"label.f5" : "F5", +"label.f5.details" : "F5 λεπτομέρειες", +"label.f5.ip.loadbalancer" : "F5 μεγάλος ισορροπητής φορτίων Ip", +"label.failed" : "Απέτυχε", +"label.featured" : "Επιλεγμένα", +"label.fetch.latest" : "Λήψη της τελευταίας", +"label.files" : "Εναλλακτικά αρχεία για ανάκτηση", +"label.filter" : "Φίλτρο", +"label.filterby" : "Φιλτράρισμα κατά", +"label.fingerprint" : "Δακτυλικών αποτυπωμάτων", +"label.firewall" : "Τείχος προστασίας", +"label.firstname" : "Όνομα", +"label.firstname.lower" : "Όνομα", +"label.fix.errors" : "Επιδιόρθωση σφαλμάτων", +"label.fixed" : "Σταθερή προσφορά", +"label.for" : "Για", +"label.forbidden" : "Απαγορεύεται", +"label.forced" : "Επιβολή", +"label.forceencap" : "Επιβολή ενθυλάκωσης UDP των πακέτων ESP", +"label.forgedtransmits" : "Πλαστά μεταδίδει", +"label.format" : "Μορφή", +"label.french.azerty.keyboard" : "Γαλλικό πληκτρολόγιο AZERTY", +"label.friday" : "Παρασκευή", +"label.from" : "Από", +"label.from.lb" : "από LB", +"label.full" : "Πλήρη", +"label.full.path" : "Πλήρης διαδρομή", +"label.fwdeviceid" : "Αναγνωριστικό", +"label.fwdevicename" : "Πληκτρολογήστε", +"label.fwdevicestate" : "Κατάσταση", +"label.gateway" : "Πύλη", +"label.general.alerts" : "Γενικές ειδοποιήσεις", +"label.generating.url" : "Δημιουργία διεύθυνσης URL", +"label.get.diagnostics.desc" : "Εάν θέλετε να παρακάμψετε τα τυπικά αρχεία που επιστρέφονται, εισαγάγετέ τα εδώ. Διαφορετικά αφήστε κενό και πατήστε OK", +"label.global.settings" : "Καθολικές ρυθμίσεις", +"label.globo.dns" : "GloboDNS", +"label.globo.dns.configuration" : "Ρύθμιση παραμέτρων GloboDNS", +"label.glustervolume" : "Όγκο", +"label.go.back" : "Πήγαινε πίσω", +"label.go.step.2" : "Μετάβαση στο Βήμα 2", +"label.go.step.3" : "Μετάβαση στο Βήμα 3", +"label.go.step.4" : "Μετάβαση στο Βήμα 4", +"label.go.step.5" : "Μετάβαση στο Βήμα 5", +"label.gpu" : "Gpu", +"label.group" : "Ομάδα", +"label.group.by.account" : "Ομαδοποίηση κατά λογαριασμό", +"label.group.by.cluster" : "Ομαδοποίηση κατά σύμπλεγμα", +"label.group.by.pod" : "Ομαδοποίηση κατά υποομάδα", +"label.group.by.zone" : "Ομαδοποίηση κατά ζώνη", +"label.group.optional" : "Ομάδα (Προαιρετικό)", +"label.gslb" : "GSLB", +"label.gslb.assigned.lb" : "Αντιστοιχισμένη εξισορρόπηση φόρτου", +"label.gslb.assigned.lb.more" : "Αντιστοίχιση μεγαλύτερης εξισορρόπησης φόρτου", +"label.gslb.delete" : "Διαγραφή GSLB", +"label.gslb.details" : "Λεπτομέρειες GSLB", +"label.gslb.lb.details" : "Λεπτομέρειες εξισορρόπησης φόρτου", +"label.gslb.lb.remove" : "Κατάργηση εξισορρόπησης φόρτου από αυτό το GSLB", +"label.gslb.service" : "Υπηρεσία GSLB", +"label.gslb.service.private.ip" : "Υπηρεσία GSLB Ιδιωτική IP", +"label.gslb.service.public.ip" : "Υπηρεσία GSLB Δημόσια IP", +"label.gslbdomainname" : "Όνομα τομέα GSLB", +"label.gslbprovider" : "Υπηρεσία GSLB", +"label.gslbproviderprivateip" : "Υπηρεσία GSLB Ιδιωτική IP", +"label.gslbproviderpublicip" : "Υπηρεσία GSLB Δημόσια IP", +"label.gslbservicetype" : "Τύπος υπηρεσίας", +"label.guest" : "Επισκέπτη", +"label.guest.cidr" : "Επισκέπτης CIDR", +"label.guest.end.ip" : "Ip λήξης επισκέπτη", +"label.guest.gateway" : "Πύλη επισκέπτη", +"label.guest.ip" : "Διεύθυνση IP επισκέπτη", +"label.guest.ip.range" : "Εύρος IP επισκέπτη", +"label.guest.netmask" : "Netmask επισκέπτη", +"label.guest.network.details" : "Λεπτομέρειες δικτύου επισκεπτών", +"label.guest.networks" : "Δίκτυα επισκεπτών", +"label.guest.start.ip" : "Εκκίνηση ip επισκέπτη", +"label.guest.traffic" : "Κίνηση επισκεπτών", +"label.guestcidraddress" : "Επισκέπτης CIDR", +"label.guestendip" : "Ip λήξης επισκέπτη", +"label.guestgateway" : "Πύλη επισκέπτη", +"label.guestipaddress" : "Διεύθυνση IP επισκέπτη", +"label.guestiptype" : "Τύπος επισκέπτη", +"label.guestnetmask" : "Netmask επισκέπτη", +"label.guestnetwork" : "Δίκτυο επισκεπτών", +"label.guestnetworkid" : "Αναγνωριστικό δικτύου", +"label.guestnetworkname" : "Όνομα δικτύου", +"label.guestosid" : "Τύπος λειτουργικού συστήματος", +"label.gueststartip" : "Εκκίνηση ip επισκέπτη", +"label.guestvlanrange" : "Εύρος(-ες) VLAN", +"label.guestvmcidr" : "Cidr", +"label.ha" : "HA", +"label.ha.configure" : "Ρύθμιση παραμέτρων HA", +"label.ha.disable" : "Απενεργοποίηση HA", +"label.ha.enable" : "Ενεργοποίηση HA", +"label.haenable" : "Ενεργοποίηση HA", +"label.hahost" : "Ενεργοποίηση HA", +"label.haprovider" : "Υπηρεσία παροχής HA", +"label.hardware" : "Υλικού", +"label.hastate" : "Κράτος HA", +"label.header.backup.schedule" : "Μπορείτε να ρυθμίσετε επαναλαμβανόμενα χρονοδιαγράμματα δημιουργίας αντιγράφων ασφαλείας επιλέγοντας από τις παρακάτω διαθέσιμες επιλογές και εφαρμόζοντας τις προτιμήσεις πολιτικής σας", +"label.header.volume.snapshot" : "Μπορείτε να ρυθμίσετε επαναλαμβανόμενα χρονοδιαγράμματα στιγμιότυπων επιλέγοντας από τις παρακάτω διαθέσιμες επιλογές και εφαρμόζοντας τις προτιμήσεις πολιτικής σας", +"label.header.volume.take.snapshot" : "Επιβεβαιώστε ότι θέλετε να τραβήξετε ένα στιγμιότυπο αυτού του τόμου.", +"label.health.check" : "Έλεγχος υγείας", +"label.health.check.advanced.options" : "Επιλογές για προχωρημένους:", +"label.health.check.configurations.options" : "Επιλογές ρυθμίσεων:", +"label.health.check.interval.in.sec" : "Διάστημα ελέγχου εύρυθμης λειτουργίας (σε δευτερόλεπτο)", +"label.health.check.message.desc" : "Η εξισορρόπηση φόρτου θα εκτελεί αυτόματα ελέγχους εύρυθμης λειτουργίας στις παρουσίες cloudtack και θα δρομολογεί την κίνηση μόνο σε παρουσίες που περνούν τον έλεγχο εύρυθμης λειτουργίας", +"label.health.check.wizard" : "Οδηγός ελέγχου εύρυθμης λειτουργίας", +"label.healthy.threshold" : "Υγιές κατώφλι", +"label.help" : "Βοήθεια", +"label.hide.ingress.rule" : "Απόκρυψη κανόνα εισόδου", +"label.hideipaddressusage" : "Απόκρυψη χρήσης διεύθυνσης IP", +"label.hints" : "Υποδείξεις", +"label.home" : "Αρχική", +"label.host" : "Διεύθυνση IP", +"label.host.alerts" : "Κεντρικοί υπολογιστές σε κατάσταση προειδοποίησης", +"label.host.name" : "Όνομα κεντρικού υπολογιστή", +"label.host.tag" : "Ετικέτα κεντρικού υπολογιστή", +"label.host.ueficapability" : "Υποστηρίζεται UEFI", +"label.hostid" : "Κεντρικού υπολογιστή", +"label.hostname" : "Κεντρικού υπολογιστή", +"label.hostnamelabel" : "Όνομα κεντρικού υπολογιστή", +"label.hosts" : "Hosts", +"label.hosttags" : "Ετικέτες κεντρικού υπολογιστή", +"label.hourly" : "Ωριαία", +"label.hypervisor" : "Hypervisor", +"label.hypervisor.capabilities" : "Δυνατότητες Hypervisor", +"label.hypervisor.type" : "Τύπος Hypervisor", +"label.hypervisors" : "Υπερεπόπτες", +"label.hypervisorsnapshotreserve" : "Αποθεματικό στιγμιότυπου Hypervisor", +"label.hypervisortype" : "Hypervisor", +"label.hypervisorversion" : "Έκδοση Hypervisor", +"label.hypervnetworklabel" : "Ετικέτα κίνησης HyperV", +"label.i.accept.all.license.agreements" : "Αποδέχομαι όλες τις άδειες χρήσης", +"label.icmp" : "Icmp", +"label.icmpcode" : "Κωδικός ICMP", +"label.icmpcode.end.port" : "Κωδικός ICMP / Τελική θύρα", +"label.icmptype" : "Τύπος ICMP", +"label.icmptype.start.port" : "Τύπος ICMP / Θύρα έναρξης", +"label.id" : "Αναγνωριστικό", +"label.identity.and.access" : "Ταυτότητα και πρόσβαση", +"label.ike.version" : "IKE Έδκοση", +"label.ikedh" : "IKE DH", +"label.ikeencryption" : "Κρυπτογράφηση IKE", +"label.ikehash" : "Κατακερματισμός IKE", +"label.ikelifetime" : "Διάρκεια ζωής IKE (δεύτερη)", +"label.ikepolicy" : "Πολιτική IKE", +"label.ikeversion" : "IKE Version", +"label.images" : "Εικόνες", +"label.import.backup.offering" : "Εισαγωγή προσφοράς υπηρεσίας δημιουργίας αντιγράφων ασφαλείας", +"label.import.offering" : "Προσφορά εισαγωγής", +"label.import.role" : "Ρόλος εισαγωγής", +"label.in.progress" : "σε εξέλιξη", +"label.in.progress.for" : "σε εξέλιξη για", +"label.info" : "Πληροφορίες", +"label.info.upper" : "Πληροφορίες", +"label.infrastructure" : "Υποδομή", +"label.ingress" : "Διείσδυση", +"label.ingress.rule" : "Κανόνας εισόδου", +"label.initiated.by" : "Ξεκίνησε από", +"label.insideportprofile" : "Εσωτερικό προφίλ θύρας", +"label.installwizard.addclusterintro.subtitle" : "Τι είναι ένα σύμπλεγμα;", +"label.installwizard.addclusterintro.title" : "Ας προσθέσουμε ένα σύμπλεγμα", +"label.installwizard.addhostintro.subtitle" : "Τι είναι ο κεντρικός υπολογιστής;", +"label.installwizard.addhostintro.title" : "Ας προσθέσουμε έναν κεντρικό υπολογιστή", +"label.installwizard.addpodintro.subtitle" : "Τι είναι η υποομάδα (pod);", +"label.installwizard.addpodintro.title" : "Ας προσθέσουμε μία υποομάδα", +"label.installwizard.addprimarystorageintro.subtitle" : "Τι είναι ο κύριος χώρος αποθήκευσης;", +"label.installwizard.addprimarystorageintro.title" : "Ας προσθέσουμε κύριο χώρο αποθήκευσης", +"label.installwizard.addsecondarystorageintro.subtitle" : "Τι είναι η δευτερεύουσα αποθήκευση;", +"label.installwizard.addsecondarystorageintro.title" : "Ας προσθέσουμε δευτερεύοντα χώρο αποθήκευσης", +"label.installwizard.addzoneintro.subtitle" : "Τι είναι η ζώνη;", +"label.installwizard.addzoneintro.title" : "Ας προσθέσουμε μια ζώνη", +"label.installwizard.click.launch" : "Κάντε κλικ στο κουμπί εκκίνησης.", +"label.installwizard.subtitle" : "Αυτός ο οδηγός θα σας βοηθήσει στη ρύθμιση της εγκατάστασης ™ CloudStack", +"label.installwizard.title" : "Γεια σας και καλώς ήρθατε στο CloudStack™", +"label.instance" : "Παράδειγμα", +"label.instance.groups" : "Ομάδες εικονική μηχανής", +"label.instance.name" : "Όνομα εικονική μηχανής", +"label.instance.scaled.up" : "εικονική μηχανή που κλιμακώνεται στην προσφορά που ζητήθηκε", +"label.instancename" : "Εσωτερικό όνομα", +"label.instanceport" : "Θύρα εικονική μηχανής", +"label.instances" : "Περιπτώσεις", +"label.instanciate.template.associate.profile.blade" : "Αρχικοποίηση προτύπου και συσχέτιση προφίλ με blade", +"label.intermediate.certificate" : "Ενδιάμεσο πιστοποιητικό", +"label.internal.dns.1" : "Εσωτερικό DNS 1", +"label.internal.dns.2" : "Εσωτερικό DNS 2", +"label.internal.lb" : "Εσωτερικό LB", +"label.internal.lb.details" : "Εσωτερικές λεπτομέρειες LB", +"label.internaldns1" : "Εσωτερικό DNS 1", +"label.internaldns2" : "Εσωτερικό DNS 2", +"label.internallb.description" : "Σύντομη περιγραφή της εσωτερικής LB", +"label.internallb.name.description" : "Μοναδικό όνομα για εσωτερική LB", +"label.internallb.sourceip.description" : "Σύντομη περιγραφή της εσωτερικής LB", +"label.internallbvm" : "ΕσωτερικήlbVm", +"label.interval" : "Διάστημα σταθμοσκόπησης (σε δευτερόλεπτο)", +"label.intervaltype" : "Τύπος διαστήματος", +"label.introduction.to.cloudstack" : "Εισαγωγή στο CloudStack™", +"label.invalid.integer" : "Ο ακέραιος δεν είναι έγκυρος", +"label.invalid.number" : "Μη έγκυρος αριθμός", +"label.invitations" : "Προσκλήσεις", +"label.invite" : "Προσκαλέσετε", +"label.invite.to" : "Πρόσκληση σε", +"label.invited.accounts" : "Προσκεκλημένοι λογαριασμοί", +"label.ip" : "Διεύθυνση IP", +"label.ip.allocations" : "Εκχωρήσεις IP", +"label.ip.or.fqdn" : "IP ή FQDN", +"label.ip.range" : "Περιοχή IP", +"label.ip.ranges" : "Περιοχές IP", +"label.ip4dns1" : "IPv4 DNS1", +"label.ip4dns2" : "Dns4 του IPv4", +"label.ip4gateway" : "Πύλη IPv4", +"label.ip4netmask" : "Μάσκα δικτύου IPv4", +"label.ip6address" : "Διεύθυνση IP IPv6", +"label.ip6cidr" : "IPv6 CIDR", +"label.ip6dns1" : "IPv6 DNS1", +"label.ip6dns2" : "Dns6 του IPv6", +"label.ip6gateway" : "Πύλη IPv6", +"label.ipaddress" : "Διεύθυνση IP", +"label.ipaddress1" : "Διεύθυνση IP", +"label.ipaddress2" : "Διεύθυνση IP", +"label.iplimit" : "Δημόσια όρια IP", +"label.ips" : "Ips", +"label.ipsec.splitconnections" : "Διαχωρισμός συνδέσεων", +"label.ipsecpsk" : "Ήδη κοινόχρηστο κλειδί IPsec", +"label.iptotal" : "Σύνολο διευθύνσεων IP", +"label.ipv4.cidr" : "IPv4 CIDR", +"label.ipv4.dns1" : "IPv4 DNS1", +"label.ipv4.dns2" : "Dns4 του IPv4", +"label.ipv6.dns1" : "IPv6 DNS1", +"label.ipv6.dns2" : "Dns6 του IPv6", +"label.iqn" : "Στόχος IQN", +"label.is.in.progress" : "βρίσκεται σε εξέλιξη", +"label.is.redundant.router" : "Εφεδρική", +"label.is.shared" : "Είναι κοινόχρηστο", +"label.isadvanced" : "Εμφάνιση ρυθμίσεων για προχωρημένους", +"label.iscsi" : "Iscsi", +"label.iscustomized" : "Προσαρμοσμένο μέγεθος δίσκου", +"label.iscustomizeddiskiops" : "Προσαρμοσμένη iops", +"label.iscustomizediops" : "Προσαρμοσμένη iops", +"label.isdedicated" : "αποκλειστικής χρήσης", +"label.isdefault" : "Είναι προεπιλογή", +"label.isdynamicallyscalable" : "Δυναμικά επεκτάσιμη", +"label.isextractable" : "Εκχυλιζόμενο", +"label.isfeatured" : "Επιλεγμένα", +"label.isforced" : "Επιβολή διαγραφής", +"label.ismanaged" : "Διαχείριση", +"label.iso" : "Iso", +"label.iso.boot" : "Εκκίνηση ISO", +"label.iso.id" : "Αναγνωριστικό ISO", +"label.iso.name" : "Όνομα ISO", +"label.isoid" : "Iso", +"label.isolated" : "Απομονωμένες", +"label.isolated.networks" : "Απομονωμένα δίκτυα", +"label.isolatedpvlanid" : "Δευτερεύον αναγνωριστικό VLAN", +"label.isolatedpvlantype" : "Δευτερεύων τύπος VLAN", +"label.isolation.method" : "Μέθοδος απομόνωσης", +"label.isolation.mode" : "Λειτουργία απομόνωσης", +"label.isolationmethod" : "Μέθοδος απομόνωσης", +"label.isolationmethods" : "Μέθοδος απομόνωσης", +"label.isolationuri" : "URI απομόνωσης", +"label.isoname" : "Συνημμένο ISO", +"label.isos" : "ISOs", +"label.isostate" : "Κατάσταση ISO", +"label.ispasswordenabled" : "Ενεργοποιημένος κωδικός πρόσβασης", +"label.ispersistent" : "Επίμονο ", +"label.isportable" : "Διασταυρωτικές Ζώνες", +"label.ispublic" : "Δημόσια", +"label.isready" : "Έτοιμο", +"label.isredundantrouter" : "Εφεδρικός δρομολογητής", +"label.isrouting" : "Δρομολόγηση", +"label.isself" : "Self", +"label.isshared" : "Κοινόχρηστο", +"label.issourcenat" : "Πηγαίο NAT", +"label.isstaticnat" : "Στατικό NAT", +"label.issystem" : "Είναι σύστημα", +"label.isvolatile" : "Άστατο", +"label.item.listing" : "Λίστα στοιχείων", +"label.items" : "Στοιχεία", +"label.japanese.keyboard" : "Ιαπωνικό πληκτρολόγιο", +"label.keep" : "Διατήρηση", +"label.keep.colon" : "Διατήρηση", +"label.key" : "Κλειδί", +"label.keyboard" : "Γλώσσα πληκτρολογίου", +"label.keyboardtype" : "Τύπος πληκτρολογίου", +"label.keypair" : "Ζεύγος πλήκτρων SSH", +"label.kubeconfig.cluster" : "Ρύθμιση παραμέτρων ομοταξίας Kubernetes", +"label.kubernetes" : "Κουμπερνέτες", +"label.kubernetes.cluster" : "Σύμπλεγμα Kubernetes", +"label.kubernetes.cluster.create" : "Δημιουργία ομοταξίας Kubernetes", +"label.kubernetes.cluster.delete" : "Διαγραφή ομοταξίας Kubernetes", +"label.kubernetes.cluster.details" : "Λεπτομέρειες ομοταξίας Kubernetes", +"label.kubernetes.cluster.scale" : "κλιμάκωση ομοταξίας kubernetes ", +"label.kubernetes.cluster.start" : "Εκκίνηση ομοταξίας kubernetes", +"label.kubernetes.cluster.stop" : "Σύμπλεγμα \"Στάση κουμπερνέτες\"", +"label.kubernetes.cluster.upgrade" : "Αναβάθμιση ομοταξίας Kubernetes", +"label.kubernetes.dashboard" : "Περιβάλλον εργασίας χρήστη πίνακα εργαλείων kubernetes", +"label.kubernetes.isos" : "Kubernetes ISOs", +"label.kubernetes.service" : "Υπηρεσία Kubernetes", +"label.kubernetes.version.add" : "Προσθήκη έκδοσης Kubernetes", +"label.kubernetes.version.delete" : "Διαγραφή έκδοσης Kubernetes", +"label.kubernetes.version.details" : "Λεπτομέρειες έκδοσης kubernetes", +"label.kubernetes.version.update" : "Διαχείριση έκδοσης Kubernetes", +"label.kubernetesversionid" : "Έκδοση Kubernetes", +"label.kubernetesversionname" : "Έκδοση Kubernetes", +"label.kvmnetworklabel" : "Ετικέτα κίνησης KVM", +"label.l2" : "L2", +"label.l2gatewayserviceuuid" : "Uuid υπηρεσίας πύλης L2", +"label.l3gatewayserviceuuid" : "Uuid υπηρεσίας πύλης L3", +"label.label" : "Ετικέτα", +"label.lang.arabic" : "Αραβικά", +"label.lang.brportugese" : "Πορτογαλικά Βραζιλίας", +"label.lang.catalan" : "Καταλανικά", +"label.lang.chinese" : "Κινέζικα (Απλοποιημένα)", +"label.lang.dutch" : "Ολλανδικά (Κάτω Χώρες)", +"label.lang.english" : "Αγγλικά", +"label.lang.french" : "Γαλλικά", +"label.lang.german" : "Γερμανικά", +"label.lang.hungarian" : "Ουγγρικά", +"label.lang.italian" : "Ιταλικά", +"label.lang.japanese" : "Ιαπωνικά", +"label.lang.korean" : "Κορεατικά", +"label.lang.norwegian" : "Νορβηγικά", +"label.lang.polish" : "Πολωνικά", +"label.lang.russian" : "Ρωσικά", +"label.lang.spanish" : "Ισπανικά", +"label.last.updated" : "Τελευταία ενημέρωση", +"label.lastannotated" : "Τελευταία ημερομηνία σχολίου", +"label.lastname" : "Επώνυμο", +"label.lastname.lower" : "Επώνυμο", +"label.latest.events" : "Τελευταίες εκδηλώσεις", +"label.launch" : "Έναρξη", +"label.launch.vm" : "Εκκίνηση εικονικής μηχανής", +"label.launch.zone" : "Ζώνη εκκίνησης", +"label.lb.algorithm.leastconn" : "Ελάχιστες συνδέσεις", +"label.lb.algorithm.roundrobin" : "Round-robin", +"label.lb.algorithm.source" : "Πηγή", +"label.lb.cookie" : "LbCookie", +"label.lb.protocol.http" : "HTTP", +"label.lb.protocol.ssl" : "Ssl", +"label.lb.protocol.tcp.proxy" : "Διακομιστής μεσολάβησης TCP", +"label.lbdevicededicated" : "αποκλειστικής χρήσης", +"label.lbdeviceid" : "Αναγνωριστικό", +"label.lbdevicename" : "Πληκτρολογήστε", +"label.lbdevicestate" : "Κατάσταση", +"label.lbtype" : "Τύπος εξισορρόπησης φόρτου", +"label.ldap.configuration" : "Ρύθμιση παραμέτρων LDAP", +"label.ldap.group.name" : "Ομάδα LDAP", +"label.ldap.port" : "Θύρα LDAP", +"label.level" : "Επίπεδο", +"label.license.agreements" : "Άδειες χρήσης", +"label.limit" : "Όριο", +"label.limitcpuuse" : "όριο CPU", +"label.limits" : "Ρύθμιση παραμέτρων ορίων", +"label.link.domain.to.ldap" : "Σύνδεση τομέα με LDAP", +"label.linklocalip" : "Σύνδεση τοπικής διεύθυνσης IP", +"label.linux" : "Linux", +"label.list.ciscoasa1000v" : "ASA 1000v", +"label.list.ciscovnmc" : "Cisco VNMC", +"label.list.nodes" : "Κόμβοι λίστας", +"label.list.pods" : "Κατάλογος υποομάδων", +"label.list.services" : "Υπηρεσίες λίστας", +"label.load.balancer" : "Εξισορρόπηση φόρτου", +"label.load.balancing.policies" : "Πολιτικές εξισορρόπησης φόρτου", +"label.loadbalancerinstance" : "Αντιστοιχισμένα VM", +"label.loadbalancerrule" : "Κανόνας εξισορρόπησης φόρτου", +"label.loadbalancing" : "Εξισορρόπηση φόρτου", +"label.loading" : "Φόρτωση", +"label.local" : "Τοπικό", +"label.local.storage" : "Τοπικός χώρος αποθήκευσης", +"label.local.storage.enabled" : "Ενεργοποίηση τοπικού χώρου αποθήκευσης για VM χρήστη", +"label.local.storage.enabled.system.vms" : "Ενεργοποίηση τοπικού χώρου αποθήκευσης για VM συστήματος", +"label.localstorageenabled" : "Ενεργοποίηση τοπικού χώρου αποθήκευσης για VM χρήστη", +"label.localstorageenabledforsystemvm" : "Ενεργοποίηση τοπικού χώρου αποθήκευσης για VM συστήματος", +"label.login" : "Σύνδεση", +"label.login.portal" : "Σύνδεση πύλης", +"label.login.single.signon" : "Καθολική σύνδεση", +"label.logout" : "Αποσύνδεση", +"label.lun" : "Lun", +"label.lun.number" : "Lun #", +"label.lxcnetworklabel" : "Ετικέτα κίνησης LXC", +"label.macaddress" : "Διεύθυνση MAC", +"label.macaddress.example" : "Η διεύθυνση MAC. Παράδειγμα: 01:23:45:67:89:ab", +"label.macaddresschanges" : "Αλλαγές διεύθυνσης MAC", +"label.macos" : "Macos", +"label.make.project.owner" : "Πραγματοποίηση κατόχου έργου λογαριασμού", +"label.make.user.project.owner" : "Ορισμός κατόχου έργου χρήστη", +"label.makeredundant" : "Κάνε εφεδρικό", +"label.manage" : "Διαχείριση", +"label.manage.resources" : "Διαχείριση πόρων", +"label.manage.vpn.user" : "Διαχείριση χρηστών VPN", +"label.managedstate" : "Διαχειριζόμενη κατάσταση", +"label.management" : "Διαχείριση", +"label.management.ips" : "Διευθύνσεις IP διαχείρισης", +"label.management.server" : "Διακομιστής διαχείρισης", +"label.management.servers" : "Διακομιστές διαχείρισης", +"label.managementservers" : "Αριθμός διακομιστών διαχείρισης", +"label.controlnodes" : "Kόμβοι ελέγχου", +"label.max.primary.storage" : "Μέγιστος αρχικός (GiB)", +"label.max.secondary.storage" : "Μέγιστος αριθμός δευτερευουσών (GiB)", +"label.maxcpu" : "Μέγιστοι πυρήνες CPU", +"label.maxcpunumber" : "Μέγιστοι πυρήνες CPU", +"label.maxdatavolumeslimit" : "Μέγιστο όριο τόμων δεδομένων", +"label.maxerrorretry" : "Μέγιστη επανάληψη σφάλματος", +"label.maxguestslimit" : "Μέγιστο όριο επισκεπτών", +"label.maxhostspercluster" : "Μέγιστοι κεντρικοί υπολογιστές ανά σύμπλεγμα", +"label.maximum" : "Μέγιστη", +"label.maxinstance" : "Μέγιστες παρουσίες", +"label.maxiops" : "Μέγιστο IOPS", +"label.maxmemory" : "Μέγιστη μνήμη (MiB)", +"label.maxnetwork" : "Μέγιστα δίκτυα", +"label.maxprimarystorage" : "Μέγιστη κύρια αποθήκευση (GiB)", +"label.maxproject" : "Μέγ. Έργα", +"label.maxpublicip" : "Μέγιστος αριθμός δημόσιων IP", +"label.maxsecondarystorage" : "Μέγιστη δευτερεύουσα αποθήκευση (GiB)", +"label.maxsnapshot" : "Μέγιστα στιγμιότυπα", +"label.maxtemplate" : "Μέγ. πρότυπα", +"label.maxuservm" : "Μέγιστες vm χρήστη", +"label.maxvolume" : "Μέγιστος αριθμός Volumes", +"label.maxvpc" : "Μέγ. VPCs", +"label.may.continue" : "Μπορείτε τώρα να συνεχίσετε.", +"label.mb.memory" : "Μνήμη MB", +"label.memallocated" : "Κατανομή Μνήμης", +"label.memory" : "Μνήμη", +"label.memory.maximum.mb" : "Μέγιστη μνήμη (σε MB)", +"label.memory.mb" : "Μνήμη (σε MB)", +"label.memory.total" : "Σύνολο μνήμης", +"label.memory.used" : "Μνήμη που χρησιμοποιείται", +"label.memoryallocated" : "Εκχωρημένη μνήμη", +"label.memoryallocatedgb" : "Εκχωρημένη μνήμη", +"label.memorylimit" : "Όρια μνήμης (MiB)", +"label.memorymaxdeviation" : "Απόκλιση", +"label.memorytotal" : "Εκχωρημένη μνήμη", +"label.memorytotalgb" : "Σύνολο μνήμης", +"label.memoryused" : "Χρησιμοποιημένη μνήμη", +"label.memoryusedgb" : "Μνήμη που χρησιμοποιείται", +"label.memused" : "Χρήση μνήμης", +"label.menu.all.accounts" : "Όλοι οι λογαριασμοί", +"label.menu.all.instances" : "Όλες οι παρουσίες", +"label.menu.backup" : "Αντίγραφο ασφαλείας", +"label.menu.backup.offerings" : "προσφορές υπηρεσίας δημιουργίας αντιγράφων ασφαλείας", +"label.menu.community.isos" : "Κοινότητα ISOs", +"label.menu.community.templates" : "Πρότυπα κοινότητας", +"label.menu.destroyed.instances" : "Κατεστραμμένες παρουσίες", +"label.menu.featured.isos" : "Προτεινόμενα ISOs", +"label.menu.featured.templates" : "Προτεινόμενα πρότυπα", +"label.menu.ipaddresses" : "Διευθύνσεις IP", +"label.menu.my.accounts" : "Οι λογαριασμοί μου", +"label.menu.my.instances" : "Οι παρουσίες μου", +"label.menu.my.isos" : "IsOs μου", +"label.menu.my.templates" : "Τα πρότυπά μου", +"label.menu.physical.resources" : "Φυσικοί πόροι", +"label.menu.regions" : "Περιοχές", +"label.menu.running.instances" : "Εκτέλεση παρουσιών", +"label.menu.security.groups" : "Ομάδες ασφαλείας", +"label.menu.service.offerings" : "προσφορές υπηρεσίας υπηρεσιών", +"label.menu.sshkeypair" : "SSH KeyPair", +"label.menu.stopped.instances" : "Παρουσίες που διακόπηκαν", +"label.menu.storage" : "Αποθήκευσης", +"label.menu.system" : "Σύστημα", +"label.menu.virtual.appliances" : "Εικονικές συσκευές", +"label.menu.virtual.resources" : "Εικονικοί πόροι", +"label.metrics" : "Μετρήσεις", +"label.metrics.cpu.allocated" : "Εκχώρηση CPU", +"label.metrics.cpu.usage" : "Cpu", +"label.metrics.disk.iops.total" : "Iops", +"label.metrics.disk.read" : "Διαβάστε", +"label.metrics.disk.usage" : "Χρήση δίσκου", +"label.metrics.disk.write" : "Γράψετε", +"label.metrics.memory.usage" : "Χρήση Mem", +"label.metrics.network.read" : "Διαβάστε", +"label.metrics.network.usage" : "Χρήση δικτύου", +"label.metrics.network.write" : "Γράψετε", +"label.metrics.num.cpu.cores" : "Πυρήνες", +"label.migrate.data.from.image.store" : "Μετεγκατάσταση δεδομένων από το χώρο αποθήκευσης εικόνων", +"label.migrate.instance.to" : "Μετεγκατάσταση εικονική μηχανής σε", +"label.migrate.instance.to.host" : "Μετεγκατάσταση εικονική μηχανής σε άλλο κεντρικό υπολογιστή", +"label.migrate.instance.to.ps" : "Μετεγκατάσταση εικονική μηχανής σε άλλο κύριο χώρο αποθήκευσης", +"label.migrate.lb.vm" : "Μετεγκατάσταση εικονικής μηχανής LB", +"label.migrate.lb.vm.to.ps" : "Μετεγκατάσταση LB VM σε άλλο κύριο χώρο αποθήκευσης", +"label.migrate.router.to" : "Μετεγκατάσταση δρομολογητή σε", +"label.migrate.systemvm.to" : "Μετεγκατάσταση εικονικής μηχανής συστήματος σε", +"label.migrate.to.host" : "Μετεγκατάσταση στον κεντρικό υπολογιστή", +"label.migrate.to.storage" : "Μετεγκατάσταση στο χώρο αποθήκευσης", +"label.migrate.volume" : "Μετεγκατάσταση τόμου", +"label.migrate.volume.newdiskoffering.desc" : "Αυτή η επιλογή επιτρέπει στους διαχειριστές να αντικαταστήσουν την παλιά προσφορά υπηρεσίας δίσκου, χρησιμοποιώντας μία που ταιριάζει καλύτερα στη νέα τοποθέτηση του τόμου.", +"label.migrate.volume.to.primary.storage" : "Μετεγκατάσταση τόμου σε άλλο κύριο χώρο αποθήκευσης", +"label.migrating" : "Μετεγκατάσταση", +"label.migrating.data" : "Μετεγκατάσταση δεδομένων", +"label.min.balance" : "Υπόλοιπο Min", +"label.min.past.hour" : "min μετά την ώρα", +"label.min_balance" : "Υπόλοιπο Min", +"label.mincpunumber" : "Ελάχιστοι πυρήνες CPU", +"label.minimum" : "Ελάχιστο", +"label.mininstance" : "Ελάχιστες παρουσίες", +"label.miniops" : "Min IOPS", +"label.minmaxiops" : "Min IOPS / Max IOPS", +"label.minmemory" : "Ελάχιστη μνήμη (σε MB)", +"label.minute.past.hour" : "λεπτά μετά την ώρα", +"label.minutes.past.hour" : "λεπτά μετά την ώρα", +"label.monday" : "Δευτέρα", +"label.monitor" : "Παρακολούθηση", +"label.monthly" : "Μηνιαία", +"label.more.access.dashboard.ui" : "Περισσότερες πληροφορίες σχετικά με την πρόσβαση στο περιβάλλον εργασίας χρήστη του πίνακα εργαλείων", +"label.more.templates" : "Περισσότερα πρότυπα", +"label.move.down.row" : "Μετακίνηση κατά μία γραμμή προς τα κάτω", +"label.move.to.bottom" : "Μετακίνηση προς τα κάτω", +"label.move.to.top" : "Μετακίνηση στην κορυφή", +"label.move.up.row" : "Μετακίνηση κατά μία γραμμή προς τα επάνω", +"label.my.account" : "Ο λογαριασμός μου", +"label.my.network" : "Το δίκτυό μου", +"label.my.templates" : "Τα πρότυπά μου", +"label.na" : "Μη Διαθέσιμο", +"label.name" : "Όνομα", +"label.name.optional" : "Όνομα (Προαιρετικό)", +"label.nat" : "Ενεργοποίηση NAT bigswitch BCF", +"label.nat.port.range" : "Περιοχή θυρών NAT", +"label.ncc" : "Ncc", +"label.ncc.delete" : "Διαγραφή NCC", +"label.ncc.details" : "Λεπτομέρειες NCC", +"label.netmask" : "Netmask", +"label.netscaler" : "Διαβαθμίσεις δικτύου", +"label.netscaler.details" : "Λεπτομέρειες netsccaler", +"label.netscaler.mpx" : "Εξισορρόπηση φόρτου NETSccaler MPX", +"label.netscaler.sdx" : "Εξισορρόπηση φόρτου SDX κλίμακας δικτύου", +"label.netscaler.vpx" : "Εξισορρόπηση φόρτου VPX του NetScaler", +"label.network" : "Δικτύου", +"label.network.acl" : "ACL δικτύου", +"label.network.acl.lists" : "Λίστες ACL δικτύου", +"label.network.acls" : "Acl δικτύου", +"label.network.addvm" : "Προσθήκη δικτύου σε εικονική μηχανή", +"label.network.desc" : "Δίκτυο Desc", +"label.network.details" : "Λεπτομέρειες δικτύου", +"label.network.device" : "Συσκευή δικτύου", +"label.network.device.type" : "Τύπος συσκευής δικτύου", +"label.network.domain" : "Τομέας δικτύου", +"label.network.label.display.for.blank.value" : "Χρήση προεπιλεγμένης πύλης", +"label.network.name" : "Όνομα δικτύου", +"label.network.offering" : "Προσφορά δικτύου", +"label.network.offering.access" : "Δίκτυο που προσφέρει πρόσβαση", +"label.network.offering.details" : "Λεπτομέρειες προσφοράς υπηρεσίας δικτύου", +"label.network.offering.display.text" : "Κείμενο εμφάνισης προσφοράς υπηρεσίας δικτύου", +"label.network.offering.name" : "Όνομα προσφοράς υπηρεσίας δικτύου", +"label.network.offerings" : "προσφορές υπηρεσίας δικτύου", +"label.network.service.providers" : "Υπηρεσίες παροχής δικτύου", +"label.networkcidr" : "Δίκτυο CIDR", +"label.networkdevicetype" : "Πληκτρολογήστε", +"label.networkdomain" : "Τομέας δικτύου", +"label.networkdomaintext" : "Τομέας δικτύου", +"label.networkid" : "Δικτύου", +"label.networking.and.security" : "Δικτύωση και ασφάλεια", +"label.networkkbsread" : "Ανάγνωση δικτύου", +"label.networkkbswrite" : "Εγγραφή δικτύου", +"label.networklimit" : "Όρια δικτύου", +"label.networkname" : "Όνομα δικτύου", +"label.networkofferingdisplaytext" : "Προσφορά δικτύου", +"label.networkofferingid" : "Προσφορά δικτύου", +"label.networkofferingidtext" : "Αναγνωριστικό προσφοράς υπηρεσίας δικτύου", +"label.networkofferingname" : "Προσφορά δικτύου", +"label.networkrate" : "Ρυθμός δικτύου (Mb/s)", +"label.networkread" : "Ανάγνωση δικτύου", +"label.networks" : "Δίκτυα", +"label.networkspeed" : "Ταχύτητα δικτύου", +"label.networktype" : "Τύπος δικτύου", +"label.networkwrite" : "Εγγραφή δικτύου", +"label.new" : "Νέο", +"label.new.instance.group" : "Νέα ομάδα εικονική μηχανής", +"label.new.password" : "Νέος κωδικός πρόσβασης", +"label.new.project" : "Νέο έργο", +"label.new.secondaryip.description" : "Εισαγωγή νέας δευτερεύουσας διεύθυνσης IP", +"label.new.tag" : "Νέα ετικέτα", +"label.new.vm" : "Νέα εικονική μηχανή", +"label.newdiskoffering" : "Νέα Προσφορά", +"label.newinstance" : "Νέα εικονική μηχανή", +"label.newname" : "Νέο όνομα", +"label.newsize" : "Νέο μέγεθος (GB)", +"label.next" : "Επόμενη", +"label.nexusvswitch" : "Nexus 1000v", +"label.nfs" : "Nfs", +"label.nfs.storage" : "Χώρος αποθήκευσης NFS", +"label.nfscachenfsserver" : "Διακομιστής NFS", +"label.nfscachepath" : "Διαδρομή", +"label.nfscachezoneid" : "Ζώνη", +"label.nfsserver" : "Διακομιστής NFS", +"label.nicadaptertype" : "Τύπος προσαρμογέα NIC", +"label.nicira.controller.address" : "Διεύθυνση ελεγκτή", +"label.nicira.nvp.details" : "Λεπτομέρειες για το NVP nicira", +"label.nics" : "Nics", +"label.no" : "Όχι", +"label.no.actions" : "Δεν υπάρχουν διαθέσιμες ενέργειες", +"label.no.alerts" : "Χωρίς πρόσφατες ειδοποιήσεις", +"label.no.data" : "Δεν υπάρχουν δεδομένα για εμφάνιση", +"label.no.errors" : "Δεν υπάρχουν πρόσφατα σφάλματα", +"label.no.grouping" : "(χωρίς ομαδοποίηση)", +"label.no.isos" : "Δεν υπάρχουν διαθέσιμα ISOs", +"label.no.items" : "Δεν υπάρχουν διαθέσιμα στοιχεία", +"label.no.matching.offering" : "Δεν βρέθηκε προσφορά που να ταιριάζει", +"label.no.security.groups" : "Δεν υπάρχουν διαθέσιμες ομάδες ασφαλείας", +"label.noderootdisksize" : "Μέγεθος ριζικού δίσκου κόμβου (σε GB)", +"label.nodiskcache" : "Δεν υπάρχει cache δίσκου", +"label.none" : "Κανένας", +"label.noselect" : "Όχι, ευχαριστώ", +"label.not.found" : "Δεν βρέθηκε", +"label.not.suitable" : "Δεν είναι κατάλληλο", +"label.notifications" : "Ειδοποιήσεις", +"label.num.cpu.cores" : "# των πυρήνων cpu", +"label.number" : "#Rule", +"label.number.of.clusters" : "Αριθμός συμπλεγμάτων", +"label.number.of.hosts" : "Αριθμός κεντρικών υπολογιστών", +"label.number.of.pods" : "Αριθμός υποομάδων", +"label.number.of.system.vms" : "Αριθμός VM συστήματος", +"label.number.of.virtual.routers" : "Αριθμός εικονικών δρομολογητών", +"label.number.of.zones" : "Αριθμός ζωνών", +"label.numberofrouterrequiresupgrade" : "Σύνολο εικονικών δρομολογητών που απαιτούν αναβάθμιση", +"label.numretries" : "Αριθμός επαναλήψεων", +"label.nvpdeviceid" : "Αναγνωριστικό", +"label.ocfs2" : "OCFS2", +"label.of" : "του", +"label.of.month" : "του μήνα", +"label.offerha" : "Προσφορά HA", +"label.offeringtype" : "Υπολογισμός τύπου προσφοράς υπηρεσίας", +"label.ok" : "Ok", +"label.open.documentation" : "Άνοιγμα τεκμηρίωσης", +"label.open.url" : "Άνοιγμα διεύθυνσης URL στο πρόγραμμα περιήγησης", +"label.opendaylight" : "Άνοιγμα σημειωσιού ημέρας", +"label.opendaylight.controller" : "Ελεγκτής ανοιχτού φωτισμού ημέρας", +"label.opendaylight.controllerdetail" : "Λεπτομέρειες ελεγκτή OpenDaylight", +"label.opendaylight.controllers" : "Ελεγκτές φωτισμού OpenDay", +"label.operation" : "Λειτουργία", +"label.optional" : "Προαιρετική", +"label.order" : "Παραγγελία", +"label.oscategoryid" : "Προτίμηση λειτουργικού συστήματος", +"label.ostypeid" : "Τύπος λειτουργικού συστήματος", +"label.ostypename" : "Τύπος λειτουργικού συστήματος", +"label.other" : "Άλλα", +"label.outofbandmanagement" : "Διαχείριση εκτός ζώνης", +"label.outofbandmanagement.action.issue" : "Έκδοση ενέργειας ενέργειας διαχείρισης εκτός ζώνης", +"label.outofbandmanagement.changepassword" : "Αλλαγή κωδικού πρόσβασης διαχείρισης εκτός ζώνης", +"label.outofbandmanagement.configure" : "Ρύθμιση παραμέτρων διαχείρισης εκτός ζώνης", +"label.outofbandmanagement.disable" : "Απενεργοποίηση διαχείρισης εκτός ζώνης", +"label.outofbandmanagement.enable" : "Ενεργοποίηση διαχείρισης εκτός ζώνης", +"label.overprovisionfactor" : "Υπερυποθωσών συντελεστής", +"label.override.guest.traffic" : "Παράκαμψη της κίνησης επισκεπτών", +"label.override.public.traffic" : "Παράκαμψη δημόσιας κίνησης", +"label.override.rootdisk.size" : "Παράκαμψη μεγέθους ριζικού δίσκου", +"label.overrideguesttraffic" : "Παράκαμψη της κίνησης επισκεπτών", +"label.overridepublictraffic" : "Παράκαμψη δημόσιας κίνησης", +"label.ovf.properties" : "ιδιότητες vApp", +"label.ovm3cluster" : "Εγγενής ομαδοποίηση", +"label.ovm3networklabel" : "Ετικέτα κίνησης OVM3", +"label.ovm3pool" : "Εγγενής ομαδοποίηση", +"label.ovm3vip" : "Πρωτεύουσα Vip IP", +"label.ovmnetworklabel" : "Ετικέτα κίνησης OVM", +"label.ovs" : "OVS", +"label.owned.public.ips" : "Δημόσιες διευθύνσεις IP που ανήκουν", +"label.owner.account" : "Λογαριασμός κατόχου", +"label.owner.domain" : "Τομέας κατόχου", +"label.owners" : "Ιδιοκτήτες", +"label.pa" : "Palo Alto", +"label.page" : "Σελίδα", +"label.palo.alto.details" : "Palo Alto λεπτομέρειες", +"label.palo.alto.firewall" : "Τείχος προστασίας Palo Alto", +"label.palp" : "Προφίλ αρχείου καταγραφής Palo Alto", +"label.params" : "Παραμέτρους", +"label.parent.domain" : "Γονικός τομέας", +"label.parentdomainname" : "Γονικός τομέας", +"label.parentname" : "Γονικό", +"label.passive" : "Παθητική", +"label.password" : "Κωδικό πρόσβασης", +"label.password.reset.confirm" : "Έγινε επαναφορά του κωδικού πρόσβασης σε ", +"label.passwordenabled" : "Ενεργοποιημένος κωδικός πρόσβασης", +"label.path" : "Διαδρομή", +"label.patp" : "Palo Alto Προφίλ Απειλής", +"label.pavr" : "Εικονικός δρομολογητής", +"label.payload" : "Ωφέλιμο φορτίο", +"label.pcidevice" : "Gpu", +"label.per.account" : "Ανά λογαριασμό", +"label.per.zone" : "Ανά ζώνη", +"label.perfectforwardsecrecy" : "Ιδανική προώθηση μυστικότητας", +"label.perform.fresh.checks" : "Εκτέλεση νέων ελέγχων", +"label.performfreshchecks" : "Εκτέλεση νέων ελέγχων", +"label.permission" : "Άδεια", +"label.permissions" : "Δικαιώματα", +"label.physical.network" : "Φυσικό δίκτυο", +"label.physical.network.id" : "Αναγνωριστικό φυσικού δικτύου", +"label.physical.network.name" : "Όνομα φυσικού δικτύου", +"label.physicalnetworkid" : "Φυσικό δίκτυο", +"label.physicalsize" : "Φυσικό μέγεθος", +"label.ping.cifs.password" : "Κωδικός πρόσβασης PING CIFS", +"label.ping.cifs.username" : "Όνομα χρήστη PING CIFS", +"label.ping.dir" : "Κατάλογος PING", +"label.ping.path" : "Διαδρομή ping", +"label.ping.storage.ip" : "IP αποθήκευσης PING", +"label.pkcs.private.certificate" : "Ιδιωτικό πιστοποιητικό PKCS#8", +"label.plannermode" : "Λειτουργία σχεδιασμού", +"label.please.complete.the.following.fields" : "Συμπληρώστε τα ακόλουθα πεδία", +"label.please.specify.netscaler.info" : "Καθορίστε πληροφορίες netsccaler", +"label.please.wait" : "Παρακαλώ περίμενε", +"label.plugin.details" : "Λεπτομέρειες προσθήκης", +"label.plugins" : "Plugins", +"label.pod" : "Υποομάδα", +"label.pod.dedicated" : "Υποομάδα αποκλειστικής χρήσης", +"label.pod.name" : "Όνομα υποομάδας", +"label.podid" : "Υποομάδα", +"label.podname" : "Όνομα υπομονάδας", +"label.pods" : "Υποομάδα", +"label.port" : "Θύρα", +"label.port.forwarding.policies" : "Πολιτικές προώθησης θυρών", +"label.port.range" : "Εύρος θυρών", +"label.portable.ip" : "Φορητή IP", +"label.portable.ip.range.details" : "λεπτομέρειες εύρους Φορητής IP", +"label.portable.ip.ranges" : "Φορητές περιοχές IP", +"label.portableipaddress" : "Φορητές IP", +"label.portforwarding" : "Προώθηση Θυρών", +"label.powerflex.gateway" : "Πύλη", +"label.powerflex.gateway.username" : "Όνομα χρήστη πύλης", +"label.powerflex.gateway.password" : "Κωδικός χρήστη πύλης", +"label.powerflex.storage.pool" : "Χώρος αποθήκευσης", +"label.powerstate" : "Κατάσταση ενέργειας", +"label.preferred" : "Προτιμώμενη", +"label.presetup" : "Προρύθμιση", +"label.prev" : "Προηγούμενο", +"label.previous" : "Προηγούμενη", +"label.primary" : "Πρωτοβάθμια", +"label.primary.network" : "Πρωτεύον δίκτυο", +"label.primary.storage" : "Κύριος χώρος αποθήκευσης", +"label.primary.storage.allocated" : "Εκχωρήθηκε κύριος χώρος αποθήκευσης", +"label.primary.storage.count" : "Κύριοι χώροι συγκέντρωσης αποθήκευσης", +"label.primary.storage.used" : "Χρησιμοποιείται κύριος χώρος αποθήκευσης", +"label.primarystoragelimit" : "Όρια κύριας αποθήκευσης (GiB)", +"label.primarystoragetotal" : "Κύριος χώρος αποθήκευσης", +"label.private.gateway" : "Ιδιωτική πύλη", +"label.private.interface" : "Ιδιωτική διασύνδεση", +"label.private.ip.range" : "Ιδιωτική περιοχή IP", +"label.private.ips" : "Ιδιωτικές διευθύνσεις IP", +"label.private.registry" : "Ιδιωτικό μητρώο", +"label.private.zone" : "Ιδιωτική Ζώνη", +"label.privateinterface" : "Ιδιωτική διασύνδεση", +"label.privateip" : "Ιδιωτική διεύθυνση IP", +"label.privatekey" : "Ιδιωτικό κλειδί", +"label.privatekey.password" : "Κωδικός πρόσβασης ιδιωτικού κλειδιού", +"label.privatenetwork" : "Ιδιωτικό δίκτυο", +"label.privateport" : "Ιδιωτική θύρα", +"label.profiledn" : "Συσχετισμένο προφίλ", +"label.profilename" : "Προφίλ", +"label.project" : "Έργο", +"label.project.dashboard" : "Πίνακας εργαλείων έργου", +"label.project.ids" : "Τα id έργου", +"label.project.invitation" : "Προσκλήσεις έργου", +"label.project.invite" : "Πρόσκληση σε έργο", +"label.project.name" : "Όνομα έργου", +"label.project.owner" : "Κάτοχοι έργου", +"label.project.role" : "Ρόλος έργου", +"label.project.role.permissions" : "Δικαιώματα ρόλου έργου", +"label.project.roles" : "Ρόλοι έργου", +"label.project.view" : "Προβολή έργου", +"label.projectaccountname" : "Όνομα λογαριασμού έργου", +"label.projectid" : "Αναγνωριστικό έργου", +"label.projectlimit" : "Όρια έργου", +"label.projectname" : "Έργο", +"label.projects" : "Έργα", +"label.promiscuousmode" : "Μεικτή λειτουργία", +"label.property" : "Ιδιότητα", +"label.protocol" : "Πρωτόκολλο", +"label.protocol.number" : "Αριθμός πρωτοκόλλου", +"label.protocolnumber" : "#Πρωτόκολλο", +"label.provider" : "Πάροχος", +"label.providername" : "Πάροχος", +"label.providers" : "Παρόχους", +"label.provisioning" : "Διάταξη", +"label.provisioningtype" : "Τύπος διάταξης", +"label.provisioningtype.fat" : "Διάταξη Fat", +"label.provisioningtype.sparse" : "Διάταξη sparse", +"label.provisioningtype.thin" : "thin Διάταξη", +"label.public.interface" : "Δημόσια διασύνδεση", +"label.public.ip" : "Δημόσια διεύθυνση IP", +"label.public.ip.addresses" : "Δημόσιες διευθύνσεις IP", +"label.public.ips" : "Δημόσιες διευθύνσεις IP", +"label.public.lb" : "Δημόσια LB", +"label.public.load.balancer.provider" : "Υπηρεσία παροχής δημόσιου εξισορρόπησης φόρτου", +"label.public.network" : "Δημόσιο δίκτυο", +"label.public.traffic" : "Δημόσια κίνηση", +"label.public.zone" : "Δημόσια Ζώνη", +"label.publicinterface" : "Δημόσια διασύνδεση", +"label.publicip" : "Διεύθυνση IP", +"label.publickey" : "Δημόσιο κλειδί", +"label.publicnetwork" : "Δημόσιο δίκτυο", +"label.publicport" : "Δημόσιa θύρα", +"label.purpose" : "Σκοπός", +"label.pxe.server.type" : "Τύπος διακομιστή Pxe", +"label.qostype" : "Τύπος QoS", +"label.quickview" : "Γρήγορη προβολή", +"label.quiescevm" : "Εικονική μηχανή Quiesce", +"label.quiettime" : "Ώρα ηρεμίας (σε δευτερόλεπτο)", +"label.quota" : "Ποσόστωση", +"label.quota.add.credits" : "Προσθήκη μονάδων", +"label.quota.configuration" : "Ρύθμιση παραμέτρων ορίου δίσκου", +"label.quota.configure" : "Ρύθμιση παραμέτρων ορίου", +"label.quota.credits" : "Πιστώσεις", +"label.quota.dates" : "Ενημέρωση ημερομηνιών", +"label.quota.description" : "Περιγραφή ορίου μεγέθους", +"label.quota.email.edit" : "Επεξεργασία προτύπου ηλεκτρονικού ταχυδρομείου", +"label.quota.enddate" : "Ημερομηνία λήξης", +"label.quota.endquota" : "Όριο τέλους", +"label.quota.enforce" : "Επιβολή ορίου μεγέθους", +"label.quota.fullsummary" : "Όλοι οι λογαριασμοί", +"label.quota.remove" : "Κατάργηση ορίου μεγέθους", +"label.quota.startdate" : "Ημερομηνία έναρξης", +"label.quota.startquota" : "Έναρξη ορίου", +"label.quota.statement" : "Δήλωση", +"label.quota.statement.balance" : "Υπόλοιπο ποσόστωσης", +"label.quota.statement.bydates" : "Δήλωση", +"label.quota.statement.quota" : "Χρήση ορίου δίσκου", +"label.quota.statement.tariff" : "Tariff ποσόστωσης", +"label.quota.tariff" : "Tariff", +"label.quota.tariff.edit" : "Επεξεργασία τιμολογίου", +"label.quota.tariff.effectivedate" : "Ημερομηνία έναρξης ισχύος", +"label.quota.total" : "Σύνολο", +"label.quota.totalusage" : "Συνολική χρήση", +"label.quota.type.name" : "Τύπος χρήσης", +"label.quota.type.unit" : "Μονάδα χρήσης", +"label.quota.usage" : "Κατανάλωση ποσοστώσεων", +"label.quota.value" : "Τιμή ορίου δίσκου", +"label.quota_enforce" : "Επιβολή ορίου μεγέθους", +"label.rados.monitor" : "Οθόνη RADOS", +"label.rados.pool" : "Πισίνα RADOS", +"label.rados.secret" : "RADOS Μυστικό", +"label.rados.user" : "Χρήστης RADOS", +"label.ram" : "Ram", +"label.rbd" : "Rbd", +"label.rbdid" : "Χρήστης Cephx", +"label.rbdmonitor" : "Οθόνη Ceph", +"label.rbdpool" : "Πισίνα Ceph", +"label.rbdsecret" : "Cephx μυστικό", +"label.read" : "Διαβάστε", +"label.read.io" : "Ανάγνωση (IO)", +"label.readonly" : "Μόνο για ανάγνωση", +"label.reason" : "Λόγο", +"label.reboot" : "Επανεκκίνηση", +"label.receivedbytes" : "Byte που λήφθηκαν", +"label.recent.errors" : "Πρόσφατα σφάλματα", +"label.recover.vm" : "Ανάκτηση εικονικής μηχανής", +"label.redundantrouter" : "Εφεδρικός δρομολογητής", +"label.redundantrouterstate" : "Περιττή κατάσταση", +"label.redundantstate" : "Περιττή κατάσταση", +"label.redundantvpcrouter" : "Πλεονάζον VPC", +"label.reenterpassword" : "Επανάληψη εισαγωγής κωδικού πρόσβασης", +"label.refresh" : "Ανανέωση", +"label.refresh.blades" : "Ανανέωση Blades", +"label.region" : "Περιοχή", +"label.region.details" : "Λεπτομέρειες περιοχής", +"label.register.template" : "Πρότυπο καταχώρησης", +"label.reinstall.vm" : "Επανεγκατάσταση εικονικής μηχανής", +"label.reject" : "Απορρίψει", +"label.related" : "Σχετικές", +"label.relationaloperator" : "Φορέα", +"label.release" : "Αποδέσμευση", +"label.release.account" : "Αποδέσμευση από λογαριασμό", +"label.release.dedicated.cluster" : "Έκδοση αποκλειστικού ομοταξίας", +"label.release.dedicated.host" : "Αποδέσμευση αποκλειστικού κεντρικού υπολογιστή", +"label.release.dedicated.pod" : "Αποδέσμευση αποκλειστικής υποομάδας (pod)", +"label.release.dedicated.vlan.range" : "Έκδοση αποκλειστικής σειράς VLAN", +"label.release.dedicated.zone" : "Έκδοση αποκλειστικής ζώνης", +"label.releasing.ip" : "Αποδέσμευση IP", +"label.remind.later" : "Θύμισέ μου αργότερα", +"label.remove" : "Κατάργηση", +"label.remove.acl" : "Κατάργηση ACL", +"label.remove.egress.rule" : "Κατάργηση κανόνα εξόδου", +"label.remove.from.load.balancer" : "Κατάργηση εικονική μηχανής από την εξισορρόπηση φόρτου", +"label.remove.ingress.rule" : "Κατάργηση κανόνα εισόδου", +"label.remove.ip.range" : "Κατάργηση περιοχής IP", +"label.remove.ldap" : "Κατάργηση LDAP", +"label.remove.management.ip.range" : "Κατάργηση περιοχής IP διαχείρισης", +"label.remove.network.offering" : "Κατάργηση προσφοράς υπηρεσίας δικτύου", +"label.remove.pf" : "Κατάργηση κανόνα προώθησης θυρών", +"label.remove.project.account" : "Κατάργηση λογαριασμού από το έργο", +"label.remove.project.role" : "Κατάργηση ρόλου έργου", +"label.remove.project.user" : "Κατάργηση χρήστη από το έργο", +"label.remove.region" : "Κατάργηση περιοχής", +"label.remove.rule" : "Κατάργηση κανόνα", +"label.remove.ssh.key.pair" : "Κατάργηση ζεύγους πλήκτρων SSH", +"label.remove.static.nat.rule" : "Κατάργηση στατικού κανόνα NAT", +"label.remove.static.route" : "Κατάργηση στατικής διαδρομής", +"label.remove.this.physical.network" : "Κατάργηση αυτού του φυσικού δικτύου", +"label.remove.tier" : "Κατάργηση βαθμίδας", +"label.remove.vm.from.lb" : "Κατάργηση εικονικής μηχανής από τον κανόνα εξισορρόπησης φόρτου", +"label.remove.vm.load.balancer" : "Κατάργηση εικονικής μηχανής από την εξισορρόπηση φόρτου", +"label.remove.vmware.datacenter" : "Κατάργηση κέντρου δεδομένων VMware", +"label.remove.vpc" : "Κατάργηση VPC", +"label.remove.vpc.offering" : "Κατάργηση προσφοράς υπηρεσίας VPC", +"label.removing" : "Αφαίρεση", +"label.removing.user" : "Κατάργηση χρήστη", +"label.replace.acl" : "Αντικατάσταση ACL", +"label.replace.acl.list" : "Αντικατάσταση λίστας ACL", +"label.report.bug" : "Θέμα αναφοράς", +"label.required" : "Απαιτείται", +"label.requireshvm" : "HVM", +"label.requiresupgrade" : "Απαιτεί αναβάθμιση", +"label.reserved.system.gateway" : "Δεσμευμένη πύλη συστήματος", +"label.reserved.system.ip" : "Δεσμευμένο IP συστήματος", +"label.reserved.system.netmask" : "Δεσμευμένη μάσκα δικτύου συστήματος", +"label.reservediprange" : "Δεσμευμένη περιοχή IP", +"label.reservedsystemendip" : "Τερματισμός δεσμευμένου συστήματος IP", +"label.reservedsystemgateway" : "Δεσμευμένη πύλη συστήματος", +"label.reservedsystemnetmask" : "Δεσμευμένη μάσκα δικτύου συστήματος", +"label.reservedsystemstartip" : "Έναρξη δεσμευμένης IP συστήματος", +"label.reset" : "Επαναφορά", +"label.reset.ssh.key.pair" : "Επαναφορά ζεύγους κλειδιών SSH", +"label.reset.ssh.key.pair.on.vm" : "Επαναφορά ζεύγους κλειδιών SSH σε εικονική μηχανή", +"label.reset.vpn.connection" : "Επαναφορά σύνδεσης VPN", +"label.resetvm" : "Επαναφορά εικονικής μηχανής", +"label.resource" : "Πόρων", +"label.resource.limit.exceeded" : "Υπέρβαση ορίου πόρων", +"label.resource.limits" : "Όρια πόρων", +"label.resource.name" : "Όνομα πόρου", +"label.resourceid" : "Αναγνωριστικό πόρου", +"label.resourcename" : "Όνομα πόρου", +"label.resources" : "Πόρους", +"label.resourcestate" : "Κατάσταση πόρου", +"label.response.timeout.in.sec" : "Χρονικό όριο απόκρισης (σε δευτερόλεπτα)", +"label.restart.network" : "Επανεκκίνηση δικτύου", +"label.restart.vpc" : "Επανεκκίνηση VPC", +"label.restartrequired" : "Απαιτείται επανεκκίνηση", +"label.restore" : "Επαναφορά", +"label.restore.volume.attach" : "Επαναφορά τόμου και επισύναψη", +"label.retry.interval" : "Διάστημα επανάληψης", +"label.review" : "Αναθεώρηση", +"label.revoke.project.invite" : "Ανάκληση πρόσκλησης", +"label.revokeinvitationconfirm" : "Επιβεβαιώστε ότι θέλετε να ανακαλέσετε αυτήν την πρόσκληση;", +"label.role" : "Ρόλο", +"label.rolename" : "Ρόλο", +"label.roles" : "Ρόλους", +"label.roletype" : "Τύπος ρόλου", +"label.rootdisksize" : "Μέγεθος ριζικού δίσκου (GB)", +"label.root.certificate" : "Πιστοποιητικό ρίζας", +"label.root.disk.offering" : "Προσφορά ριζικού δίσκου", +"label.root.disk.size" : "Μέγεθος ριζικού δίσκου (GB)", +"label.rootdiskcontrollertype" : "Ελεγκτής ριζικού δίσκου", +"label.rootdiskcontrollertypekvm" : "Ελεγκτής ριζικού δίσκου", +"label.routerip" : "IPv4 διεύθυνση του δρομολογητή στο κοινόχρηστο δίκτυο ", +"label.routeripv6" : "IPv6 διεύθυνση του δρομολογητή στο κοινόχρηστο δίκτυο", +"label.router.health.check.last.updated" : "Τελευταία ενημέρωση", +"label.router.health.check.name" : "Έλεγχος ονόματος", +"label.router.health.check.success" : "Επιτυχία", +"label.router.health.checks" : "Υγειονομικοί έλεγχοι", +"label.router.vm.scaled.up" : "Κλίμακα vm δρομολογητή", +"label.routercount" : "Σύνολο εικονικών δρομολογητών", +"label.routerrequiresupgrade" : "Απαιτείται αναβάθμιση", +"label.routertype" : "Πληκτρολογήστε", +"label.routing.host" : "Κεντρικός υπολογιστής δρομολόγησης", +"label.rule" : "Κανόνα", +"label.rule.number" : "Αριθμός κανόνα", +"label.rules" : "Κανόνες", +"label.rules.file" : "Αρχείο κανόνων", +"label.rules.file.to.import" : "Αρχείο κανόνων σε μορφή CSV για εισαγωγή", +"label.rules.file.import.description" : "Κάντε κλικ ή σύρετε τις ρυθμίσεις κανόνα CSV για εισαγωγή", +"label.run.proxy.locally" : "Τοπική εκτέλεση διακομιστή μεσολάβησης", +"label.running" : "Εκτέλεση VM", +"label.s3.access.key" : "Κλειδί πρόσβασης", +"label.s3.bucket" : "Κουβά", +"label.s3.connection.timeout" : "Χρονικό όριο σύνδεσης", +"label.s3.endpoint" : "Τελικό σημείο", +"label.s3.max.error.retry" : "Μέγιστη επανάληψη σφάλματος", +"label.s3.nfs.path" : "Διαδρομή S3 NFS", +"label.s3.nfs.server" : "Διακομιστής S3 NFS", +"label.s3.secret.key" : "Μυστικό κλειδί", +"label.s3.socket.timeout" : "Χρονικό όριο υποδοχής", +"label.s3.use.https" : "Χρήση HTTPS", +"label.saml.disable" : "Απενεργοποίηση SAML", +"label.saml.enable" : "Ενεργοποίηση SAML", +"label.samlenable" : "Εξουσιοδότηση SAML SSO", +"label.samlentity" : "Υπηρεσία παροχής ταυτότητας", +"label.saturday" : "Σάββατο", +"label.save" : "Αποθήκευση", +"label.save.and.continue" : "Αποθήκευση και συνέχιση", +"label.save.changes" : "Αποθήκευση αλλαγών", +"label.save.new.rule" : "Αποθήκευση νέου κανόνα", +"label.saving.processing" : "Εξοικονόμηση....", +"label.scale.vm" : "Κλίμακα VM", +"label.scale.up.policy" : "ΚΛΙΜΆΚΩΣΗ POLICY", +"label.scaledown.policy" : "αρνητική κλιμάκωση policy ", +"label.scaleup.policy" : "θετική κλιμάκωση policy", +"label.schedule" : "Πρόγραμμα", +"label.scheduled.backups" : "Προγραμματισμένα αντίγραφα ασφαλείας", +"label.scheduled.snapshots" : "Προγραμματισμένα στιγμιότυπα", +"label.scope" : "Πεδίο εφαρμογής", +"label.search" : "Αναζήτηση", +"label.secondary.isolated.vlan.type.isolated" : "Απομονωμένες", +"label.secondary.isolated.vlan.type.promiscuous" : "Ανομοιογενές", +"label.secondary.staging.store" : "Δευτερεύων χώρος αποθήκευσης ανασυγκρότησης", +"label.secondary.staging.store.details" : "Λεπτομέρειες δευτερεύοντος χώρου αποθήκευσης ανασυγκρότησης", +"label.secondary.storage" : "Δευτερεύουσα αποθήκευση", +"label.secondary.storage.count" : "Δευτερεύοντες χώροι αποθήκευσης", +"label.secondary.storage.details" : "Λεπτομέρειες δευτερεύουσας αποθήκευσης", +"label.secondary.storage.vm" : "Δευτερεύων χώρος αποθήκευσης vm", +"label.secondary.used" : "Δευτερεύων χώρος αποθήκευσης που χρησιμοποιείται", +"label.secondaryips" : "Δευτερεύουσες διευθύνσεις IP", +"label.secondarystoragelimit" : "Όρια δευτερεύουσας αποθήκευσης (GiB)", +"label.secretkey" : "Μυστικό κλειδί", +"label.secured" : "Ασφαλές", +"label.security.group.name" : "Όνομα ομάδας ασφαλείας", +"label.security.groups" : "Ομάδες ασφαλείας", +"label.security.groups.enabled" : "Ενεργοποιημένες ομάδες ασφαλείας", +"label.securitygroup" : "Ομάδα ασφαλείας", +"label.securitygroupenabled" : "Ενεργοποιημένες ομάδες ασφαλείας", +"label.securitygroups" : "Ομάδες ασφαλείας", +"label.securitygroupsenabled" : "Ενεργοποιημένες ομάδες ασφαλείας", +"label.select" : "Επιλέξτε", +"label.select-view" : "Επιλογή προβολής", +"label.select.a.zone" : "Επιλογή ζώνης", +"label.select.deployment.infrastructure" : "Επιλογή υποδομής ανάπτυξης", +"label.select.host" : "Επιλογή κεντρικού υπολογιστή", +"label.select.instance" : "Επιλογή εικονική μηχανής", +"label.select.instance.to.attach.volume.to" : "Επιλογή εικονική μηχανής για επισύναψη τόμου σε", +"label.select.iso.or.template" : "Επιλογή ISO ή προτύπου", +"label.select.offering" : "Επιλογή προσφοράς υπηρεσίας", +"label.select.project" : "Επιλογή έργου", +"label.select.projects" : "Επιλογή έργων", +"label.select.region" : "Επιλογή περιοχής", +"label.select.tier" : "Επιλογή βαθμίδας", +"label.select.vm.for.static.nat" : "Επιλογή εικονικής μηχανής για στατικό NAT", +"label.select.zones" : "Επιλογή ζωνών", +"label.self" : "Εξόρυξη", +"label.selfexecutable" : "Self", +"label.semanticversion" : "Σημασιολογική έκδοση", +"label.sent" : "Ημερομηνία", +"label.sentbytes" : "Byte που στάλθηκαν", +"label.server" : "Διακομιστής", +"label.server.certificate" : "Πιστοποιητικό διακομιστή", +"label.service.connectivity.distributedroutercapabilitycheckbox" : "Κατανεμημένος δρομολογητής", +"label.service.connectivity.regionlevelvpccapabilitycheckbox" : "Επίπεδο περιοχής VPC", +"label.service.lb.elasticlbcheckbox" : "Ελαστική LB", +"label.service.lb.inlinemodedropdown" : "Λειτουργία", +"label.service.lb.lbisolationdropdown" : "Απομόνωση LB", +"label.service.lb.netscaler.servicepackages" : "Πακέτα υπηρεσιών netsccaler", +"label.service.lb.netscaler.servicepackages.description" : "Περιγραφή πακέτου εξυπηρέτησης", +"label.service.offering" : "Προσφορά Υπηρεσιών", +"label.service.offering.details" : "Υπηρεσίες που προσφέρουν λεπτομέρειες", +"label.service.sourcenat.redundantroutercapabilitycheckbox" : "Δυνατότητα εφεδρικού δρομολογητή", +"label.service.state" : "Κατάσταση υπηρεσίας", +"label.service.staticnat.associatepublicip" : "Συσχέτιση δημόσιας διεύθυνσης IP", +"label.service.staticnat.elasticipcheckbox" : "Ελαστική IP", +"label.servicecapabilities" : "Δυνατότητες υπηρεσίας", +"label.servicelist" : "Υπηρεσίες", +"label.serviceofferingid" : "Προσφορά υπολογισμού", +"label.serviceofferingname" : "Προσφορά υπολογισμού", +"label.session.expired" : "Η περίοδος λειτουργίας έληξε", +"label.set.default.nic" : "Ορισμός προεπιλεγμένου NIC", +"label.set.reservation" : "Ορισμός κράτησης", +"label.set.reservation.desc" : "Προαιρετικό: Υποδείξτε τον λογαριασμό που θα συσχετιστεί με αυτό το εύρος IP.

Συστημικά VMs: Ενεργοποίηση της αντιστοίχησης δημοσίου εύρους IP για SSVM και CPVM, πεδίο λογαριασμού απενεργοποιημένο. Οι κανόνες αντιστοίχησης καθορίζονται στο system.vm.public.ip.reservation.mode.strictness'", +"label.set.up.zone.type" : "Ρύθμιση τύπου ζώνης", +"label.setting" : "Ρύθμιση", +"label.settings" : "Ρυθμίσεις", +"label.setup" : "Εγκατάστασης", +"label.setup.network" : "Ρύθμιση δικτύου", +"label.setup.zone" : "Ρύθμιση ζώνης", +"label.shared" : "Κοινόχρηστο", +"label.sharedexecutable" : "Κοινόχρηστο", +"label.sharedmountpoint" : "Κοινόχρηστο μέσο", +"label.sharewith" : "Κοινή χρήση με", +"label.show.ingress.rule" : "Εμφάνιση κανόνα εισόδου", +"label.showing" : "Προβολή", +"label.shrinkok" : "Συρρίκνωση OK", +"label.shutdown.provider" : "Υπηρεσία παροχής τερματισμού", +"label.simplified.chinese.keyboard" : "Απλοποιημένο πληκτρολόγιο στα κινέζικα", +"label.s2scustomergatewayid" : "Αναγνωριστικό πύλης πελάτη τοποθεσίας σε τοποθεσία", +"label.s2svpngatewayid" : "Αναγνωριστικό πύλης VPN τοποθεσίας σε τοποθεσία", +"label.site.to.site.vpn" : "VPN από τοποθεσία σε τοποθεσία", +"label.site.to.site.vpn.connections" : "Συνδέσεις VPN από τοποθεσία σε τοποθεσία", +"label.size" : "Μέγεθος", +"label.sizegb" : "Μέγεθος", +"label.skip.guide" : "Έχω χρησιμοποιήσει CloudStack πριν, παραλείψτε αυτόν τον οδηγό", +"label.smb.domain" : "Τομέας SMB", +"label.smb.password" : "Κωδικός πρόσβασης SMB", +"label.smb.username" : "Όνομα χρήστη SMB", +"label.smbdomain" : "Τομέας SMB", +"label.smbpassword" : "Κωδικός πρόσβασης SMB", +"label.smbusername" : "Όνομα χρήστη SMB", +"label.snapshot" : "Στιγμιότυπο", +"label.snapshot.name" : "Όνομα στιγμιότυπου", +"label.snapshot.schedule" : "Ρύθμιση επαναλαμβανόμενου στιγμιότυπου", +"label.snapshotlimit" : "Όρια στιγμιοτύπων", +"label.snapshotmemory" : "Μνήμη στιγμιότυπου", +"label.snapshots" : "Στιγμιότυπα", +"label.snmpcommunity" : "Κοινότητα SNMP", +"label.snmpport" : "Θύρα SNMP", +"label.sockettimeout" : "Χρονικό όριο υποδοχής", +"label.source.based" : "Βάσει πηγής", +"label.source.nat.supported" : "Υποστηρίζεται από το SourceNAT", +"label.sourcecidr" : "Πηγή CIDR", +"label.sourceipaddress" : "Πηγαία Διεύθυνση IP ", +"label.sourcenat" : "Πηγαίο NAT", +"label.sourcenatsupported" : "Η προέλευση NAT υποστηρίζεται", +"label.sourcenattype" : "Υποστηριζόμενος τύπος πηγαίου NAT ", +"label.sourceport" : "Θύρα πηγαία", +"label.specify.vxlan" : "Καθορισμός VXLAN", +"label.specifyipranges" : "Καθορισμός περιοχών IP", +"label.specifyvlan" : "Καθορισμός VLAN", +"label.splitconnections" : "Διαχωρισμός συνδέσεων", +"label.sr.name" : "Ετικέτα ονόματος SR", +"label.srx" : "SRX", +"label.srx.details" : "Λεπτομέρειες SRX", +"label.srx.firewall" : "Τείχος προστασίας Juniper SRX", +"label.ssh.key.pair.details" : "Λεπτομέρειες ζεύγους κλειδιών SSH", +"label.ssh.key.pairs" : "Ζεύγη πλήκτρων SSH", +"label.ssh.port" : "Θύρα SSH", +"label.sshkeypair" : "Νέο ζεύγος κλειδιών SSH", +"label.sshkeypairs" : "SSH ζεύγη κλειδιών", +"label.sslcertificates" : "Πιστοποιητικά SSL", +"label.standard.us.keyboard" : "Τυπικό πληκτρολόγιο (Η.Π.Α.)", +"label.start" : "Ξεκινήσετε", +"label.start.ip" : "Έναρξη IP", +"label.start.lb.vm" : "Έναρξη εικονικής μηχανής LB", +"label.start.reserved.system.ip" : "Έναρξη δεσμευμένης IP συστήματος", +"label.start.rolling.maintenance" : "Έναρξη συντήρησης κύλισης", +"label.start.rolling.maintenance.payload" : "Ωφέλιμο φορτίο", +"label.start.vlan" : "Εκκίνηση VLAN", +"label.start.vxlan" : "Εκκίνηση VXLAN", +"label.startdate" : "Κατά ημερομηνία (έναρξη)", +"label.startip" : "Έναρξη IP", +"label.startipv4" : "Εκκίνηση IP του IPv4", +"label.startipv6" : "Εκκίνηση IP του IPv6", +"label.startport" : "θύρα έναρξης", +"label.startquota" : "Τιμή ορίου δίσκου", +"label.state" : "Κατάσταση", +"label.static.nat.enabled" : "Ενεργοποίηση στατικού NAT", +"label.static.nat.to" : "Στατικό NAT για να", +"label.static.nat.vm.details" : "Στατικές λεπτομέρειες vm NAT", +"label.static.routes" : "Στατικές διαδρομές", +"label.statistics" : "Στατιστικές", +"label.status" : "Κατάσταση", +"label.step.1" : "Βήμα 1", +"label.step.1.title" : "Βήμα 1: Επιλογή προτύπου", +"label.step.2" : "Βήμα 2", +"label.step.2.title" : "Βήμα 2: Επιλογή προσφοράς", +"label.step.3" : "Βήμα 3", +"label.step.3.title" : "Βήμα 3: Επιλογή προσφοράς δίσκου", +"label.step.4" : "Βήμα 4", +"label.step.4.title" : "Βήμα 4: Δίκτυο", +"label.step.5" : "Βήμα 5", +"label.step.5.title" : "Βήμα 5: Επιβεβαίωση", +"label.stickiness.method" : "Μέθοδος Stickiness", +"label.sticky.cookie-name" : "Όνομα cookie", +"label.sticky.expire" : "Λήγει", +"label.sticky.holdtime" : "Χρόνος αναμονής", +"label.sticky.indirect" : "Έμμεση", +"label.sticky.length" : "Μήκος", +"label.sticky.mode" : "Λειτουργία", +"label.sticky.name" : "Sticky όνομα", +"label.sticky.nocache" : "Δεν υπάρχει cache", +"label.sticky.postonly" : "Δημοσίευση μόνο", +"label.sticky.prefix" : "Πρόθεμα", +"label.sticky.request-learn" : "Αίτηση εκμάθησης", +"label.sticky.tablesize" : "Μέγεθος πίνακα", +"label.stop" : "Σταμάτα", +"label.stop.lb.vm" : "Διακοπή εικονικής μηχανής LB", +"label.stopped" : "Σταματημένοι VM", +"label.storage" : "Αποθήκευσης", +"label.storage.tags" : "Ετικέτες αποθήκευσης", +"label.storage.traffic" : "Κίνηση αποθήκευσης", +"label.storageid" : "Κύριος χώρος αποθήκευσης", +"label.storage.migration.required" : "Η μετεγκατάσταση αποθηκευτικού χώρου είναι απαραίτητη", +"label.storagemotionenabled" : "Ενεργοποίηση κίνησης αποθήκευσης", +"label.storagepolicy" : "Πολιτική αποθήκευσης", +"label.storagepool" : "Χώρος αποθήκευσης", +"label.storagetags" : "Ετικέτες αποθήκευσης", +"label.storagetype" : "Τύπος αποθήκευσης", +"label.strict" : "Αυστηρή", +"label.subdomainaccess" : "Πρόσβαση δευτερεύοντος τομέα", +"label.submit" : "Υποβάλει", +"label.submitted.by" : "[Κατατέθηκε απο: ]", +"label.succeeded" : "Πέτυχε", +"label.success" : "Επιτυχία", +"label.success.set" : "Ο ορισμός ολοκληρώθηκε με επιτυχία", +"label.success.updated" : "Η ενημέρωση ολοκληρώθηκε με επιτυχία", +"label.suitability" : "Καταλληλότητα", +"label.suitable" : "Κατάλληλο", +"label.summary" : "Περίληψη", +"label.sunday" : "Κυριακή", +"label.supportedservices" : "Υποστηριζόμενες υπηρεσίες", +"label.supportsha" : "Υποστηρίζει HA", +"label.supportspublicaccess" : "Υποστηρίζει δημόσια πρόσβαση", +"label.supportsregionlevelvpc" : "Υποστηρίζει VPC επιπέδου περιοχής", +"label.supportsstrechedl2subnet" : "Υποστηρίζει υποδίκτυο Streched L2", +"label.suspend.project" : "Αναστολή έργου", +"label.switch.type" : "Τύπος εναλλάκτη", +"label.system.capacity" : "Χωρητικότητα συστήματος", +"label.system.offering" : "Προσφορά συστήματος", +"label.system.offering.for.router" : "Προσφορά συστήματος για δρομολογητή", +"label.system.offerings" : "προσφορές υπηρεσίας συστημάτων", +"label.system.service.offering" : "Προσφορά υπηρεσιών συστήματος", +"label.system.service.offering.details" : "Λεπτομέρειες προσφοράς υπηρεσίας υπηρεσιών συστήματος", +"label.system.vm" : "Εικονική μηχανή συστήματος", +"label.system.vm.details" : "Λεπτομέρειες vm συστήματος", +"label.system.vm.scaled.up" : "Κλιμάκωση εικονικής μηχανής συστήματος", +"label.system.vms" : "VM συστήματος", +"label.system.wide.capacity" : "Χωρητικότητα σε όλο το σύστημα", +"label.systemvmtype" : "Τύπος εικονικής μηχανής συστήματος", +"label.tag.key" : "Πλήκτρο ετικέτας", +"label.tag.value" : "Τιμή ετικέτας", +"label.tagged" : "Με ετικέτα", +"label.tags" : "Ετικέτες", +"label.target.iqn" : "Στόχος IQN", +"label.tariffactions" : "Ενέργειες", +"label.tariffvalue" : "Δασμολογική Αξία", +"label.task.completed" : "Η εργασία ολοκληρώθηκε", +"label.tcp" : "TCP", +"label.tcp.proxy" : "Διακομιστής μεσολάβησης TCP", +"label.template" : "Επιλογή προτύπου", +"label.templatebody" : "Σώμα", +"label.templatedn" : "Επιλογή προτύπου", +"label.templatefileupload" : "Τοπικό αρχείο", +"label.templateid" : "Επιλογή προτύπου", +"label.templateiso" : "Πρότυπο/ISO", +"label.templatelimit" : "Όρια προτύπων", +"label.templatename" : "Πρότυπο", +"label.templatenames" : "Πρότυπο", +"label.templates" : "Πρότυπα", +"label.templatesubject" : "Θέμα", +"label.templatetotal" : "Πρότυπο", +"label.templatetype" : "Τύπος προτύπου", +"label.tftp.dir" : "Κατάλογος TFTP", +"label.tftpdir" : "Ριζικός κατάλογος Tftp", +"label.theme.default" : "Προεπιλεγμένο θέμα", +"label.theme.grey" : "Προσαρμοσμένο - Γκρι", +"label.theme.lightblue" : "Προσαρμοσμένο - Ανοιχτό Μπλε", +"label.threshold" : "Όριο", +"label.thursday" : "Πέμπτη", +"label.tier.details" : "Λεπτομέρειες βαθμίδας", +"label.tiername" : "Βαθμίδα", +"label.time" : "Ώρα", +"label.time.colon" : "Ωρα:", +"label.timeout" : "Χρονικό όριο", +"label.timeout.in.second " : " Χρονικό όριο (δευτερόλεπτα)", +"label.timezone" : "Ζώνη ώρας", +"label.timezone.colon" : "Ζώνη ώρας:", +"label.to" : "Να", +"label.token" : "Διακριτικό", +"label.token.for.dashboard.login" : "Το διακριτικό για σύνδεση πίνακα εργαλείων μπορεί να ανακτηθεί χρησιμοποιώντας την ακόλουθη εντολή", +"label.total" : "Σύνολο", +"label.total.hosts" : "Σύνολο κεντρικών υπολογιστών", +"label.total.memory" : "Συνολική μνήμη", +"label.total.network" : "Σύνολο δικτύων", +"label.total.storage" : "Συνολικός χώρος αποθήκευσης", +"label.total.vms" : "Σύνολο VM", +"label.total.volume" : "Σύνολο τόμων", +"label.totalcpu" : "Σύνολο CPU", +"label.traffic.label" : "Ετικέτα κίνησης", +"label.traffic.types" : "Τύποι κίνησης", +"label.traffictype" : "Τύπος κίνησης", +"label.transportzoneuuid" : "Ζώνη μεταφοράς Uuid", +"label.try.again" : "Δοκίμασε ξανά", +"label.tuesday" : "Τρίτη", +"label.type" : "Πληκτρολογήστε", +"label.type.id" : "Αναγνωριστικό τύπου", +"label.ucs" : "UCS", +"label.udp" : "UDP", +"label.uk.keyboard" : "Πληκτρολόγιο Ηνωμένου Βασιλείου", +"label.unauthorized" : "Μη εξουσιοδοτημένη", +"label.unavailable" : "Διαθέσιμη", +"label.unhealthy.threshold" : "Μη υγιές όριο", +"label.unique.name.tier" : "Ένα μοναδικό όνομα της βαθμίδας", +"label.unit" : "Μονάδα χρήσης", +"label.unknown" : "Άγνωστο", +"label.unlimited" : "Απεριόριστη", +"label.untagged" : "Χωρίς tag", +"label.update.instance.group" : "Ενημέρωση ομάδας εικονική μηχανής", +"label.update.physical.network" : "Ενημέρωση φυσικού δικτύου", +"label.update.project.resources" : "Ενημέρωση πόρων έργου", +"label.update.project.role" : "Ενημέρωση ρόλου έργου", +"label.update.ssl" : " Πιστοποιητικό SSL", +"label.update.ssl.cert" : " Πιστοποιητικό SSL", +"label.update.to" : "ενημερώθηκε σε", +"label.update.traffic.label" : "Ενημέρωση ετικετών κίνησης", +"label.update.vmware.datacenter" : "Ενημέρωση κέντρου δεδομένων VMware", +"label.updating" : "Ενημέρωση", +"label.upgrade.router.newer.template" : "Αναβάθμιση δρομολογητή για χρήση νεότερου προτύπου", +"label.upload" : "Φόρτωση", +"label.upload.from.local" : "Αποστολή από τοπικό", +"label.upload.iso.from.local" : "Αποστολή του ISO από την τοπική", +"label.upload.template.from.local" : "Αποστολή προτύπου από τοπικό", +"label.upload.volume" : "Αποστολή τόμου", +"label.upload.volume.from.local" : "Αποστολή τόμου από τοπικό", +"label.upload.volume.from.url" : "Αποστολή τόμου από τη διεύθυνση URL", +"label.url" : "Διεύθυνση url", +"label.usage.sanity.result" : "Αποτέλεσμα λογικής χρήσης", +"label.usage.server" : "Διακομιστής χρήσης", +"label.usageinterface" : "Διασύνδεση χρήσης", +"label.usagename" : "Τύπος χρήσης", +"label.usageunit" : "Μονάδα", +"label.use.local.timezone" : "Χρήση τοπικής ζώνης ώρας", +"label.use.kubectl.access.cluster" : "kubectl και kubeconfig αρχείο για πρόσβαση στο σύμπλεγμα", +"label.use.vm.ip" : "Χρήση VM IP:", +"label.use.vm.ips" : "Χρήση VM IPs", +"label.used" : "Χρησιμοποιείται", +"label.usehttps" : "Χρήση HTTPS", +"label.usenewdiskoffering" : "Αντικατάσταση προσφοράς υπηρεσίας δίσκου;", +"label.user" : "Χρήστη", +"label.user.as.admin" : "Ορισμός χρήστη ως διαχειριστή έργου", +"label.user.conflict" : "Σύγκρουση", +"label.user.details" : "Στοιχεία χρήστη", +"label.user.source" : "Πηγή", +"label.user.vm" : "VM χρήστη", +"label.userdata" : "Userdata", +"label.userdatal2" : "Δεδομένα χρήστη", +"label.username" : "Όνομα χρήστη", +"label.users" : "Χρήστες", +"label.usersource" : "Τύπος χρήστη", +"label.usevpc" : "VPC", +"label.using.cli" : "Χρήση CLI", +"label.utilization" : "Χρήση", +"label.uuid" : "Αναγνωριστικό", +"label.value" : "Τιμή", +"label.vcdcname" : "όνομα vCenter DC", +"label.vcenter" : "VMware Datacenter vCenter", +"label.vcenter.cluster" : "σύμπλεγμα vCenter", +"label.vcenter.datacenter" : "vCenter Datacenter", +"label.vcenter.datastore" : "vCenter Datastore", +"label.vcenter.host" : "Κεντρικός υπολογιστής vCenter", +"label.vcenter.password" : "Κωδικός πρόσβασης vCenter", +"label.vcenter.username" : "όνομα χρήστη vCenter", +"label.vcenterdatacenter" : "vCenter Datacenter", +"label.vcenterdatastore" : "vCenter Datastore", +"label.esx.host" : "Κεντρικός υπολογιστής ESX/ESXi", +"label.vcenterpassword" : "Κωδικός πρόσβασης vCenter", +"label.vcenterusername" : "όνομα χρήστη vCenter", +"label.vcipaddress" : "Διεύθυνση IP vCenter", +"label.vcsdeviceid" : "Αναγνωριστικό", +"label.version" : "Έκδοση", +"label.versions" : "Εκδόσεις", +"label.vgpu" : "VGPU", +"label.vgpu.max.resolution" : "Μέγιστη ανάλυση", +"label.vgpu.max.vgpu.per.gpu" : "vGPU ανά GPU", +"label.vgpu.remaining.capacity" : "Εναπομένουσα χωρητικότητα", +"label.vgpu.video.ram" : "Μνήμη RAM βίντεο", +"label.vgputype" : "τύπος vGPU", +"label.view" : "Δείτε", +"label.view.all" : "Προβολή όλων", +"label.view.console" : "Προβολή κονσόλας", +"label.view.more" : "Δείτε περισσότερα", +"label.view.secondary.ips" : "Προβολή δευτερευουσών IP", +"label.viewing" : "Προβολή", +"label.virtual.appliance" : "Εικονική συσκευή", +"label.virtual.appliance.details" : "Λεπτομέρειες εικονικής εφαρμογής", +"label.virtual.appliances" : "Εικονικές συσκευές", +"label.virtual.machine" : "Εικονική μηχανή", +"label.virtual.machines" : "Εικονικές μηχανές", +"label.virtual.network" : "Εικονικό δίκτυο", +"label.virtual.networking" : "Εικονική δικτύωση", +"label.virtual.routers" : "Εικονικοί δρομολογητές", +"label.virtual.routers.group.account" : "Εικονικοί δρομολογητές ομάδα κατά λογαριασμό", +"label.virtual.routers.group.cluster" : "Ομάδα εικονικών δρομολογητών κατά σύμπλεγμα", +"label.virtual.routers.group.pod" : "Εικονικοί δρομολογητές ανά υποομάδα (pod)", +"label.virtual.routers.group.zone" : "Εικονικοί δρομολογητές ομαδοποιούνται κατά ζώνη", +"label.virtualmachinedisplayname" : "Όνομα VM", +"label.virtualmachineid" : "Αναγνωριστικό εικονικής μηχανής", +"label.virtualmachinename" : "Όνομα VM", +"label.virtualsize" : "Εικονικό μέγεθος", +"label.vlan" : "VLAN/VNI", +"label.vlan.range" : "Περιοχή VLAN/VNI", +"label.vlan.range.details" : "Λεπτομέρειες εύρους VLAN", +"label.vlan.vni.ranges" : "Εύρος(ες) VLAN/VNI", +"label.vlanid" : "Αναγνωριστικό VLAN/VNI", +"label.vlanname" : "Vlan", +"label.vlanrange" : "Περιοχή VLAN/VNI", +"label.vm" : "Vm", +"label.vm.add" : "Προσθήκη εικονική μηχανής", +"label.vm.destroy" : "Καταστροφή", +"label.vm.password" : "Ο κωδικός πρόσβασης της εικονικής μηχανής είναι", +"label.vm.reboot" : "Επανεκκίνηση", +"label.vm.snapshots" : "Στιγμιότυπα VM", +"label.vm.start" : "Ξεκινήσετε", +"label.vm.stop" : "Σταμάτα", +"label.vmdisplayname" : "Εμφανιζόμενο όνομα VM", +"label.vmfs" : "VMFS", +"label.vmfs.datastore" : "Κατάστημα δεδομένων VMFS", +"label.vmipaddress" : "Διεύθυνση IP VM", +"label.vmlimit" : "Όρια εικονική μηχανής", +"label.vmname" : "Όνομα εικονικής μηχανής", +"label.vms" : "VMs", +"label.vms.in.tier" : "VM στη βαθμίδα", +"label.vmstate" : "Κατάσταση VM", +"label.vmtotal" : "Σύνολο VM", +"label.vmware.storage.policy" : "Πολιτική αποθήκευσης VMWare", +"label.vmwaredcid" : "Αναγνωριστικό Datacenter VMware", +"label.vmwaredcname" : "Όνομα Datacenter VMware", +"label.vmwaredcvcenter" : "VMware Datacenter vCenter", +"label.vmwarenetworklabel" : "Ετικέτα κίνησης VMware", +"label.vnmc" : "VNMC", +"label.vnmc.devices" : "Συσκευές VNMC", +"label.volgroup" : "Ομάδα τόμων", +"label.volume" : "Όγκο", +"label.volumeid" : "Όγκο", +"label.volume.details" : "Λεπτομέρειες τόμου", +"label.volume.empty" : "Δεν υπάρχουν τόμοι δεδομένων που να είναι συνδεδεμένοι σε αυτήν την εικονική μηχανή", +"label.volume.ids" : "Αναγνωριστικό τόμου", +"label.volume.migrated" : "Μετεγκατάσταση τόμου", +"label.volume.volumefileupload.description" : "Κάντε κλικ ή σύρετε το αρχείο σε αυτήν την περιοχή για αποστολή", +"label.volumechecksum" : "Άθροισμα ελέγχου MD5", +"label.volumechecksum.description" : "Χρήση του κατακερματισμού που δημιουργήσατε κατά την έναρξη της διαδικασίας αποστολής τόμου", +"label.volumefileupload" : "Τοπικό αρχείο", +"label.volumegroup" : "Ομάδα τόμων", +"label.volumeids" : "Τόμοι προς διαγραφή", +"label.volumelimit" : "Όρια τόμου", +"label.volumename" : "Όνομα τόμου", +"label.volumes" : "Τόμους", +"label.volumetotal" : "Όγκο", +"label.vpc" : "VPC", +"label.vpc.id" : "Αναγνωριστικό VPC", +"label.vpc.offering.access" : "VPC που προσφέρει την πρόσβαση", +"label.vpc.offering.details" : "VPC που προσφέρει τις λεπτομέρειες", +"label.vpc.offerings" : "προσφορές υπηρεσίας VPC", +"label.vpc.router.details" : "Λεπτομέρειες δρομολογητή VPC", +"label.vpc.virtual.router" : "Εικονικός δρομολογητής VPC", +"label.vpcid" : "VPC", +"label.vpclimit" : "Όρια VPC", +"label.vpcname" : "VPC", +"label.vpcoffering" : "Προσφορά υπηρεσίας VPC", +"label.vpcofferingid" : "Προσφορά υπηρεσίας VPC", +"label.vpctotal" : "Σύνολο VPC", +"label.vpn" : "VPN", +"label.vpn.connection" : "Σύνδεση VPN", +"label.vpn.gateway" : "Πύλη VPN", +"label.vpn.users" : "Χρήστες VPN", +"label.vpncustomergateway" : "Διεύθυνση IP της απομακρυσμένης πύλης", +"label.vpncustomergateway.cidrlist" : "Λίστα CIDR επισκέπτη διαχωρισμένων με κόμματα των απομακρυσμένων υποδικτύων.", +"label.vpncustomergateway.esplifetime" : "Η διάρκεια ζωής της φάσης-2 της συσχέτισης ασφαλείας σε δευτερόλεπτα", +"label.vpncustomergateway.ikelifetime" : "φάση-1 διάρκεια ζωής της συσχέτισης ασφαλείας σε δευτερόλεπτα", +"label.vpncustomergateway.secretkey" : "Εισαγωγή μιας μυστικής τιμής κλειδιού", +"label.vpncustomergatewayid" : "Πύλη πελάτη VPN", +"label.vpncustomergatewayname" : "Μοναδικό όνομα για πύλη πελάτη VPN", +"label.vsmctrlvlanid" : "Αναγνωριστικό VLAN ελέγχου", +"label.vsmdeviceid" : "Όνομα", +"label.vsmdevicestate" : "Κατάσταση", +"label.vsmipaddress" : "Διεύθυνση IP Nexus 1000v", +"label.vsmpassword" : "Nexus 1000v Κωδικός πρόσβασης", +"label.vsmpktvlanid" : "Αναγνωριστικό VLAN πακέτου", +"label.vsmstoragevlanid" : "Αναγνωριστικό VLAN αποθήκευσης", +"label.vsmusername" : "Όνομα χρήστη Nexus 1000v", +"label.vsmusername.req" : "Όνομα χρήστη Nexus 1000v", +"label.vsphere.managed" : "διαχείριση vSphere", +"label.vspherestoragepolicy" : "Πολιτική αποθήκευσης vSphere", +"label.vswitch.name" : "όνομα vSwitch", +"label.vswitch.type" : "τύπος vSwitch", +"label.vswitchguestname" : "Όνομα vSwitch κίνησης επισκεπτών", +"label.vswitchguesttype" : "Τύπος vSwitch κίνησης επισκεπτών", +"label.vswitchpublicname" : "Όνομα vSwitch κίνησης κοινού", +"label.vswitchpublictype" : "Τύπος vSwitch δημόσιας κίνησης", +"label.vxlan" : "VXLAN", +"label.vxlan.id" : "Αναγνωριστικό VXLAN", +"label.vxlan.range" : "Σειρά VXLAN", +"label.waiting" : "Αναμονή", +"label.warn" : "Προειδοποιεί", +"label.warn.upper" : "Προειδοποιεί", +"label.warning" : "Προειδοποίηση", +"label.wednesday" : "Τετάρτη", +"label.weekly" : "Εβδομαδιαία", +"label.welcome" : "Καλώς ήρθες", +"label.welcome.cloud.console" : "Καλώς ορίσατε στην Κονσόλα διαχείρισης", +"label.what.is.cloudstack" : "Τι είναι το CloudStack™;", +"label.windows" : "Windows", +"label.with.snapshotid" : "με αναγνωριστικό στιγμιότυπου", +"label.write" : "Γράψετε", +"label.writeback" : "Προσωρινή αποθήκευση δίσκου επιστροφής εγγραφής", +"label.writecachetype" : "Τύπος cache εγγραφής", +"label.writeio" : "Εγγραφή (IO)", +"label.writethrough" : "Εγγραφή μέσω", +"label.xennetworklabel" : "Ετικέτα κίνησης XenServer", +"label.xenservertoolsversion61plus" : "Η αρχική έκδοση XS είναι 6.1+", +"label.yes" : "Ναι", +"label.yourinstance" : "Η περίστασή σας", +"label.zone" : "Ζώνη", +"label.zone.dedicated" : "Αποκλειστική ζώνη", +"label.zone.details" : "Λεπτομέρειες ζώνης", +"label.zone.id" : "Αναγνωριστικό ζώνης", +"label.zone.step.1.title" : "Βήμα 1: Επιλογή δικτύου", +"label.zone.step.2.title" : "Βήμα 2: Πρόσθήκη ζώνης", +"label.zone.step.3.title" : "Βήμα 3: Προσθήκη υποομάδας", +"label.zone.step.4.title" : "Βήμα 4: Προσθήκη εύρους IP", +"label.zone.type" : "Τύπος ζώνης", +"label.zone.wide" : "Σε ολόκληρη τη ζώνη", +"label.zoneid" : "Ζώνη", +"label.zonename" : "Ζώνη", +"label.zonenamelabel" : "Όνομα ζώνης", +"label.zones" : "Ζώνες", +"label.zonewizard.traffictype.guest" : "Επισκέπτες (guest): Κίνηση μεταξύ των εικονικών μηχανών των τελικών χρηστών", +"label.zonewizard.traffictype.management" : "Διαχείριση (Management): Κίνηση μεταξύ των πόρων του Cloudstack καθώς και την επικοινωνία με τον διακομιστή διαχείρισης (management), διακομιστών (hosts), συστημικών VMs", +"label.zonewizard.traffictype.public" : "Δημόσιο (public): Κίνηση μεταξύ του διαδυκτίου και των εικονικών μηχανών", +"label.zonewizard.traffictype.storage" : "Χώρος αποθήκευσης (storage): Κίνηση μεταξύ των πρωτεύοντων και δευτερεύοντων διακομιστών χώρου αποθήκευσης όπως VM templates και snapshosts", +"message.acquire.ip.failed" : "Απέτυχε η απόκτηση ip", +"message.acquire.ip.nic" : "Επιβεβαιώστε ότι θέλετε να αποκτήσετε μια νέα δευτερεύουσα IP για την κάρτα δικτύου.
Σημείωση: Θα πρέπει να ορίσετε μέσα στο VM χειροκίνητα την δευτερεύουσα IP", +"message.acquire.new.ip" : "Επιβεβαιώστε ότι θέλετε να αποκτήσετε μια νέα IP για αυτό το δίκτυο.", +"message.acquire.new.ip.vpc" : "Επιβεβαιώστε ότι θέλετε να αποκτήσετε μια νέα IP για αυτό το VPC.", +"message.acquire.public.ip" : "Επιλέξτε μια ζώνη από την οποία θέλετε να αποκτήσετε τη νέα σας IP.", +"message.action.acquire.ip" : "Επιβεβαιώστε ότι θέλετε να αποκτήσετε νέα IP", +"message.action.cancel.maintenance" : "Ο κεντρικός υπολογιστής σας ακυρώθηκε με επιτυχία για συντήρηση. Αυτή η διαδικασία μπορεί να διαρκέσει έως και μερικά λεπτά.", +"message.action.cancel.maintenance.mode" : "Επιβεβαιώστε ότι θέλετε να ακυρώσετε αυτήν τη συντήρηση.", +"message.action.change.service.warning.for.instance" : "Η εικονική μηχανή σας πρέπει να διακοπεί πριν επιχειρήσετε να αλλάξετε την τρέχουσα προσφορά υπηρεσιών.", +"message.action.change.service.warning.for.router" : "Ο δρομολογητής σας πρέπει να διακοπεί πριν επιχειρήσετε να αλλάξετε την τρέχουσα προσφορά υπηρεσιών.", +"message.action.create.snapshot.from.vmsnapshot" : "Επιβεβαιώστε ότι θέλετε να δημιουργήσετε στιγμιότυπο από το Στιγμιότυπο του VM", +"message.action.delete.backup.offering" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την προσφορά υπηρεσίας αντιγράφων ασφαλείας;", +"message.action.delete.cluster" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το σύμπλεγμα.", +"message.action.delete.disk.offering" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την προσφορά υπηρεσίας δίσκου.", +"message.action.delete.domain" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον τομέα.", +"message.action.delete.external.firewall" : "Επιβεβαιώστε ότι θέλετε να αφαιρέσετε το εξωτερικό τοίχος προστασίας. Προειδοποίηση: Αν σκοπεύεται να το προσθέσετε ξανά πρέπει να μηδενίσετε τα δεδομένα χρήσης στην συσκευή", +"message.action.delete.external.load.balancer" : "Επιβεβαιώστε ότι θέλετε να αφαιρέσετε τον εξωτερικό LB. Προειδοποίηση: Αν σκοπεύεται να τον προσθέσετε ξανά πρέπει να μηδενίσετε τα δεδομένα χρήσης στην συσκευή", +"message.action.delete.ingress.rule" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον κανόνα εισόδου.", +"message.action.delete.iso" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το ISO.", +"message.action.delete.iso.for.all.zones" : "Το ISO χρησιμοποιείται από όλες τις ζώνες. Επιβεβαιώστε ότι θέλετε να το διαγράψετε από όλες τις ζώνες.", +"message.action.delete.network" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το δίκτυο.", +"message.action.delete.nexusvswitch" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το nexus 1000v", +"message.action.delete.physical.network" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το φυσικό δίκτυο", +"message.action.delete.pod" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την υποομάδα.", +"message.action.delete.primary.storage" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον πρωτεύοντα χώρο αποθήκευσης.", +"message.action.delete.secondary.storage" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον δευτερεύοντα χώρο αποθήκευσης.", +"message.action.delete.security.group" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την ομάδα ασφαλείας.", +"message.action.delete.service.offering" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την προσφορά υπηρεσίας.", +"message.action.delete.snapshot" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το στιγμιότυπο.", +"message.action.delete.system.service.offering" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την προσφορά υπηρεσίας συστήματος.", +"message.action.delete.template" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το πρότυπο.", +"message.action.delete.template.for.all.zones" : "Το πρότυπο χρησιμοποιείται από όλες τις ζώνες. Επιβεβαιώστε ότι θέλετε να το διαγράψετε από όλες τις ζώνες.", +"message.action.delete.volume" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον τόμο.", +"message.action.delete.vpn.user" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το χρήστη VPN.", +"message.action.delete.zone" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν τη ζώνη.", +"message.action.destroy.instance" : "Επιβεβαιώστε ότι θέλετε να καταστρέψετε την εικονική μηχανή.", +"message.action.destroy.instance.with.backups" : "Επιβεβαιώστε ότι θέλετε να καταστρέψετε την εικονική μηχανή. Πιθανόν να υπάρχουν αντίγραφα ασφαλείας που θα σβηστούν επίσης", +"message.action.destroy.systemvm" : "Επιβεβαιώστε ότι θέλετε να καταστρέψετε την εικονική μηχανή συστήματος.", +"message.action.destroy.volume" : "Επιβεβαιώστε ότι θέλετε να καταστρέψετε τον τόμο.", +"message.action.disable.cluster" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε αυτό το σύμπλεγμα.", +"message.action.disable.nexusvswitch" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε αυτό το nexus 1000v", +"message.action.disable.physical.network" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε αυτό το φυσικό δίκτυο.", +"message.action.disable.pod" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε αυτήν την υποομάδα (pod).", +"message.action.disable.static.nat" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε το στατικό NAT.", +"message.action.disable.zone" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε αυτήν τη ζώνη.", +"message.action.download.iso" : "Επιβεβαιώστε ότι θέλετε να κατεβάσετε αυτό το ISO.", +"message.action.download.template" : "Επιβεβαιώστε ότι θέλετε να κάνετε λήψη αυτού του προτύπου.", +"message.action.downloading.template" : "Λήψη προτύπου.", +"message.action.enable.cluster" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε αυτό το σύμπλεγμα.", +"message.action.enable.maintenance" : "Ο κεντρικός υπολογιστής σας έχει προετοιμαστεί με επιτυχία για συντήρηση. Αυτή η διαδικασία μπορεί να διαρκέσει έως και αρκετά λεπτά ή περισσότερο, ανάλογα με τον αριθμό των VM που βρίσκονται αυτήν τη στιγμή σε αυτόν τον κεντρικό υπολογιστή.", +"message.action.enable.nexusvswitch" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε αυτό το nexus 1000v", +"message.action.enable.physical.network" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε αυτό το φυσικό δίκτυο.", +"message.action.enable.pod" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε αυτό το pod.", +"message.action.enable.zone" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε αυτήν τη ζώνη.", +"message.action.expunge.instance" : "Επιβεβαιώστε ότι θέλετε να εξουδετεί αυτήν την εικονική μηχανή.", +"message.action.expunge.instance.with.backups" : "Επιβεβαιώστε ότι θέλετε να σβήσετε οριστικά την εικονική μηχανή. Πιθανόν να υπάρχουν αντίγραφα ασφαλείας που θα σβηστούν επίσης", +"message.action.force.reconnect" : "Ο κεντρικός υπολογιστής σας αναγκάστηκε να επανασυνδεθεί με επιτυχία. Αυτή η διαδικασία μπορεί να διαρκέσει έως και μερικά λεπτά.", +"message.action.host.enable.maintenance.mode" : "Η ενεργοποίηση της λειτουργίας συντήρησης θα προκαλέσει μια ζωντανή μετεγκατάσταση όλων των εμφανίσεων που εκτελούνται σε αυτόν τον κεντρικό υπολογιστή σε οποιονδήποτε διαθέσιμο κεντρικό υπολογιστή.", +"message.action.instance.reset.password" : "Επιβεβαιώστε ότι θέλετε να αλλάξετε τον κωδικό πρόσβασης ROOT για αυτήν την εικονική μηχανή.", +"message.action.manage.cluster" : "Επιβεβαιώστε ότι θέλετε να διαχειριστείτε το σύμπλεγμα.", +"message.action.primarystorage.enable.maintenance.mode" : "Προειδοποίηση: Αν θέσετε το πρωτεύον χώρο αποθήκευσης σε συντήρηση όλες οι εικονικές μηχανές που χρησιμοποιούν τόμους απο αυτό θα σταματήσουν. Θέλετε να συνεχίσετε;", +"message.action.reboot.instance" : "Επιβεβαιώστε ότι θέλετε να επανεκκινήσετε αυτήν την εικονική μηχανή.", +"message.action.reboot.router" : "Όλες οι υπηρεσίες που παρέχονται από αυτόν τον εικονικό δρομολογητή θα διακοπούν. Επιβεβαιώστε ότι θέλετε να επανεκκινήσετε αυτόν το δρομολογητή.", +"message.action.reboot.systemvm" : "Επιβεβαιώστε ότι θέλετε να επανεκκινήσετε αυτό το σύστημα VM.", +"message.action.recover.volume" : "Επιβεβαιώστε ότι θέλετε να ανακτήσετε αυτόν τον τόμο.", +"message.action.release.ip" : "Επιβεβαιώστε ότι θέλετε να αποδεσμεύσετε αυτήν την IP.", +"message.action.remove.host" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε αυτόν τον κεντρικό υπολογιστή.", +"message.action.reset.password.off" : "Αυτήν τη στιγμή η εικονική μηχανή σας δεν υποστηρίζει αυτήν τη δυνατότητα.", +"message.action.reset.password.warning" : "Η εικονική μηχανή σας πρέπει να διακοπεί πριν επιχειρήσετε να αλλάξετε τον τρέχοντα κωδικό πρόσβασής της.", +"message.action.restore.instance" : "Επιβεβαιώστε ότι θέλετε να επαναφέρετε αυτήν την εικονική μηχανή.", +"message.action.revert.snapshot" : "Επιβεβαιώστε ότι θέλετε να επαναφέρετε τον τόμο κατοχής σε αυτό το στιγμιότυπο.", +"message.action.router.health.checks" : "Το αποτέλεσμα των ελέγχων εύρυθμης λειτουργίας θα ληφθεί από το δρομολογητή.", +"message.action.router.health.checks.disabled.warning" : "Ενεργοποιήστε τους ελέγχους εύρυθμης λειτουργίας του δρομολογητή.", +"message.action.secondary.storage.read.only" : "Επιβεβαιώστε ότι θέλετε να θέσετε το δευτερεύον χώρο αποθήκευσης σε επιλογή read-only", +"message.action.secondary.storage.read.write" : "Επιβεβαιώστε ότι θέλετε να θέσετε το δευτερεύον χώρο αποθήκευσης σε επιλογή read-write", +"message.action.secure.host" : "Αυτό θα επανεκκινήσει τον κεντρικό agent και την διεργασία libvirtd μετά την εφαρμογή νέων πιστοποιητικών X509, επιβεβαιώνετε;", +"message.action.settings.warning.vm.running" : "Διακόψτε την εικονική μηχανή για πρόσβαση στις ρυθμίσεις", +"message.action.settings.warning.vm.started" : "Η εικονική μηχανή έχει ξεκινήσει. Πρέπει να διακοπεί για να αποκτήσετε πρόσβαση στις ρυθμίσεις", +"message.action.start.instance" : "Επιβεβαιώστε ότι θέλετε να ξεκινήσετε αυτήν την εικονική μηχανή.", +"message.action.start.router" : "Επιβεβαιώστε ότι θέλετε να ξεκινήσετε αυτόν το δρομολογητή.", +"message.action.start.systemvm" : "Επιβεβαιώστε ότι θέλετε να ξεκινήσετε αυτό το σύστημα VM.", +"message.action.stop.instance" : "Επιβεβαιώστε ότι θέλετε να διακόψετε αυτήν την εικονική μηχανή.", +"message.action.stop.router" : "Όλες οι υπηρεσίες που παρέχονται από αυτόν τον εικονικό δρομολογητή θα διακοπούν. Επιβεβαιώστε ότι θέλετε να διακόψετε αυτόν το δρομολογητή.", +"message.action.stop.systemvm" : "Επιβεβαιώστε ότι θέλετε να διακόψετε αυτό το σύστημα VM.", +"message.action.unmanage.cluster" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε τη διαχείριση του ομοταξίας.", +"message.action.unmanage.virtualmachine" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε τη διαχείριση της εικονικής μηχανής.", +"message.action.vmsnapshot.create" : "Επιβεβαιώστε ότι θέλετε να τραβήξετε ένα στιγμιότυπο αυτής της εικονική μηχανής.
Παρατηρήστε ότι η εικονική μηχανή θα διακοπεί κατά τη διάρκεια της λήψης στιγμιοτύπου και θα συνεχιστεί μετά την ολοκλήρωση της διαδικασίας, εάν εκτελείται στο KVM.", +"message.action.vmsnapshot.delete" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το στιγμιότυπο VM.
Παρατηρήστε ότι η εικονική μηχανή θα διακοπεί πριν από τη διαγραφή του στιγμιότυπου και θα συνεχιστεί μετά τη διαγραφή, εάν εκτελείται στο KVM.", +"message.action.vmsnapshot.revert" : "Επαναφορά στιγμιότυπου VM", +"message.action.vmstoragesnapshot.create" : "Επιλέξτε έναν τόμο που θέλετε να τραβήξετε ένα στιγμιότυπο.", +"message.activate.project" : "Είστε βέβαιοι ότι θέλετε να ενεργοποιήσετε αυτό το έργο;", +"message.add.cluster" : "Προσθέστε ένα διαχειριζόμενο σύμπλεγμα hypervisor για τη ζώνη , pod ", +"message.add.cluster.zone" : "Προσθήκη διαχειριζόμενου ομοταξίας hypervisor για ζώνη ", +"message.add.disk.offering" : "Καθορίστε τις ακόλουθες παραμέτρους για να προσθέσετε μια νέα προσφορά δίσκου", +"message.add.domain" : "Καθορίστε τον δευτερεύοντα τομέα που θέλετε να δημιουργήσετε κάτω από αυτόν τον τομέα", +"message.add.egress.rule.failed" : "Η προσθήκη νέου κανόνα εξόδου απέτυχε", +"message.add.egress.rule.processing" : "Προσθήκη νέου κανόνα εξόδου...", +"message.add.failed" : "Η προσθήκη απέτυχε", +"message.add.firewall" : "Προσθήκη τείχους προστασίας στη ζώνη", +"message.add.firewall.rule.failed" : "Η προσθήκη νέου κανόνα τείχους προστασίας απέτυχε", +"message.add.firewall.rule.processing" : "Προσθήκη νέου κανόνα τείχους προστασίας...", +"message.add.guest.network" : "Επιβεβαιώστε ότι θέλετε να προσθέσετε ένα δίκτυο επισκεπτών", +"message.add.host" : "Καθορίστε τις ακόλουθες παραμέτρους για να προσθέσετε έναν νέο κεντρικό υπολογιστή", +"message.add.ip.range" : "Προσθήκη περιοχής IP σε δημόσιο δίκτυο στη ζώνη", +"message.add.ip.range.direct.network" : "Προσθήκη περιοχής IP για την άμεση σύνδεση δικτύου στη ζώνη ", +"message.add.ip.range.to.pod" : "

Προσθέστε ένα εύρος διεθύνσεων IPs στην υποομάδα:

", +"message.add.iprange.processing" : "Προσθήκη περιοχής IP...", +"message.add.load.balancer" : "Προσθήκη εξισορρόπησης φόρτου στη ζώνη", +"message.add.load.balancer.under.ip" : "Ο κανόνας ισομοιρασμού φόρτου προστέθηκε στην IP:", +"message.add.network" : "Προσθέστε ένα νέο δίκτυο για την ζώνη: ", +"message.add.network.acl.failed" : "Η προσθήκη λίστας ACL δικτύου απέτυχε", +"message.add.network.acl.processing" : "Προσθήκη λίστας ACL δικτύου...", +"message.add.network.failed" : "Η προσθήκη δικτύου απέτυχε", +"message.add.network.processing" : "Προσθήκη δικτύου...", +"message.add.new.gateway.to.vpc" : "Καθορίστε τις πληροφορίες για να προσθέσετε μια νέα πύλη σε αυτό το VPC.", +"message.add.pod" : "Προσθέστε ένα νέο pod για τη ζώνη ", +"message.add.pod.during.zone.creation" : "Κάθε ζώνη πρέπει να περιέχει ένα ή περισσότερα pods, και θα προσθέσουμε το πρώτο pod τώρα. Ένα pod περιέχει κεντρικούς υπολογιστές και κύριους διακομιστές αποθήκευσης, τα οποία θα προσθέσετε σε ένα μεταγενέστερο βήμα. Πρώτα, ρυθμίστε τις παραμέτρους μιας περιοχής δεσμευμένων διευθύνσεων IP για την εσωτερική Κίνηση διαχείρισης του CloudStack. Η δεσμευμένη περιοχή IP πρέπει να είναι μοναδική για κάθε ζώνη στο cloud.", +"message.add.port.forward.failed" : "Η προσθήκη νέου κανόνα προώθησης θυρών απέτυχε", +"message.add.port.forward.processing" : "Προσθήκη νέου κανόνα προώθησης θυρών...", +"message.add.primary" : "Καθορίστε τις ακόλουθες παραμέτρους για να προσθέσετε ένα νέο πρωτεύον χώρο αποθήκευσης", +"message.add.primary.storage" : "Προσθέστε ένα νέο κύριο χώρο αποθήκευσης για τη ζώνη , pod ", +"message.add.private.gateway.failed" : "Η προσθήκη ιδιωτικής πύλης απέτυχε", +"message.add.private.gateway.processing" : "Προσθήκη ιδιωτικής πύλης...", +"message.add.region" : "Καθορίστε τις απαιτούμενες πληροφορίες για την προσθήκη μιας νέας περιοχής.", +"message.add.resource.description" : "Προσθήκη πόρων υποδομής", +"message.add.resource.hint" : "Προσθέστε πόρους υποδομής - pods, συμπλέγματα, πρωτεύοντες/δευτερεύουσες αποθήκες.", +"message.add.rule.failed" : "Απέτυχε η προσθήκη νέου κανόνα", +"message.add.rule.processing" : "Προσθήκη νέου κανόνα ομάδας ασφαλείας...", +"message.add.secondary.ipaddress.processing" : "Προσθήκη δευτερεύουσας διεύθυνσης IP...", +"message.add.secondary.storage" : "Προσθήκη νέου χώρου αποθήκευσης για τη ζώνη ", +"message.add.service.offering" : "Συμπληρώστε τα παρακάτω δεδομένα για να προσθέσετε μια νέα προσφορά υπηρεσίας υπολογισμού.", +"message.add.static.route.failed" : "Απέτυχε η προσθήκη στατικής διαδρομής", +"message.add.static.route.processing" : "Προσθήκη στατικής διαδρομής...", +"message.add.system.service.offering" : "Συμπληρώστε τα παρακάτω δεδομένα για να προσθέσετε μια νέα προσφορά υπηρεσιών συστήματος.", +"message.add.tag.failed" : "Απέτυχε η προσθήκη νέας ετικέτας", +"message.add.tag.for.networkacl" : "Προσθήκη ετικέτας για networkacl", +"message.add.tag.processing" : "Προσθήκη νέας ετικέτας...", +"message.add.template" : "Πληκτρολογήστε τα ακόλουθα δεδομένα για να δημιουργήσετε το νέο σας πρότυπο", +"message.add.user.to.project" : "Αυτή η φόρμα χρησιμοποιείται για να ενεργοποιήσετε την προσθήκη συγκεκριμένων χρηστών ενός λογαριασμού σε ένα έργο.
Επιπλέον, ένα ProjectRole μπορεί να προστεθεί στο πρόσθετο χρήστη/λογαριασμό για να επιτρέψει/απαγορεύσει την πρόσβαση API σε επίπεδο έργου.
Μπορούμε επίσης να καθορίσουμε το ρόλο με τον οποίο ο χρήστης θα πρέπει να προστεθεί σε ένα έργο - Admin/Regular, εάν δεν καθοριστεί, είναι προεπιλογή σε «Regular»", +"message.add.volume" : "Συμπληρώστε τα παρακάτω δεδομένα για να προσθέσετε έναν νέο τόμο.", +"message.add.vpn.connection.failed" : "Η προσθήκη σύνδεσης VPN απέτυχε", +"message.add.vpn.connection.processing" : "Προσθήκη σύνδεσης VPN...", +"message.add.vpn.customer.gateway" : "Προσθήκη πύλης πελατών VPN", +"message.add.vpn.customer.gateway.failed" : "Απέτυχε η προσθήκη πύλης πελάτη VPN", +"message.add.vpn.customer.gateway.processing" : "Η δημιουργία της πύλης πελατών VPN βρίσκεται σε εξέλιξη", +"message.add.vpn.gateway" : "Επιβεβαιώστε ότι θέλετε να προσθέσετε μια πύλη VPN", +"message.add.vpn.gateway.failed" : "Η προσθήκη πύλης VPN απέτυχε", +"message.add.vpn.gateway.processing" : "Προσθήκη πύλης VPN...", +"message.added.vpc.offering" : "Προστέθηκε προσφορά υπηρεσίας VPC", +"message.adding.host" : "Προσθήκη κεντρικού υπολογιστή", +"message.adding.netscaler.device" : "Προσθήκη συσκευής netsccaler", +"message.adding.netscaler.provider" : "Προσθήκη υπηρεσίας παροχής Netsccaler", +"message.additional.networks.desc" : "Επιλέξτε πρόσθετα δίκτυα με τα οποία θα συνδεθεί η εικονική εικονική μηχανή σας.", +"message.admin.guide.read" : "Για VM που βασίζονται σε VM, διαβάστε την ενότητα δυναμικής κλιμάκωσης στον οδηγό διαχείρισης πριν από την κλιμάκωση. Θέλετε να συνεχίσετε;,", +"message.advanced.mode.desc" : "Επιλέξτε αυτό το μοντέλο δικτύου εάν θέλετε να ενεργοποιήσετε την υποστήριξη VLAN. Αυτό το μοντέλο δικτύου παρέχει τη μεγαλύτερη ευελιξία στην παροχή στους διαχειριστές προσαρμοσμένων προσφορών δικτύου, όπως η παροχή υποστήριξης τείχους προστασίας, VPN ή εξισορρόπησης φόρτου, καθώς και η ενεργοποίηση της άμεσης vs εικονικής δικτύωσης.", +"message.advanced.security.group" : "Επιλέξτε αυτό εάν θέλετε να χρησιμοποιήσετε ομάδες ασφαλείας για να παρέχετε απομόνωση vm επισκέπτη.", +"message.advanced.virtual" : "Επιλέξτε αυτό εάν θέλετε να χρησιμοποιήσετε vlan σε ολόκληρη τη ζώνη για να παρέχετε απομόνωση VM επισκέπτη.", +"message.after.enable.s3" : "Η παραμετροποίηση του δευτερεύοντος χώρου αποθήκευσης S3-backend έχει ολοκληρωθεί. Σημείωση: Μετά την απομάκρυνση απο την παρούσα σελίδα δεν είναι δυνατή η εκ νέου παραμετροποίηση", +"message.after.enable.swift" : "Η παραμετροποίηση του δευτερεύοντος χώρου αποθήκευσης Swift έχει ολοκληρωθεί. Σημείωση: Μετά την απομάκρυνση απο την παρούσα σελίδα δεν είναι δυνατή η εκ νέου παραμετροποίηση", +"message.alert.state.detected" : "Εντοπίστηκε κατάσταση ειδοποίησης", +"message.allow.vpn.access" : "Πληκτρολογήστε ένα όνομα χρήστη και κωδικό πρόσβασης του χρήστη που θέλετε να επιτρέψετε την πρόσβαση VPN.", +"message.apply.snapshot.policy" : "Έχετε ενημερώσει με επιτυχία την τρέχουσα πολιτική στιγμιοτύπων.", +"message.apply.success" : "Η εφαρμογή ολοκληρώθηκε με επιτυχία", +"message.assign.instance.another" : "Καθορίστε τον τύπο λογαριασμού, τον τομέα, το όνομα λογαριασμού και το δίκτυο (προαιρετικό) του νέου λογαριασμού.
Εάν το προεπιλεγμένο nic της εικονικής μηχανής βρίσκεται σε κοινόχρηστο δίκτυο, το CloudStack θα ελέγξει αν το δίκτυο μπορεί να χρησιμοποιηθεί από το νέο λογαριασμό, εάν δεν καθορίσετε ένα δίκτυο.
Εάν το προεπιλεγμένο nic της εικονικής μηχανής βρίσκεται σε απομονωμένο δίκτυο και ο νέος λογαριασμός έχει περισσότερα απομονωμένα δίκτυα, θα πρέπει να καθορίσετε ένα.", +"message.assign.vm.failed" : "Απέτυχε η αντιστοίχιση vm", +"message.assign.vm.processing" : "Αντιστοίχιση εικονικής μηχανής...", +"message.attach.iso.confirm" : "Επιβεβαιώστε ότι θέλετε να επισυνάψετε το ISO σε αυτήν την εικονική εικονική μηχανή.", +"message.attach.volume" : "Συμπληρώστε τα παρακάτω δεδομένα για να επισυνάψετε έναν νέο τόμο. Εάν συνδέετε έναν τόμο δίσκου σε μια εικονική μηχανή που βασίζεται στα Windows, θα χρειαστεί να επανεκκινήσετε την εικονική μηχανή για να δείτε τον συνημμένο δίσκο.", +"message.attach.volume.failed" : "Απέτυχε η επισύναψη τόμου", +"message.attach.volume.progress" : "Επισύναψη τόμου", +"message.authorization.failed" : "Η περίοδος λειτουργίας έληξε, η επαλήθευση εξουσιοδότησης απέτυχε", +"message.backup.attach.restore" : "Επιβεβαιώστε ότι θέλετε να επαναφέρετε και να επισυνάψετε τον τόμο από το αντίγραφο ασφαλείας;", +"message.backup.create" : "Είστε βέβαιοι ότι θέλετε να δημιουργήσετε ένα αντίγραφο ασφαλείας VM;", +"message.backup.offering.remove" : "Είστε βέβαιοι ότι θέλετε να καταργήσετε την εικονική μηχανή από την προσφορά δημιουργίας αντιγράφων ασφαλείας και να διαγράψετε την αλυσίδα αντιγράφων ασφαλείας;", +"message.backup.restore" : "Επιβεβαιώστε ότι θέλετε να επαναφέρετε το αντίγραφο ασφαλείας vm;", +"message.basic.mode.desc" : "Επιλέξτε αυτό το μοντέλο δικτύου, αν δεν* * θέλετε να ενεργοποιήσετε οποιαδήποτε υποστήριξη VLAN. Σε όλες τις εικονικές παρουσίες που δημιουργούνται στο πλαίσιο αυτού του μοντέλου δικτύου θα εκχωρηθεί μια διεύθυνση IP απευθείας από το δίκτυο και οι ομάδες ασφαλείας χρησιμοποιούνται για την παροχή ασφάλειας και διαχωρισμού.", +"message.certificate.upload.processing" : "Αποστολή πιστοποιητικού σε εξέλιξη", +"message.change.offering.confirm" : "Επιβεβαιώστε ότι θέλετε να αλλάξετε την προσφορά υπηρεσιών αυτής της εικονικής εικονική μηχανής.", +"message.change.password" : "Αλλάξτε τον κωδικό πρόσβασής σας", +"message.cluster.dedicated" : "Αποκλειστικό σύμπλεγμα", +"message.cluster.dedication.released" : "Η αποκλειστική διάθεση στο σύμπλεγμα αποδεσμέυτηκε", +"message.config.sticky.policy.failed" : "Απέτυχε η ρύθμιση παραμέτρων της πολιτικής αυτοκόλλητης", +"message.config.sticky.policy.processing" : "Ενημέρωση sticky πολιτικής...", +"message.configure.all.traffic.types" : "Έχετε πολλά φυσικά δίκτυα. Ρυθμίστε τις παραμέτρους των ετικετών για κάθε τύπο κίνησης κάνοντας κλικ στο κουμπί Επεξεργασία.", +"message.configure.firewall.rules.allow.traffic" : "Ρύθμιση παραμέτρων των κανόνων ώστε να επιτρέπεται η Κίνηση", +"message.configure.firewall.rules.block.traffic" : "Ρύθμιση παραμέτρων των κανόνων για τον αποκλεισμό της κίνησης", +"message.configure.ldap" : "Επιβεβαιώστε ότι θέλετε να ρυθμίσετε τις παραμέτρους του LDAP.", +"message.configuring.guest.traffic" : "Ρύθμιση παραμέτρων επισκεψιμότητας επισκεπτών", +"message.configuring.physical.networks" : "Ρύθμιση παραμέτρων φυσικών δικτύων", +"message.configuring.public.traffic" : "Ρύθμιση παραμέτρων δημόσιας κίνησης", +"message.configuring.storage.traffic" : "Ρύθμιση παραμέτρων κίνησης αποθήκευσης", +"message.confirm.action.force.reconnect" : "Επιβεβαιώστε ότι θέλετε να επισυνάσετε την επανασύνδεση αυτού του κεντρικού υπολογιστή.", +"message.confirm.add.vnmc.provider" : "Επιβεβαιώστε ότι θέλετε να προσθέσετε την υπηρεσία παροχής VNMC.", +"message.confirm.archive.alert" : "Επιβεβαιώστε ότι θέλετε να αρχειοθετήσετε αυτήν την ειδοποίηση.", +"message.confirm.archive.event" : "Επιβεβαιώστε ότι θέλετε να αρχειοθετήσετε αυτό το συμβάν.", +"message.confirm.archive.selected.alerts" : "Επιβεβαιώστε ότι θέλετε να αρχειοθετήσετε τις επιλεγμένες ειδοποιήσεις", +"message.confirm.archive.selected.events" : "Επιβεβαιώστε ότι θέλετε να αρχειοθετήσετε τα επιλεγμένα συμβάντα", +"message.confirm.attach.disk" : "Είστε βέβαιοι ότι θέλετε να επισυνάψετε το δίσκο;", +"message.confirm.configure.ovs" : "Είστε βέβαιοι ότι θέλετε να ρυθμίσετε τις παραμέτρους του Ovs;", +"message.confirm.create.volume" : "Είστε βέβαιοι ότι θέλετε να δημιουργήσετε τόμο;", +"message.confirm.current.guest.cidr.unchanged" : "Θέλετε να διατηρήσετε αμετάβλητο το τρέχον δίκτυο επισκεπτών CIDR;", +"message.confirm.dedicate.cluster.domain.account" : "Θέλετε πραγματικά να αφιερώσετε αυτό το σύμπλεγμα σε έναν τομέα / λογαριασμό; ", +"message.confirm.dedicate.host.domain.account" : "Θέλετε πραγματικά να αφιερώσετε αυτόν τον κεντρικό υπολογιστή σε έναν τομέα/απολογισμό; ", +"message.confirm.dedicate.pod.domain.account" : "Θέλετε πραγματικά να αφιερώσετε αυτήν την υποομάδα (pod) σε ένα domain / λογαριασμό; ", +"message.confirm.dedicate.zone" : "Θέλετε πραγματικά να αφιερώσετε αυτή τη ζώνη σε έναν τομέα / λογαριασμό;", +"message.confirm.delete.acl.list" : "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη λίστα ACL;", +"message.confirm.delete.alert" : "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν την ειδοποίηση;", +"message.confirm.delete.baremetal.rack.configuration" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε τη ρύθμιση παραμέτρων του Baremetal Rack.", +"message.confirm.delete.bigswitchbcf" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν τον ελεγκτή BigSwitch BCF", +"message.confirm.delete.brocadevcs" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το εναλλάκτη Brocade Vcs", +"message.confirm.delete.ciscoasa1000v" : "Παρακαλώ επιβεβαιώστε ότι θέλετε να διαγράψετε CiscoASA1000v", +"message.confirm.delete.ciscovnmc.resource" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε τον πόρο CiscoVNMC", +"message.confirm.delete.f5" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το F5", +"message.confirm.delete.internal.lb" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το εσωτερικό LB", +"message.confirm.delete.kubernetes.version" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την έκδοση Kubernetes.", +"message.confirm.delete.netscaler" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το NetSccaler", +"message.confirm.delete.niciranvp" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε τον ελεγκτή Nicira Nvp", +"message.confirm.delete.pa" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το Palo Alto", +"message.confirm.delete.provider" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την υπηρεσία παροχής;", +"message.confirm.delete.secondary.staging.store" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το δευτερεύον χώρο αποθήκευσης ανασυγκρότησης.", +"message.confirm.delete.srx" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το SRX", +"message.confirm.delete.ucs.manager" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το UCS Manager", +"message.confirm.destroy.kubernetes.cluster" : "Επιβεβαιώστε ότι θέλετε να καταστρέψετε αυτό το σύμπλεγμα Kubernetes.", +"message.confirm.destroy.router" : "Όλες οι υπηρεσίες που παρέχονται από αυτόν τον εικονικό δρομολογητή θα διακοπούν. Επιβεβαιώστε ότι θέλετε να διακόψετε αυτόν το δρομολογητή. Επιβεβαιώστε ότι θέλετε να καταστρέψετε αυτόν το δρομολογητή", +"message.confirm.disable.host" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε τον κεντρικό υπολογιστή", +"message.confirm.disable.storage" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε το χώρο συγκέντρωσης χώρου αποθήκευσης", +"message.confirm.disable.network.offering" : "Είστε βέβαιοι ότι θέλετε να απενεργοποιήσετε αυτήν την προσφορά δικτύου;", +"message.confirm.disable.provider" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε αυτήν την υπηρεσία παροχής", +"message.confirm.disable.vnmc.provider" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε την υπηρεσία παροχής VNMC.", +"message.confirm.disable.vpc.offering" : "Είστε βέβαιοι ότι θέλετε να απενεργοποιήσετε αυτήν την προσφορά VPC;", +"message.confirm.enable.host" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε τον κεντρικό υπολογιστή", +"message.confirm.enable.storage" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε το χώρο συγκέντρωσης χώρου αποθήκευσης", +"message.confirm.enable.network.offering" : "Είστε βέβαιοι ότι θέλετε να ενεργοποιήσετε αυτήν την προσφορά δικτύου;", +"message.confirm.enable.provider" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε αυτήν την υπηρεσία παροχής", +"message.confirm.enable.vnmc.provider" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε την υπηρεσία παροχής VNMC.", +"message.confirm.enable.vpc.offering" : "Είστε βέβαιοι ότι θέλετε να ενεργοποιήσετε αυτήν την προσφορά VPC;", +"message.confirm.force.update" : "Θέλετε να επιβάλετε την ενημέρωση;", +"message.confirm.join.project" : "Επιβεβαιώστε ότι επιθυμείτε να συμμετάσχετε σε αυτό το έργο.", +"message.confirm.migrate.volume" : "Θέλετε να μετεγκαταστήσετε αυτόν τον τόμο;", +"message.confirm.refresh.blades" : "Επιβεβαιώστε ότι θέλετε να ανανεώσετε τα Blades.", +"message.confirm.release.dedicate.vlan.range" : "Επιβεβαιώστε ότι θέλετε να αποδεσμεύσετε την αποκλειστική σειρά VLAN", +"message.confirm.release.dedicated.cluster" : "Θέλετε να αποδεσμεύσετε αυτό το αποκλειστικό σύμπλεγμα;", +"message.confirm.release.dedicated.host" : "Θέλετε να αποδεσμεύσετε αυτόν τον αποκλειστικό κεντρικό υπολογιστή;", +"message.confirm.release.dedicated.pod" : "Θέλετε να αποδεσμεύσετε αυτήν την ειδική υποομάδα (pod);", +"message.confirm.release.dedicated.zone" : "Θέλετε να αποδεσμεύσετε αυτήν την αποκλειστική ζώνη; ", +"message.confirm.remove.event" : "Είστε βέβαιοι ότι θέλετε να καταργήσετε αυτό το συμβάν;", +"message.confirm.remove.ip.range" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε αυτήν την περιοχή IP.", +"message.confirm.remove.load.balancer" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε την εικονική μηχανή από την εξισορρόπηση φόρτου", +"message.confirm.remove.network.offering" : "Είστε βέβαιοι ότι θέλετε να καταργήσετε αυτήν την προσφορά δικτύου;", +"message.confirm.remove.selected.alerts" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε τις επιλεγμένες ειδοποιήσεις", +"message.confirm.remove.selected.events" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε τα επιλεγμένα συμβάντα", +"message.confirm.remove.vmware.datacenter" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε το κέντρο δεδομένων VMware", +"message.confirm.remove.vpc.offering" : "Είστε βέβαιοι ότι θέλετε να καταργήσετε αυτήν την προσφορά VPC;", +"message.confirm.replace.acl.new.one" : "Θέλετε να αντικαταστήσετε το ACL με ένα νέο;", +"message.confirm.scale.up.router.vm" : "Θέλετε πραγματικά να κλιμακώσετε το Router VM;", +"message.confirm.scale.up.system.vm" : "Θέλετε πραγματικά να κλιμακώσετε το σύστημα VM;", +"message.confirm.shutdown.provider" : "Επιβεβαιώστε ότι θέλετε να τερματίσετε τη λειτουργία αυτής της υπηρεσίας παροχής", +"message.confirm.start.kubernetes.cluster" : "Επιβεβαιώστε ότι θέλετε να ξεκινήσετε αυτό το σύμπλεγμα Kubernetes.", +"message.confirm.start.lb.vm" : "Επιβεβαιώστε ότι θέλετε να ξεκινήσετε το LB VM", +"message.confirm.stop.kubernetes.cluster" : "Επιβεβαιώστε ότι θέλετε να διακόψετε αυτό το σύμπλεγμα Kubernetes.", +"message.confirm.stop.lb.vm" : "Επιβεβαιώστε ότι θέλετε να διακόψετε το LB VM", +"message.confirm.upgrade.router.newer.template" : "Επιβεβαιώστε ότι θέλετε να αναβαθμίσετε το δρομολογητή για να χρησιμοποιήσετε νεότερο πρότυπο", +"message.confirm.upgrade.routers.account.newtemplate" : "Επιβεβαιώστε ότι θέλετε να αναβαθμίσετε όλους τους δρομολογητές σε αυτόν το λογαριασμό για να χρησιμοποιήσετε νεότερο πρότυπο", +"message.confirm.upgrade.routers.cluster.newtemplate" : "Επιβεβαιώστε ότι θέλετε να αναβαθμίσετε όλους τους δρομολογητές σε αυτό το σύμπλεγμα για να χρησιμοποιήσετε νεότερο πρότυπο", +"message.confirm.upgrade.routers.newtemplate" : "Επιβεβαιώστε ότι θέλετε να αναβαθμίσετε όλους τους δρομολογητές σε αυτήν τη ζώνη για να χρησιμοποιήσετε νεότερα πρότυπα", +"message.confirm.upgrade.routers.pod.newtemplate" : "Επιβεβαιώστε ότι θέλετε να αναβαθμίσετε όλους τους δρομολογητές σε αυτήν την υποομάδα (pod) για να χρησιμοποιήσετε νεότερα πρότυπα", +"message.copy.iso.confirm" : "Επιβεβαιώστε ότι επιθυμείτε να αντιγράψετε το ISO σας", +"message.copy.template" : "Αντιγραφή προτύπου XXX από ζώνη σε", +"message.copy.template.confirm" : "Είστε βέβαιοι ότι θέλετε να αντιγράψετε το πρότυπο;", +"message.create.compute.offering" : "Υπολογισμός προσφοράς υπηρεσίας που δημιουργήθηκε", +"message.create.internallb" : "Δημιουργία εσωτερικού LB", +"message.create.internallb.failed" : "Απέτυχε η δημιουργία εσωτερικής lb", +"message.create.internallb.processing" : "Δημιουργία εσωτερικού LB σε εξέλιξη", +"message.create.service.offering" : "Δημιουργία προσφοράς υπηρεσίας υπηρεσιών", +"message.create.snapshot.from.vmsnapshot.failed" : "Απέτυχε η δημιουργία στιγμιότυπου από το στιγμιότυπο VM", +"message.create.snapshot.from.vmsnapshot.progress" : "Δημιουργία στιγμιότυπου σε εξέλιξη", +"message.create.template" : "Είστε βέβαιοι ότι θέλετε να δημιουργήσετε πρότυπο;", +"message.create.template.vm" : "Δημιουργία εικονικής μηχανής από πρότυπο ", +"message.create.template.volume" : "Παρακαλώ εισάγεται της ακόλουθες πληροφορίες πριν την δημιουργία του προτύπου τόμου δίσκων: . Η δημιουργία του προτύπου, ανάλογα με το μέγεθος του, ενδέχεται να διαρκέσει απο κάποια λεπτά ώρες.", +"message.create.volume.failed" : "Απέτυχε η δημιουργία τόμου", +"message.create.volume.processing" : "Δημιουργία τόμου σε εξέλιξη", +"message.create.vpc.offering" : "VPC προσφορά που δημιουργήθηκε", +"message.create.vpn.customer.gateway.failed" : "Η δημιουργία πύλης πελάτη VPN απέτυχε", +"message.creating.cluster" : "Δημιουργία ομοταξίας", +"message.creating.guest.network" : "Δημιουργία δικτύου επισκεπτών", +"message.creating.physical.networks" : "Δημιουργία φυσικών δικτύων", +"message.creating.pod" : "Δημιουργία υποομάδας (pod)", +"message.creating.primary.storage" : "Δημιουργία πρωτεύοντος χώρου αποθήκευσης", +"message.creating.secondary.storage" : "Δημιουργία δευτερεύοντος χώρου αποθήκευσης", +"message.creating.systemvm" : "Δημιουργία VM συστήματος (αυτό μπορεί να διαρκέσει λίγο)", +"message.creating.zone" : "Δημιουργία ζώνης", +"message.datacenter.description" : "Όνομα του κέντρου δεδομένων στο vCenter", +"message.datastore.description" : "Όνομα του χώρου αποθήκευσης δεδομένων στο vCenter", +"message.data.migration" : "Μετεγκατάσταση δεδομένων", +"message.data.migration.progress" : "Μετεγκατάσταση δεδομένων μεταξύ των καταστημάτων αποθήκευσης εικόνων", +"message.dedicate.zone" : "αποκλειστική διάθεση ζώνης", +"message.dedicated.zone.released" : "Αποδεσμεύτηκε η αποκλειστική διάθεση ζώνης", +"message.dedicating.cluster" : "αποκλειστικοποίηση ομοταξίας...", +"message.dedicating.host" : "αποκλειστικοποίηση υποδοχής...", +"message.dedicating.pod" : "αποκλειστικοποίηση υποομάδας (pod)...", +"message.dedicating.zone" : "αποκλειστικοποίηση Ζώνης...", +"message.delete.account" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν το λογαριασμό.", +"message.delete.acl.processing" : "Κατάργηση κανόνα ACL...", +"message.delete.acl.rule" : "Κατάργηση κανόνα ACL", +"message.delete.acl.rule.failed" : "Απέτυχε η κατάργηση του κανόνα ACL", +"message.delete.affinity.group" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε αυτήν την ομάδα συνάφειας.", +"message.delete.backup" : "Είστε βέβαιοι ότι θέλετε να διαγράψετε το αντίγραφο ασφαλείας;", +"message.delete.failed" : "Η διαγραφή απέτυχε", +"message.delete.gateway" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε την πύλη", +"message.delete.port.forward.processing" : "Διαγραφή κανόνα προώθησης θυρών...", +"message.delete.project" : "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το έργο;", +"message.delete.rule.processing" : "Διαγραφή κανόνα...", +"message.delete.sslcertificate" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το πιστοποιητικό.", +"message.delete.static.route.failed" : "Απέτυχε η διαγραφή της στατικής διαδρομής", +"message.delete.static.route.processing" : "Διαγραφή στατικής διαδρομής...", +"message.delete.tag.failed" : "Απέτυχε η διαγραφή της ετικέτας", +"message.delete.tag.for.networkacl" : "Κατάργηση ετικέτας για networkacl", +"message.delete.tag.processing" : "Διαγραφή ετικέτας...", +"message.delete.user" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτόν το χρήστη.", +"message.delete.vpn.connection" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε τη σύνδεση VPN", +"message.delete.vpn.customer.gateway" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την πύλη πελάτη VPN", +"message.delete.vpn.gateway" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την πύλη VPN", +"message.deleting.vm" : "Διαγραφή εικονικής μηχανής", +"message.deployasis" : "Το επιλεγμένο πρότυπο μπορεί να χρησιμοποιηθεί χωρίς αλλαγές (as-is). To VM θα εισάγει ένα OVA με vApps απευθείας απο το Virtual Center. Οι κύριοι δίσκοι μπορούν να αλλάξουν μέγεθος μόνο αν είναι σε κατάσταση σταματημένη για αυτά πρότυπα", +"message.desc.add.new.lb.sticky.rule" : "Προσθήκη νέου αυτοκόλλητου κανόνα LB", +"message.desc.advanced.zone" : "Για πιο εξελιγμένες τοπολογίες δικτύου. Αυτό το μοντέλο δικτύου παρέχει τη μεγαλύτερη ευελιξία στον ορισμό των δικτύων επισκεπτών και στην παροχή προσαρμοσμένων προσφορών δικτύου, όπως υποστήριξη τείχους προστασίας, VPN ή εξισορρόπησης φόρτου.", +"message.desc.basic.zone" : "Παρέχετε ένα μόνο δίκτυο όπου σε κάθε εικονική μηχανή VM εκχωρείται μια διεύθυνση IP απευθείας από το δίκτυο. Η απομόνωση των επισκεπτών μπορεί να παρέχεται μέσω των μέσων επιπέδου 3, όπως ομάδες ασφαλείας (φιλτράρισμα πηγαία διευθύνσεων IP).", +"message.desc.cluster" : "Κάθε υποομάδα (pod) πρέπει να περιέχει ένα ή περισσότερα συμπλέγματα, και θα προσθέσουμε το πρώτο σύμπλεγμα τώρα. Ένα σύμπλεγμα παρέχει έναν τρόπο ομαδοποίησης κεντρικών υπολογιστών. Οι κεντρικοί υπολογιστές σε ένα σύμπλεγμα έχουν όλοι πανομοιότυπο υλικό, εκτελούν τον ίδιο Hypervisor, βρίσκονται στο ίδιο υποδίκτυο και έχουν πρόσβαση στον ίδιο κοινόχρηστο χώρο αποθήκευσης. Κάθε σύμπλεγμα αποτελείται από έναν ή περισσότερους κεντρικούς υπολογιστές και έναν ή περισσότερους κύριους διακομιστές αποθήκευσης.", +"message.desc.create.ssh.key.pair" : "Παρακαλούμε συμπληρώστε τα παρακάτω δεδομένα για να δημιουργήσετε ή να καταχωρήσετε ένα ζεύγος κλειδιών ssh.

(1) Εάν έχει οριστεί δημόσιο κλειδί, το CloudStack θα καταχωρήσει το δημόσιο κλειδί. Μπορείτε να το χρησιμοποιήσετε μέσω του ιδιωτικού σας κλειδιού.

(2) Εάν το δημόσιο κλειδί δεν έχει οριστεί, cloudstack θα δημιουργήσει ένα νέο ζεύγος κλειδιών SSH. Σε αυτήν την περίπτωση, αντιγράψτε και αποθηκεύστε το ιδιωτικό κλειδί. Το CloudStack δεν θα το διατήρησει.
", +"message.desc.created.ssh.key.pair" : "Δημιούργησε ένα ζεύγος κλειδιών SSH.", +"message.desc.host" : "Κάθε σύμπλεγμα πρέπει να περιέχει τουλάχιστον έναν κεντρικό υπολογιστή (υπολογιστή) για να εκτελούνται οι VM επισκεπτών και θα προσθέσουμε τον πρώτο κεντρικό υπολογιστή τώρα. Για να λειτουργήσει ένας κεντρικός υπολογιστής στο CloudStack, πρέπει να εγκαταστήσετε λογισμικό hypervisor στον κεντρικό υπολογιστή, να αντιστοιχίσετε μια διεύθυνση IP στον κεντρικό υπολογιστή και να βεβαιωθείτε ότι ο κεντρικός υπολογιστής είναι συνδεδεμένος στο διακομιστή διαχείρισης CloudStack.

Δώστε τη διεύθυνση DNS ή IP του κεντρικού υπολογιστή, το όνομα χρήστη (συνήθως root) και τον κωδικό πρόσβασης, καθώς και τυχόν ετικέτες που χρησιμοποιείτε για να κατηγοριοποιήσετε κεντρικούς υπολογιστές.", +"message.desc.primary.storage" : "Κάθε σύμπλεγμα πρέπει να περιέχει έναν ή περισσότερους πρωτεύοντες διακομιστές αποθήκευσης και θα προσθέσουμε τον πρώτο τώρα. Ο κύριος χώρος αποθήκευσης περιέχει τους τόμους δίσκων για όλους τους VM που εκτελούνται σε κεντρικούς υπολογιστές του ομοταξίας. Χρησιμοποιήστε οποιοδήποτε πρωτόκολλο συμβατό με πρότυπα που υποστηρίζεται από τον υποκείμενο Hypervisor.", +"message.desc.reset.ssh.key.pair" : "Καθορίστε ένα ζεύγος κλειδιών ssh που θέλετε να προσθέσετε σε αυτήν την εικονική μηχανή. Σημειώστε ότι ο ριζικός κωδικός πρόσβασης θα αλλάξει από αυτήν τη λειτουργία, εάν είναι ενεργοποιημένος ο κωδικός πρόσβασης.", +"message.desc.secondary.storage" : "Κάθε ζώνη πρέπει να έχει τουλάχιστον ένα NFS ή δευτερεύοντα διακομιστή αποθήκευσης, και θα προσθέσουμε το πρώτο τώρα. Ο δευτερεύων χώρος αποθήκευσης αποθηκεύει πρότυπα VM, εικόνες ISO και στιγμιότυπα τόμου δίσκου VM. Αυτός ο διακομιστής πρέπει να είναι διαθέσιμος σε όλους τους κεντρικούς υπολογιστές της ζώνης.

Δώστε τη διεύθυνση IP και την εξαγόμενη διαδρομή.", +"message.desc.zone" : "Μια ζώνη είναι η μεγαλύτερη οργανική μονάδα στο CloudStack και συνήθως αντιστοιχεί σε ένα μόνο κέντρο δεδομένων. Οι ζώνες παρέχουν φυσική απομόνωση και πλεονασμό. Μια ζώνη αποτελείται από ένα ή περισσότερα pods (καθένα από τα οποία περιέχει κεντρικούς υπολογιστές και πρωτεύοντες διακομιστές αποθήκευσης) και έναν δευτερεύοντα διακομιστή αποθήκευσης, ο οποίος είναι κοινόχρηστος από όλα τα pods της ζώνης.", +"message.detach.disk" : "Είστε βέβαιοι ότι θέλετε να αποσυνδέσετε αυτόν το δίσκο;", +"message.detach.iso.confirm" : "Επιβεβαιώστε ότι θέλετε να αποσυνδέσετε το ISO από αυτήν την εικονική εικονική μηχανή.", +"message.diagnostics.exitcode" : "exitcode: var", +"message.diagnostics.stderr" : "exitcode: var", +"message.diagnostics.stdout" : "exitcode: var", +"message.disable.account" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε αυτόν το λογαριασμό. Απενεργοποιώντας το λογαριασμό, όλοι οι χρήστες αυτού του λογαριασμού δεν θα έχουν πλέον πρόσβαση στους πόρους τους στο cloud. Όλες οι εικονικές μηχανές που εκτελούνται θα τερματιστούν αμέσως.", +"message.disable.snapshot.policy" : "Έχετε απενεργοποιήσει με επιτυχία την τρέχουσα πολιτική στιγμιοτύπων.", +"message.disable.user" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε αυτόν το χρήστη.", +"message.disable.vpn" : "Είστε βέβαιοι ότι θέλετε να απενεργοποιήσετε το VPN;", +"message.disable.vpn.access" : "Επιβεβαιώστε ότι θέλετε να απενεργοποιήσετε το VPN απομακρυσμένης πρόσβασης.", +"message.disable.vpn.failed" : "Απέτυχε η απενεργοποίηση του VPN", +"message.disable.vpn.processing" : "Απενεργοποίηση VPN...", +"message.disabling.network.offering" : "Απενεργοποίηση προσφοράς VPN...", +"message.disabling.vpc.offering" : "Απενεργοποίηση προσφοράς υπηρεσίας VPC", +"message.disallowed.characters" : "Disallowed character <,>", +"message.discovering.feature" : "Ανακαλύπτοντας χαρακτηριστικά, περιμένετε...", +"message.disk.offering.created" : "Disk offering created:", +"message.download.diagnostics" : "Επιλέξτε τον κάτωθι σύνδεσμο για να κατεβάσετε τα διαγνωστικά:

00000", +"message.download.iso" : "Επιλέξτε τον κάτωθι σύνδεσμο για να κατεβάσετε το ISO::

00000", +"message.download.template" : "Επιλέξτε τον κάτωθι σύνδεσμο για να κατεβάσετε το πρότυπο:

00000", +"message.download.volume" : "Επιλέξτε τον κάτωθι σύνδεσμο για να κατεβάσετε τον τόμο:

00000", +"message.download.volume.confirm" : "Επιβεβαιώστε ότι θέλετε να κάνετε λήψη αυτού του τόμου.", +"message.edit.account" : "Επεξεργασία (\"-1\" δηλώνει ότι δεν υπάρχει όριο στο ποσό των πόρων που δημιουργούνται)", +"message.edit.acl.failed" : "Απέτυχε η επεξεργασία του κανόνα ACL", +"message.edit.acl.processing" : "Επεξεργασία κανόνα ACL...", +"message.edit.confirm" : "Επιβεβαιώστε τις αλλαγές σας πριν κάνετε κλικ στο κουμπί \"Αποθήκευση\".", +"message.edit.limits" : "Καθορίστε όρια στους ακόλουθους πόρους. Ένα \"-1\" δηλώνει ότι δεν υπάρχει όριο στο ποσό των πόρων που δημιουργούνται.", +"message.edit.rule.failed" : "Απέτυχε η επεξεργασία του κανόνα", +"message.edit.rule.processing" : "Ενημέρωση κανόνα...", +"message.edit.traffic.type" : "Καθορίστε την ετικέτα κίνησης που θέλετε να σχετίζεται με αυτόν τον τύπο κίνησης.", +"message.enable.account" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε αυτόν το λογαριασμό.", +"message.enable.netsacler.provider.failed" : "απέτυχε η ενεργοποίηση της υπηρεσίας παροχής Netsccaler", +"message.enable.securitygroup.provider.failed" : "Απέτυχε η ενεργοποίηση της υπηρεσίας παροχής ομάδας ασφαλείας", +"message.enable.user" : "Επιβεβαιώστε ότι θέλετε να ενεργοποιήσετε αυτόν το χρήστη.", +"message.enable.vpn" : "Επιβεβαιώστε ότι θέλετε να είναι ενεργοποιημένο το VPN απομακρυσμένης πρόσβασης για αυτήν τη διεύθυνση IP.", +"message.enable.vpn.access" : "Το VPN είναι απενεργοποιημένο αυτήν τη στιγμή για αυτήν τη διεύθυνση IP. Θέλετε να ενεργοποιήσετε την πρόσβαση VPN;", +"message.enable.vpn.failed" : "Απέτυχε η ενεργοποίηση του VPN", +"message.enable.vpn.processing" : "Ενεργοποίηση VPN...", +"message.enabled.vpn" : "Το VPN απομακρυσμένης πρόσβασης είναι επί του παρόντος ενεργοποιημένο και είναι προσβάσιμο μέσω της", +"message.enabled.vpn.ip.sec" : "Το προ-κοινόχρηστο κλειδί IPSec είναι", +"message.enabled.vpn.note" : "Σημείωση: Οι χρήστες VPN μπορούν να παραμετροποιηθούν απο το μενού networks", +"message.enabling.network.offering" : "Ενεργοποίηση προσφοράς υπηρεσίας δικτύου", +"message.enabling.security.group.provider" : "Ενεργοποίηση της υπηρεσίας παροχής ομάδας ασφαλείας", +"message.enabling.vpc.offering" : "Ενεργοποίηση προσφοράς υπηρεσίας VPC", +"message.enabling.zone" : "Ενεργοποίηση ζώνης", +"message.enabling.zone.dots" : "Ενεργοποίηση ζώνης...", +"message.enter.seperated.list.multiple.cidrs" : "Εισαγάγετε μια λίστα CIDR διαχωρισμένων με κόμματα, εάν υπάρχουν περισσότερα από ένα", +"message.enter.token" : "Πληκτρολογήστε το διακριτικό που σας δόθηκε στο μήνυμα ηλεκτρονικού ταχυδρομείου πρόσκλησης.", +"message.error.access.key" : "Πληκτρολογήστε το κλειδί πρόσβασης", +"message.error.add.guest.network" : "Τα πεδία IPv4 ή τα πεδία IPv6 πρέπει να συμπληρωθούν κατά την προσθήκη ενός δικτύου επισκεπτών", +"message.error.add.secondary.ipaddress" : "Παρουσιάστηκε σφάλμα κατά την προσθήκη της δευτερεύουσας διεύθυνσης IP", +"message.error.agent.password" : "Πληκτρολογήστε τον κωδικό πρόσβασης του agent", +"message.error.agent.username" : "Πληκτρολογήστε το όνομα χρήστη του agent", +"message.error.binaries.iso.url" : "Πληκτρολογήστε δυαδικά αρχεία ISO URL", +"message.error.bucket" : "Παρακαλώ εισάγετε κάδο", +"message.error.cloudian.console" : "Η καθολική σύνδεση απέτυχε για την κονσόλα διαχείρισης cloudian. Ζητήστε από το διαχειριστή σας να διορθώσει προβλήματα ενοποίησης.", +"message.error.cluster.description" : "Πληκτρολογήστε την περιγραφή του ομοταξίας Kubernetes", +"message.error.cluster.name" : "Πληκτρολογήστε το όνομα του ομοταξίας", +"message.error.confirm.password" : "Επιβεβαιώστε τον νέο κωδικό πρόσβασης", +"message.error.current.password" : "Πληκτρολογήστε τον τρέχοντα κωδικό πρόσβασης", +"message.error.custom.disk.size" : "Πληκτρολογήστε προσαρμοσμένο μέγεθος δίσκου", +"message.error.date" : "Επιλέξτε μια ημερομηνία", +"message.error.description" : "Πληκτρολογήστε την περιγραφή", +"message.error.discovering.feature" : "Εντοπίστηκε εξαίρεση κατά τον εντοπισμό δυνατοτήτων", +"message.error.display.text" : "Πληκτρολογήστε εμφανιζόμενο κείμενο", +"message.error.domain" : "Εισάγετε τον τομέα σας, αφήστε κενό για τον τομέα ROOT", +"message.error.enable.saml" : "Δεν είναι δυνατή η εύρεση των id χρηστών για την ενεργοποίηση του Saml σύνδεση μιας φοράς, παρακαλούμε να το ενεργοποιήσετε με μη αυτόματο τρόπο.", +"message.error.endip" : "Πληκτρολογήστε End IP", +"message.error.gateway" : "Πληκτρολογήστε Πύλη", +"message.error.host.name" : "Πληκτρολογήστε το όνομα του κεντρικού υπολογιστή", +"message.error.host.password" : "Πληκτρολογήστε τον κωδικό πρόσβασης κεντρικού υπολογιστή", +"message.error.host.tags" : "Πληκτρολογήστε ετικέτες κεντρικού υπολογιστή", +"message.error.host.username" : "Πληκτρολογήστε το όνομα χρήστη του κεντρικού υπολογιστή", +"message.error.hypervisor.type" : "Επιλέξτε τύπο Hypervisor", +"message.error.input.value" : "Πληκτρολογήστε την τιμή", +"message.error.internal.dns1" : "Πληκτρολογήστε εσωτερικό DNS 1", +"message.error.internal.dns2" : "Πληκτρολογήστε Εσωτερικό DNS 2", +"message.error.internallb.instance.port" : "Καθορίστε μια θύρα εικονική μηχανής", +"message.error.internallb.name" : "Καθορίστε ένα όνομα για το εσωτερικό LB", +"message.error.internallb.source.port" : "Καθορίστε μια πηγαία θύρα", +"message.error.invalid.range" : "Εισαγάγετε τιμές από το 0 έως το 1", +"message.error.ip.range" : "Πληκτρολογήστε έγκυρο εύρος", +"message.error.ipv4.address" : "Πληκτρολογήστε μια έγκυρη διεύθυνση IPv4", +"message.error.ipv4.dns1" : "Πληκτρολογήστε IpV4 DNS 1", +"message.error.ipv4.dns2" : "Πληκτρολογήστε IpV4 DNS 2", +"message.error.ipv6.address" : "Πληκτρολογήστε μια έγκυρη διεύθυνση IP v6.", +"message.error.ipv6.cidr" : "Πληκτρολογήστε IpV6 CIDR", +"message.error.ipv6.dns1" : "Πληκτρολογήστε IpV6 DNS 1", +"message.error.ipv6.dns2" : "Πληκτρολογήστε IpV6 DNS 2", +"message.error.ipv6.gateway" : "Πληκτρολογήστε πύλη IpV6", +"message.error.ipv6.gateway.format" : "Πληκτρολογήστε μια έγκυρη πύλη IPv6.", +"message.error.kubecluster.name" : "Πληκτρολογήστε το όνομα ομοταξίας Kubernetes", +"message.error.kuberversion" : "Πληκτρολογήστε kubernetes σημασιολογική έκδοση", +"message.error.limit.value" : "Η τιμή δεν πρέπει να είναι μικρότερη από", +"message.error.loading.setting" : "Παρουσιάστηκε σφάλμα κατά τη φόρτωση αυτών των ρυθμίσεων.", +"message.error.lun" : "Πληκτρολογήστε LUN #", +"message.error.macaddress" : "Πληκτρολογήστε μια έγκυρη διεύθυνση MAC.", +"message.error.name" : "Πληκτρολογήστε το όνομα", +"message.error.netmask" : "Πληκτρολογήστε Netmask", +"message.error.network.domain" : "Πληκτρολογήστε τομέα δικτύου", +"message.error.network.offering" : "Επιλέξτε προσφορά δικτύου", +"message.error.new.password" : "Πληκτρολογήστε νέο κωδικό πρόσβασης", +"message.error.nexus1000v.ipaddess" : "Πληκτρολογήστε Nexus 1000v ΔΙΕΎΘΥΝΣΗ IP", +"message.error.nexus1000v.password" : "Παρακαλώ εισάγετε Nexus 1000v κωδικός πρόσβασης", +"message.error.nexus1000v.username" : "Παρακαλώ εισάγετε Nexus 1000v όνομα χρήστη", +"message.error.number" : "Πληκτρολογήστε έναν έγκυρο αριθμό", +"message.error.password" : "Πληκτρολογήστε τον κωδικό πρόσβασής σας", +"message.error.path" : "Πληκτρολογήστε διαδρομή", +"message.error.provide.setting" : "Πρέπει να παρέχει ένα έγκυρο κλειδί και τιμή για τη ρύθμιση", +"message.error.rados.monitor" : "Πληκτρολογήστε RADOS Monitor", +"message.error.rados.pool" : "Παρακαλώ εισάγετε rados πισίνα", +"message.error.rados.secret" : "Παρακαλώ εισάγετε RADOS Μυστικό", +"message.error.rados.user" : "Πληκτρολογήστε rados χρήστη", +"message.error.remove.nic" : "Παρουσιάστηκε σφάλμα", +"message.error.remove.secondary.ipaddress" : "Παρουσιάστηκε σφάλμα κατά την κατάργηση της δευτερεύουσας διεύθυνσης IP", +"message.error.required.input" : "Εισαγάγετε είσοδο", +"message.error.retrieve.kubeconfig" : "Δεν είναι δυνατή η ανάκτηση του ομοταξίας Kubernetes", +"message.error.s3nfs.path" : "Πληκτρολογήστε S3 NFS Path", +"message.error.s3nfs.server" : "Πληκτρολογήστε S3 NFS Server", +"message.error.save.setting" : "Παρουσιάστηκε σφάλμα κατά την αποθήκευση αυτής της ρύθμισης.", +"message.error.sbdomain" : "Πληκτρολογήστε τομέα SMB", +"message.error.sbdomain.password" : "Πληκτρολογήστε τον κωδικό πρόσβασης τομέα SMB", +"message.error.sbdomain.username" : "Πληκτρολογήστε όνομα χρήστη τομέα SMB", +"message.error.secret.key" : "Πληκτρολογήστε μυστικό κλειδί", +"message.error.select" : "Επιλέξτε την επιλογή", +"message.error.select.domain.to.dedicate" : "Επιλέξτε τομέα για να αφιερώσετε", +"message.error.select.zone.type" : "Επιλέξτε τον τύπο ζώνης παρακάτω.", +"message.error.server" : "Πληκτρολογήστε το διακομιστή", +"message.error.serviceoffering.for.cluster" : "Επιλέξτε την προσφορά υπηρεσιών για το σύμπλεγμα Kubernetes", +"message.error.size" : "Πληκτρολογήστε μέγεθος σε GB", +"message.error.size.for.cluster" : "Πληκτρολογήστε μέγεθος για το σύμπλεγμα Kubernetes", +"message.error.smb.password" : "Πληκτρολογήστε τον κωδικό πρόσβασης SMB", +"message.error.smb.username" : "Πληκτρολογήστε όνομα χρήστη SMB", +"message.error.specify.sticky.name" : "Καθορίστε ένα sticky όνομα", +"message.error.sr.namelabel" : "Πληκτρολογήστε όνομα-ετικέτα sr", +"message.error.startip" : "Πληκτρολογήστε IP Έναρξης ", +"message.error.storage.tags" : "Εισαγάγετε ετικέτες αποθήκευσης", +"message.error.target.iqn" : "Παρακαλώ εισάγετε IQN στόχου", +"message.error.time" : "Επιλέξτε ώρα", +"message.error.traffic.label" : "Πληκτρολογήστε ετικέτα κίνησης", +"message.error.try.save.setting" : "Παρουσιάστηκε σφάλμα κατά την αποθήκευση αυτής της ρύθμισης. Προσπαθήστε ξανά αργότερα.", +"message.error.upload.iso.description" : "Μόνο ένα ISO μπορεί να φορτωθεί κάθε φορά", +"message.error.upload.template" : "Η αποστολή του προτύπου απέτυχε", +"message.error.upload.template.description" : "Μόνο ένα πρότυπο μπορεί να αποσταλεί κάθε φορά", +"message.error.url" : "Πληκτρολογήστε διεύθυνση URL", +"message.error.username" : "Εισάγετε το όνομα χρήστη σας", +"message.error.vcenter.datacenter" : "Πληκτρολογήστε vCenter Datacenter", +"message.error.vcenter.datastore" : "Πληκτρολογήστε vCenter Datastore", +"message.error.vcenter.host" : "Πληκτρολογήστε vCenter Host", +"message.error.vcenter.password" : "Πληκτρολογήστε τον κωδικό πρόσβασης vCenter", +"message.error.vcenter.username" : "Πληκτρολογήστε όνομα χρήστη vCenter", +"message.error.version.for.cluster" : "Επιλέξτε την έκδοση Kubernetes για το σύμπλεγμα Kubernetes", +"message.error.vlan.range" : "Πληκτρολογήστε μια έγκυρη περιοχή VLAN/VNI", +"message.error.volume.name" : "Πληκτρολογήστε το όνομα τόμου", +"message.error.volumne" : "Πληκτρολογήστε Τόμος", +"message.error.volumne.group" : "Εισαγάγετε την ομάδα τόμων", +"message.error.zone" : "Επιλέξτε μια ζώνη", +"message.error.zone.combined" : "Όλες οι ζώνες δεν μπορούν να συνδυαστούν με οποιαδήποτε άλλη ζώνη", +"message.error.zone.for.cluster" : "Επιλέξτε ζώνη για σύμπλεγμα Kubernetes", +"message.error.zone.name" : "Πληκτρολογήστε το όνομα της ζώνης", +"message.error.zone.type" : "Επιλέξτε τύπο ζώνης", +"message.fail.to.delete" : "Απέτυχε η διαγραφή.", +"message.failed.to.add" : "Απέτυχε η προσθήκη", +"message.failed.to.assign.vms" : "Απέτυχε η αντιστοίχιση VM", +"message.failed.to.remove" : "Απέτυχε η κατάργηση", +"message.generate.keys" : "Επιβεβαιώστε ότι θέλετε να δημιουργήσετε νέα κλειδιά για αυτόν το χρήστη.", +"message.gslb.delete.confirm" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το GSLB", +"message.gslb.lb.remove.confirm" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε την εξισορρόπηση φόρτου από το GSLB", +"message.guest.traffic.in.advanced.zone" : "Η κίνηση δικτύου επισκεπτών είναι η επικοινωνία μεταξύ εικονικών μηχανών τελικού χρήστη. Καθορίστε μια περιοχή των id VLAN για τη μεταφορά της κίνησης των επισκεπτών για κάθε φυσικό δίκτυο.", +"message.guest.traffic.in.basic.zone" : "Η κίνηση δικτύου επισκεπτών είναι η επικοινωνία μεταξύ εικονικών μηχανών τελικού χρήστη. Καθορίστε μια περιοχή διευθύνσεων IP που μπορεί να αντιστοιχίσει το CloudStack σε VM επισκέπτη. Βεβαιωθείτε ότι αυτή η περιοχή δεν επικαλύπτει την δεσμευμένη περιοχή IP του συστήματος.", +"message.guestnetwork.state.allocated" : "Υποδεικνύει ότι η ρύθμιση παραμέτρων δικτύου έχει εκχωρηθεί, αλλά δεν έχει ρυθμιστεί", +"message.guestnetwork.state.destroy" : "Υποδεικνύει ότι το δίκτυο έχει καταστραφεί", +"message.guestnetwork.state.implemented" : "Υποδεικνύει ότι η ρύθμιση παραμέτρων δικτύου χρησιμοποιείται", +"message.guestnetwork.state.implementing" : "Υποδεικνύει ότι η ρύθμιση παραμέτρων δικτύου υλοποιείται", +"message.guestnetwork.state.setup" : "Υποδεικνύει ότι η ρύθμιση παραμέτρων δικτύου έχει ρυθμιστεί", +"message.guestnetwork.state.shutdown" : "Υποδεικνύει ότι η ρύθμιση παραμέτρων δικτύου καταστρέφεται", +"message.host.dedicated" : "Ο κεντρικος υπολογιστής είναι αποκλειστικής διάθεσης", +"message.host.dedication.released" : "Η αποκλειστική διάθεση του κεντρικου υπολογιστή Αποδεσμεύτηκε", +"message.info.cloudian.console" : "Η κονσόλα διαχείρισης Cloudian πρέπει να ανοίξει σε άλλο παράθυρο", +"message.installwizard.click.retry" : "Κάντε κλικ στο κουμπί για να προσπαθήσετε ξανά να ξεκινήσετε.", +"message.installwizard.copy.whatisacluster" : "Ένα σύμπλεγμα παρέχει έναν τρόπο ομαδοποίησης κεντρικών υπολογιστών. Οι κεντρικοί υπολογιστές σε ένα σύμπλεγμα έχουν όλοι πανομοιότυπο υλικό, εκτελούν τον ίδιο Hypervisor, βρίσκονται στο ίδιο υποδίκτυο και έχουν πρόσβαση στον ίδιο κοινόχρηστο χώρο αποθήκευσης. Οι παρουσίες εικονικής μηχανής (VM) μπορούν να μετεγκατασταθούν ζωντανά από έναν κεντρικό υπολογιστή σε έναν άλλο μέσα στο ίδιο σύμπλεγμα, χωρίς να διακοπεί η υπηρεσία στο χρήστη. Ένα σύμπλεγμα είναι η τρίτη μεγαλύτερη οργανωτική μονάδα μέσα σε ένα CloudStack™. Ανάπτυξης. Οι συστάδες περιέχονται μέσα σε pods, και τα pods περιέχονται μέσα στις ζώνες.

CloudStack™; Επιτρέπει πολλά συμπλέγματα σε μια ανάπτυξη σύννεφο, αλλά για μια βασική εγκατάσταση, χρειαζόμαστε μόνο ένα σύμπλεγμα.", +"message.installwizard.copy.whatisahost" : "Ένας κεντρικός υπολογιστής είναι ένας μεμονωμένος υπολογιστής. Οι κεντρικοί υπολογιστές παρέχουν τους πόρους υπολογιστών που εκτελούν τις εικονικές μηχανές επισκεπτών. Κάθε κεντρικός υπολογιστής έχει το λογισμικό hypervisor εγκατεστημένο για να διαχειριστεί τα vms φιλοξενουμένων (εκτός από τους bare metal κεντρικούς υπολογιστές, οι οποίοι είναι μια πρόσθετη περίπτωση που συζητείται στον προηγμένο οδηγό εγκαταστάσεων). Για παράδειγμα, ένας διακομιστής με δυνατότητα Linux KVM, ένας διακομιστής Citrix XenServer και ένας διακομιστής ESXi είναι κεντρικοί υπολογιστές. Σε μια βασική εγκατάσταση, χρησιμοποιούμε έναν μόνο κεντρικό υπολογιστή που εκτελεί XenServer ή KVM.

Ο κεντρικός υπολογιστής είναι η μικρότερη οργανική μονάδα μέσα σε ένα CloudStack™. Ανάπτυξης. Οι κεντρικοί υπολογιστές περιέχονται σε συστοιχίες, οι συστοιχίες περιέχονται μέσα σε pods και τα pods περιέχονται σε ζώνες.", +"message.installwizard.copy.whatisapod" : "Ένα pod αντιπροσωπεύει συχνά ένα ενιαίο rack. Οι κεντρικοί υπολογιστές στο ίδιο pod είναι στο ίδιο υποδίκτυο.

Ένα pod είναι η δεύτερη μεγαλύτερη οργανωτική μονάδα μέσα σε μια εγκατάσταση CloudStack™. Τα pods περιέχονται σε ζώνες. Κάθε ζώνη μπορεί να περιέχει ένα ή περισσότερα pods? στη βασική εγκατάσταση, θα έχετε μόνο ένα pod στη ζώνη σας.", +"message.installwizard.copy.whatisazone" : "Μια ζώνη είναι η μεγαλύτερη οργανωτική μονάδα μέσα σε μια εγκατάσταση CloudStack™. Μια ζώνη συνήθως αντιστοιχεί σε ένα μόνο κέντρο δεδομένων, αν και επιτρέπεται να υπάρχουν πολλές ζώνες σε ένα κέντρο δεδομένων. Το όφελος της οργάνωσης των υποδομών σε ζώνες είναι η παροχή φυσικής απομόνωσης και πλεονασμού. Για παράδειγμα, κάθε ζώνη μπορεί να έχει τη δική της σύνδεση παροχής ενέργειας και δικτύου και οι ζώνες μπορούν να διαχωριστούν ευρέως γεωγραφικά (αν και αυτό δεν απαιτείται).", +"message.installwizard.copy.whatiscloudstack" : "Το CloudStack™ είναι μια πλατφόρμα λογισμικού που συγκεντρώνει υπολογιστικούς πόρους για τη δημιουργία δημόσιων, ιδιωτικών και υβριδικών υποδομων ως υπηρεσίας (IaaS) cloud. Το CloudStack™ διαχειρίζεται τους κόμβους δικτύου, αποθήκευσης και υπολογισμού που αποτελούν μια υποδομή cloud. Χρησιμοποιήστε το CloudStack™ για να αναπτύξετε, να διαχειριστείτε και να ρυθμίσετε τις παραμέτρους περιβαλλόντων Cloud.\n\nΤο CloudStack™ παρέχει μια στοίβα λογισμικού υποδομής cloud για την παροχή εικονικών κέντρων δεδομένων ως υπηρεσία - παρέχοντας όλα τα βασικά στοιχεία για τη δημιουργία, την ανάπτυξη και τη διαχείριση εφαρμογών cloud πολλαπλών επιπέδων και πολλών tenants. Και οι εκδόσεις ανοιχτού κώδικα και Premium είναι διαθέσιμες, με την έκδοση ανοιχτού κώδικα να προσφέρει σχεδόν πανομοιότυπα χαρακτηριστικά.", +"message.installwizard.copy.whatisprimarystorage" : "Μία CloudStack™; υποδομή χρησιμοποιεί δύο τύπους αποθηκευτικού χώρου. Πρωτεύον και Δευτερεύον. Και τα δύο μπορούν να είναι iSCSI ή NFS ή τοπικοί δίσκοι.ο

πρωτεύον αποθηκευτικός χώρος ορίζεται στις συστοιχίες (cluster) και αποθηκεύει τους τόμους δίσκων των εικονικών μηχανών (VM). Γι αυτό το σκοπό βρίσκεται κοντά στους διακομιστές", +"message.installwizard.copy.whatissecondarystorage" : "Ο δευτερεύον χώρος αποθήκευσης λειτουργεί με τις ζωνες και αποθηκεύει τα παρακάτω:

  • Πρότυπα - OS είδωλα που χρησμιποιούνται για την εκκίνηση των VMs και μπορούν να περιλαμβάνουν περεταίρω πληροφορίες όπως οι εγκατεστήμενες εφαρμογές
  • ISO είδωλα - OS images που μπορεί να είναι εκκινήσημα ή όχι
  • Στιγμιότυπα απο τόμους - αποθηκευμένα αντίγραφα που μπορούν να χρησιμοποιηθούν για ανάκτηση δεδομένων ή για την δημιουργία νέων προτύπων
", +"message.installwizard.now.building" : "Τώρα υλοποιείται το cloud σας ...", +"message.installwizard.tooltip.addcluster.name" : "Ένα όνομα για το σύμπλεγμα. Αυτό μπορεί να είναι κείμενο της επιλογής σας και δεν χρησιμοποιείται από το CloudStack.", +"message.installwizard.tooltip.addhost.hostname" : "Το όνομα DNS ή η διεύθυνση IP του κεντρικού υπολογιστή.", +"message.installwizard.tooltip.addhost.password" : "Αυτός είναι ο κωδικός πρόσβασης για το χρήστη που ονομάζεται παραπάνω (από την εγκατάσταση του XenServer).", +"message.installwizard.tooltip.addhost.username" : "Συνήθως root.", +"message.installwizard.tooltip.addpod.name" : "Ένα όνομα για το pod", +"message.installwizard.tooltip.addpod.reservedsystemendip" : "Αυτή είναι η περιοχή IP στο ιδιωτικό δίκτυο που χρησιμοποιεί το CloudStack για τη διαχείριση των VM δευτερεύουσας αποθήκευσης και των vm διακομιστή μεσολάβησης κονσόλας. Αυτές οι διευθύνσεις IP λαμβάνονται από το ίδιο υποδίκτυο με τους διακομιστές υπολογιστών.", +"message.installwizard.tooltip.addpod.reservedsystemgateway" : "Η πύλη για τους κεντρικους υπολογιστές σε αυτό το pod.", +"message.installwizard.tooltip.addpod.reservedsystemnetmask" : "Η μάσκα δικτύου που χρησιμοποιείται στο υποδίκτυο που θα χρησιμοποιήσουν οι επισκέπτες.", +"message.installwizard.tooltip.addpod.reservedsystemstartip" : "Αυτή είναι η περιοχή IP στο ιδιωτικό δίκτυο που χρησιμοποιεί το CloudStack για τη διαχείριση των VM δευτερεύουσας αποθήκευσης και των vm διακομιστή μεσολάβησης κονσόλας. Αυτές οι διευθύνσεις IP λαμβάνονται από το ίδιο υποδίκτυο με τους διακομιστές υπολογιστών.", +"message.installwizard.tooltip.addprimarystorage.name" : "Το όνομα της συσκευής αποθήκευσης.", +"message.installwizard.tooltip.addprimarystorage.path" : "(για NFS) Στο NFS αυτή είναι η διαδρομή που εξάγεται από το διακομιστή. Διαδρομή (για κοινόχρηστο σημείο). Με το KVM αυτή είναι η διαδρομή σε κάθε κεντρικό υπολογιστή που είναι το σημείο όπου έχει μονταριστεί αυτός ο κύριος χώρος αποθήκευσης. Για παράδειγμα, \"/mnt/primary\".", +"message.installwizard.tooltip.addprimarystorage.server" : "(για NFS, iSCSI ή προρύθμιση) Η διεύθυνση IP ή το όνομα DNS της συσκευής αποθήκευσης.", +"message.installwizard.tooltip.addsecondarystorage.nfsserver" : "Η διεύθυνση IP του διακομιστή NFS που φιλοξενεί τον δευτερεύοντα χώρο αποθήκευσης", +"message.installwizard.tooltip.addsecondarystorage.path" : "Η διαδρομή εξαγωγής, που βρίσκεται στο διακομιστή που καθορίσατε παραπάνω", +"message.installwizard.tooltip.addzone.dns1" : "Αυτοί είναι διακομιστές DNS για χρήση από vm επισκέπτη στη ζώνη. Αυτοί οι διακομιστές DNS θα προσεγγιστούν μέσω του δημόσιου δικτύου που θα προσθέσετε αργότερα. Οι δημόσιες διευθύνσεις IP για τη ζώνη πρέπει να έχουν μια διαδρομή προς το διακομιστή DNS που ονομάζεται εδώ.", +"message.installwizard.tooltip.addzone.dns2" : "Αυτοί είναι διακομιστές DNS για χρήση από vm επισκέπτη στη ζώνη. Αυτοί οι διακομιστές DNS θα προσεγγιστούν μέσω του δημόσιου δικτύου που θα προσθέσετε αργότερα. Οι δημόσιες διευθύνσεις IP για τη ζώνη πρέπει να έχουν μια διαδρομή προς το διακομιστή DNS που ονομάζεται εδώ.", +"message.installwizard.tooltip.addzone.internaldns1" : "Αυτοί είναι διακομιστές DNS για χρήση από vm συστήματος στη ζώνη. Αυτοί οι διακομιστές DNS θα προσεγγιστούν μέσω της ιδιωτικής διασύνδεσης δικτύου των VM συστήματος. Η ιδιωτική διεύθυνση IP που παρέχετε για τα pods πρέπει να έχει μια διαδρομή προς το διακομιστή DNS που ονομάζεται εδώ.", +"message.installwizard.tooltip.addzone.internaldns2" : "Αυτοί είναι διακομιστές DNS για χρήση από vm συστήματος στη ζώνη. Αυτοί οι διακομιστές DNS θα προσεγγιστούν μέσω της ιδιωτικής διασύνδεσης δικτύου των VM συστήματος. Η ιδιωτική διεύθυνση IP που παρέχετε για τα pods πρέπει να έχει μια διαδρομή προς το διακομιστή DNS που ονομάζεται εδώ.", +"message.installwizard.tooltip.addzone.name" : "Ένα όνομα για τη ζώνη", +"message.installwizard.tooltip.configureguesttraffic.description" : "Μια περιγραφή για το δίκτυό σας", +"message.installwizard.tooltip.configureguesttraffic.guestendip" : "Το εύρος των διευθύνσεων IP που θα είναι διαθέσιμες για εκχώρηση σε επισκέπτες σε αυτήν τη ζώνη. Εάν χρησιμοποιείται ένα NIC, αυτά τα IP θα πρέπει να είναι στο ίδιο CIDR με το pod CIDR.", +"message.installwizard.tooltip.configureguesttraffic.guestgateway" : "Η πύλη που πρέπει να χρησιμοποιούν οι επισκέπτες", +"message.installwizard.tooltip.configureguesttraffic.guestnetmask" : "Η μάσκα δικτύου που χρησιμοποιείται στο υποδίκτυο που πρέπει να χρησιμοποιούν οι επισκέπτες", +"message.installwizard.tooltip.configureguesttraffic.gueststartip" : "Το εύρος των διευθύνσεων IP που θα είναι διαθέσιμες για εκχώρηση σε επισκέπτες σε αυτήν τη ζώνη. Εάν χρησιμοποιείται ένα NIC, αυτά τα IP θα πρέπει να είναι στο ίδιο CIDR με το pod CIDR.", +"message.installwizard.tooltip.configureguesttraffic.name" : "Ένα όνομα για το δίκτυό σας", +"message.instance.scaled.up.confirm" : "Θέλετε πραγματικά να κλιμακώσετε την εικονική μηχανή σας;", +"message.instancewizard.notemplates" : "Δεν έχετε διαθέσιμα πρότυπα. Προσθέστε ένα συμβατό πρότυπο και ξεκινήστε ξανά τον οδηγό εικονική μηχανής.", +"message.interloadbalance.not.return.elementid" : "Σφάλμα, η εντολή listInternalLoadBalancerElements API δεν επέστρεψε δεδομένα Internal LB element Id", +"message.ip.address.changed" : "Οι διευθύνσεις IP σας μπορεί να έχουν αλλάξει. Θέλετε να ανανεώσετε την καταχώρηση; Σημειώστε ότι σε αυτήν την περίπτωση το παράθυρο λεπτομερειών θα κλείσει.", +"message.iso.desc" : "Εικόνα δίσκου που περιέχει δεδομένα ή μέσα με δυνατότητα εκκίνησης για λειτουργικό σύστημα", +"message.join.project" : "Τώρα έχετε συμμετάσχει σε ένα έργο. Μεταβείτε στην προβολή Project για να δείτε το έργο.", +"message.kubeconfig.cluster.not.available" : "To σύμπλεγμα Kubernetes kubeconfig δεν είναι διαθέσιμo προς το παρόν", +"message.kubernetes.cluster.delete" : "Επιβεβαιώστε ότι θέλετε να καταστρέψετε το σύμπλεγμα", +"message.kubernetes.cluster.scale" : "Επιλέξτε τη ρύθμιση παραμέτρων ομοταξίας που θέλετε", +"message.kubernetes.cluster.start" : "Επιβεβαιώστε ότι θέλετε να ξεκινήσετε το σύμπλεγμα", +"message.kubernetes.cluster.stop" : "Επιβεβαιώστε ότι θέλετε να διακόψετε το σύμπλεγμα", +"message.kubernetes.cluster.upgrade" : "Επιλέξτε νέα έκδοση Kubernetes", +"message.kubernetes.version.delete" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτήν την έκδοση Kubernetes", +"message.launch.vm.on.private.network" : "Θέλετε να ξεκινήσετε την εικονική μηχανή σας στο δικό σας ιδιωτικό αποκλειστικό δίκτυο;", +"message.launch.zone" : "Η ζώνη είναι έτοιμη για εκκίνηση. προχωρήστε στο επόμενο βήμα.", +"message.launch.zone.description" : "Η ζώνη είναι έτοιμη για εκκίνηση. προχωρήστε στο επόμενο βήμα.", +"message.launch.zone.hint" : "Ρύθμιση παραμέτρων στοιχείων δικτύου και κίνησης, συμπεριλαμβανομένων των διευθύνσεων IP.", +"message.ldap.group.import" : "Όλοι οι χρήστες από το συγκεκριμένο όνομα ομάδας θα εισαχθούν", +"message.license.agreements.not.accepted" : "Οι άδειες χρήσης δεν γίνονται δεκτές", +"message.link.domain.to.ldap" : "Ενεργοποίηση αυτόματου συγχρονισμού για αυτόν τον τομέα στο LDAP", +"message.listnsp.not.return.providerid" : "Σφάλμα: η εντολή listNetworkServiceProviders API δεν επέστρεψε δεδομένα VirtualRouter provider ID", +"message.listview.subselect.multi" : "(Ctrl/Cmd-κλικ)", +"message.load.host.failed" : "Απέτυχε η φόρτωση κεντρικών υπολογιστών", +"message.lock.account" : "Επιβεβαιώστε ότι θέλετε να κλειδώσετε αυτόν το λογαριασμό. Με το κλείδωμα του λογαριασμού, όλοι οι χρήστες για αυτόν το λογαριασμό δεν θα μπορούν πλέον να διαχειρίζονται τους πόρους cloud. Η πρόσβαση στους υπάρχοντες πόρους εξακολουθεί να είναι ανοιχτή.", +"message.login.failed" : "Η σύνδεση απέτυχε", +"message.migrate.instance.confirm" : "Επιβεβαιώστε τον κεντρικό υπολογιστή στον οποίο θέλετε να μετεγκαταστήσετε την εικονική εικονική μηχανή.", +"message.migrate.instance.select.host" : "Επιλέξτε έναν κεντρικό υπολογιστή για μετεγκατάσταση", +"message.migrate.instance.to.host" : "Επιβεβαιώστε ότι θέλετε να μετεγκαταστήσετε την εικονική μηχανή σε άλλο κεντρικό υπολογιστή.", +"message.migrate.instance.to.ps" : "Επιβεβαιώστε ότι θέλετε να μετεγκαταστήσετε την εικονική μηχανή σε άλλο πρωτεύοντα χώρο αποθήκευσης.", +"message.migrate.router.confirm" : "Επιβεβαιώστε ότι θέλετε να μετεγκαστήσετε τον δρομολογητή σε:", +"message.migrate.systemvm.confirm" : "Επιβεβαιώστε ότι θέλετε να μετεγκαστήσετε το συστημικό μηχάνημα σε:", +"message.migrate.lb.vm.to.ps" : "Επιβεβαιώστε ότι θέλετε να μετεγκαστήσετε το LB VM σε άλλον πρωτεύοντα χώρο", +"message.migrate.router.to.ps" : "Επιβεβαιώστε ότι θέλετε να μετεγκαστήσετε το δρομολογητή VM σε άλλον πρωτεύοντα χώρο", +"message.migrate.system.vm.to.ps" : "Επιβεβαιώστε ότι θέλετε να μετεγκαστήσετε το συστημικό VM σε άλλον πρωτεύοντα χώρο", +"message.migrate.volume" : "Επιβεβαιώστε ότι θέλετε να μετεγκαταστήσετε όγκο σε άλλο πρωτεύοντα χώρο αποθήκευσης.", +"message.migrate.volume.failed" : "Η μετεγκατάσταση τόμου απέτυχε", +"message.migrate.volume.processing" : "Μετεγκατάσταση τόμου...", +"message.migrating.failed" : "Η μετεγκατάσταση απέτυχε", +"message.migrating.processing" : "Η μετανάστευση σε εξέλιξη για", +"message.migrating.vm.to.host.failed" : "Απέτυχε η μετεγκατάσταση της εικονικής μηχανής στον κεντρικό υπολογιστή", +"message.migrating.vm.to.storage.failed" : "Αποτυχία μετεγκατάστσης VM στον πρωτεύοντα χώρο", +"message.move.acl.order" : "Μετακίνηση σειράς κανόνων ACL", +"message.move.acl.order.failed" : "Απέτυχε η μετακίνηση του κανόνα ACL", +"message.move.acl.order.processing" : "Μετακίνηση κανόνα ACL...", +"message.ncc.delete.confirm" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε αυτό το NCC", +"message.network.acl.default.allow" : "Προσοχή: Με την παρούσα πολιτική όλη η κίνηση διαμέσου του τοίχους ασφαλείας θα επιτραπεί για αυτό το VPC tier. Πρέπει να ασφαλίσεται το δίκτυο σας.", +"message.network.acl.default.deny" : "Προσοχή: Με την παρούσα πολιτική όλη η κίνηση διαμέσου του τοίχους ασφαλείας θα απαγορευτεί για αυτό το VPC tier. Για να επιτρέψετε την επικοινωνία θα πρέπει να αλλάξετε πολιτική.", +"message.network.addvm.desc" : "Καθορίστε το δίκτυο στο οποίο θέλετε να προσθέσετε αυτήν την εικονική μηχανή. Θα προστεθεί μια νέα nic για αυτό το δίκτυο.", +"message.network.addvmnic" : "Επιβεβαιώστε ότι θέλετε να προσθέσετε ένα νέο NIC VM για αυτό το δίκτυο.", +"message.network.description" : "Δίκτυο εγκατάστασης και κίνηση", +"message.network.error" : "Σφάλμα δικτύου", +"message.network.error.description" : "Δεν είναι δυνατή η πρόσβαση στο διακομιστή διαχείρισης ή μια επέκταση προγράμματος περιήγησης ενδέχεται να αποκλείει την αίτηση δικτύου.", +"message.network.hint" : "Ρύθμιση παραμέτρων στοιχείων δικτύου και της δημόσιας/guest/διαχείρισης της κίνησης, συμπεριλαμβανομένων των διευθύνσεων IP.", +"message.network.remote.access.vpn.configuration" : "Δημιουργήθηκε ρύθμιση παραμέτρων VPN απομακρυσμένης πρόσβασης, αλλά απέτυχε να εφαρμοστεί. Ελέγξτε τη σύνδεση του στοιχείου δικτύου και, στη συνέχεια, προσπαθήστε ξανά.", +"message.network.removenic" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε αυτό το NIC, το οποίο θα καταργήσει επίσης το συσχετισμένο δίκτυο από την εικονική μηχανή.", +"message.network.secondaryip" : "Επιβεβαιώστε ότι θέλετε να αντιστοιχήσετε δευτερεύουσα IP σε αυτήν την κάρτα δικτύου.\n Σημείωση: Θα πρέπει να ρυθμίσετε μέσα στην εικονική μηχανή την διαθέσιμη IP χειροκίνητα.", +"message.network.updateip" : "Επιβεβαιώστε ότι θέλετε να αλλάξετε τη διεύθυνση IP για αυτό το NIC σε VM.", +"message.new.user" : "Καθορίστε τα ακόλουθα για να προσθέσετε ένα νέο χρήστη στο λογαριασμό", +"message.no.affinity.groups" : "Δεν έχετε καμία ομάδα συνάφειας. Συνεχίστε στο επόμενο βήμα.", +"message.no.datadisk" : "Το πρότυπο πολλαπλών δίσκων δεν έχει δίσκο δεδομένων, συνεχίστε στο επόμενο βήμα.", +"message.no.description" : "Δεν έχει εισαχθεί περιγραφή.", +"message.no.host.available" : "Δεν υπάρχουν διαθέσιμοι κεντρικοί υπολογιστές για μετεγκατάσταση", +"message.no.label.on.left" : "Δεν υπάρχει ετικέτα στα αριστερά", +"message.no.label.on.right" : "Δεν υπάρχει ετικέτα στα δεξιά", +"message.no.more.hosts.available" : "Δεν υπάρχουν άλλοι διαθέσιμοι κεντρικοί υπολογιστές για μετεγκατάσταση", +"message.no.network.support" : "Ο επιλεγμένος Hypervisorς σας, vSphere, δεν έχει πρόσθετες δυνατότητες δικτύου. Συνεχίστε με το βήμα 5.", +"message.no.network.support.configuration.not.true" : "Δεν έχετε καμία ζώνη που να έχει ενεργοποιημένη την ομάδα ασφαλείας. Έτσι, δεν υπάρχουν πρόσθετες δυνατότητες δικτύου. Συνεχίστε με το βήμα 5.", +"message.no.primary.stores" : "Δεν υπάρχουν διαθέσιμοι χώροι αποθήκευσης πρωτεύοντος χώρου αποθήκευσης για μετεγκατάσταση", +"message.no.projects" : "Δεν έχετε κανένα εργο.
Δημιουργήστε ένα νέο από την ενότητα έργων.", +"message.no.projects.adminonly" : "Δεν έχετε κανένα εργο.
Ζητήστε από το διαχειριστή σας να δημιουργήσει ένα νέο έργο.", +"message.number.clusters" : "

# του Συμπλέγματα

", +"message.number.hosts" : "

# του Κεντρικοί υπολογιστές

", +"message.number.pods" : "

# του pod

", +"message.number.storage" : "

# του Τόμοι πρωτεύοντος χώρου αποθήκευσης

", +"message.number.zones" : "

# του Ζώνες

", +"message.outofbandmanagement.action.maintenance" : "Ο κεντρικός υπολογιστής ειδοποιήσεων βρίσκεται σε λειτουργία συντήρησης", +"message.ovf.configurations" : "Διαθέσιμες διαμορφώσεις OVF για την επιλεγμένη συσκευή. Επιλέξτε την επιθυμητή τιμή. Οι μη συμβατές προσφορές υπηρεσίας υπολογισμού θα αποσυντεθεί.", +"message.ovf.properties.available" : "Υπάρχουν διαθέσιμες ιδιότητες OVF για την προσαρμογή της επιλεγμένης συσκευής. Επεξεργαστείτε τις τιμές ανάλογα.", +"message.password.has.been.reset.to" : "Έγινε επαναφορά του κωδικού πρόσβασης σε", +"message.password.of.the.vm.has.been.reset.to" : "Ο κωδικός πρόσβασης της εικονικής μηχανής επαναπροσδιορίστηκε σε", +"message.path.description" : "NFS: η εξαχθ΄είσα διαδρομή απο τον διακομιστή. VMFS: /datacenter name/datastore name. SharedMountPoint: Διαδρομή που βρίσκεται ο πρωτεύον αποθηκευτικός χώρος, παράδειγμα /mnt/primary", +"message.pending.projects.1" : "Έχετε εκκρεμή πρόσκληση για έργο", +"message.pending.projects.2" : "Για να προβάλετε, μεταβείτε στην ενότητα έργα και, στη συνέχεια, επιλέξτε προσκλήσεις από το πτυσσόμενο μενού.", +"message.please.add.at.lease.one.traffic.range" : "Προσθέστε τουλάχιστον ένα εύρος κίνησης.", +"message.please.confirm.remove.ssh.key.pair" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε αυτό το ζεύγος κλειδιών SSH", +"message.please.enter.value" : "Πληκτρολογήστε τιμές", +"message.please.proceed" : "Προχωρήστε στο επόμενο βήμα.", +"message.please.select.a.configuration.for.your.zone" : "Επιλέξτε μια ρύθμιση παραμέτρων για τη ζώνη σας.", +"message.please.select.a.different.public.and.management.network.before.removing" : "Επιλέξτε ένα διαφορετικό δημόσιο δίκτυο και δίκτυο διαχείρισης πριν από την κατάργηση", +"message.please.select.networks" : "Επιλέξτε δίκτυα για την εικονική μηχανή σας.", +"message.please.select.ssh.key.pair.use.with.this.vm" : "Επιλέξτε ένα ζεύγος SSH για να χρησμοποιηθεί στην εικονική μηχανή", +"message.please.wait.while.zone.is.being.created" : "Περιμένετε όσο δημιουργείται η ζώνη σας. αυτό μπορεί να πάρει λίγο χρόνο ...", +"message.pod.dedicated" : "Pod αποκλειστικής χρήσης", +"message.pod.dedication.released" : "Η αποκλειστική δεσμευση το Pod Αποδεσμεύτηκε", +"message.portable.ip.delete.confirm" : "Επιβεβαιώστε ότι θέλετε να διαγράψετε το φορητό εύρος IP", +"message.processing.complete" : "Η επεξεργασία ολοκληρώθηκε!", +"message.protocol.description" : "Για XenServer, επιλέξτε NFS, iSCSI, or PreSetup. Για KVM, επιλέξτε NFS, SharedMountPoint, RDB, CLVM or Gluster. Για vSphere, επιλέξτε NFS, PreSetup (VMFS or iSCSI or FiberChannel or vSAN or vVols) or DatastoreCluster. Για Hyper-V, επιλέξτε SMB/CIFS. Για LXC, επιλέξτε NFS or SharedMountPoint. Για OVM, επιλέξτε NFS or ocfs2.", +"message.project.invite.sent" : "Πρόσκληση που στάλθηκε στο χρήστη. θα προστεθούν στο έργο μόλις αποδεχθούν την πρόσκληση", +"message.public.traffic.in.advanced.zone" : "Η δημόσια κίνηση δημιουργείται όταν τα VM στο cloud αποκτούν πρόσβαση στο Internet. Για το σκοπό αυτό, πρέπει να διατίθενται οι IPs που είναι διαθέσιμες στο κοινό. Οι τελικοί χρήστες μπορούν να χρησιμοποιήσουν το περιβάλλον εργασίας χρήστη CloudStack για να αποκτήσουν αυτές τις υπηρεσίες IP για την υλοποίηση του NAT μεταξύ του δικτύου επισκεπτών τους και του δημόσιου δικτύου τους.

Παρέχετε τουλάχιστον μία σειρά διευθύνσεων IP για την κίνηση στο διαδίκτυο.", +"message.public.traffic.in.basic.zone" : "Η δημόσια κίνηση δημιουργείται όταν τα VM στο cloud αποκτούν πρόσβαση στο Internet ή παρέχουν υπηρεσίες σε υπολογιστές-πελάτες μέσω του Internet. Για το σκοπό αυτό, πρέπει να διατίθενται δημόσια προσβάσιμες IPs. Όταν δημιουργείται μια εικονική μηχανή, μια διεύθυνση IP από αυτό το σύνολο δημόσιων IP θα εκχωρηθεί στην εικονική μηχανή εκτός από τη διεύθυνση IP του επισκέπτη. Στατική 1-1 NAT θα ρυθμιστεί αυτόματα μεταξύ της δημόσιας IP και του επισκέπτη IP. Οι τελικοί χρήστες μπορούν επίσης να χρησιμοποιήσουν το περιβάλλον εργασίας χρήστη CloudStack για να αποκτήσουν πρόσθετες διευθύνσεις IP για την υλοποίηση στατικού NAT μεταξύ των περιστάσεων τους και της δημόσιας διεύθυνσης IP.", +"message.publicip.state.allocated" : "η διεύθυνση IP χρησιμοποιείται .", +"message.publicip.state.allocating" : "Η διεύθυνση IP μεταδίδεται σε άλλα στοιχεία δικτύου και δεν είναι ακόμα έτοιμη για χρήση.", +"message.publicip.state.free" : "Η διεύθυνση IP είναι έτοιμη να εκχωρηθεί.", +"message.publicip.state.releasing" : "Η διεύθυνση IP αποδεσμεύεται για άλλα στοιχεία δικτύου και δεν είναι έτοιμη για εκχώρηση.", +"message.question.are.you.sure.you.want.to.add" : "Είστε βέβαιοι ότι θέλετε να προσθέσετε", +"message.read.accept.license.agreements" : "Παρακαλούμε διαβάστε και αποδεχτείτε τους όρους για τις άδειες χρήσης.", +"message.read.admin.guide.scaling.up" : "Διαβάστε την ενότητα δυναμικής κλιμάκωσης στον οδηγό διαχείρισης πριν από την κλιμάκωση.", +"message.recover.vm" : "Επιβεβαιώστε ότι θέλετε να ανακτήσετε αυτό το VM.", +"message.redirecting.region" : "Ανακατεύθυνση στην περιοχή...", +"message.register.failed" : "Η δήλωση απέτυχε", +"message.register.succeeded" : "Η εγγραφή ολοκληρώθηκε με επιτυχία", +"message.reinstall.vm" : "Σημείωση: Προχωρήστε με επιφύλαξη. Η εργασία αυτή θα προκαλέσει επανεγκατάσταση της εικονικής μηχανής απο το πρότυπο. Όλα τα δεδομένα στον κύριο δίσκο θα χαθούν. Αν υπάρχουν δευτερεύοντες δίσκοι θα παραμείνουν άθικτοι", +"message.release.ip.failed" : "Απέτυχε η αποδέσμευση της IP", +"message.releasing.dedicated.cluster" : "Αποδέσμευση αποκλειστικού ομοταξίας...", +"message.releasing.dedicated.host" : "Αποδέσμευση αποκλειστικού κεντρικού υπολογιστή...", +"message.releasing.dedicated.pod" : "Αποδέσμευση αποκλειστικού pod ...", +"message.releasing.dedicated.zone" : "Αποδέσμευση αποκλειστικής ζώνης...", +"message.remove.egress.rule.failed" : "Η κατάργηση του κανόνα εξόδου απέτυχε", +"message.remove.egress.rule.processing" : "Διαγραφή κανόνα εξόδου...", +"message.remove.failed" : "Η κατάργηση απέτυχε", +"message.remove.firewall.rule.failed" : "Η κατάργηση του κανόνα τείχους προστασίας απέτυχε", +"message.remove.firewall.rule.processing" : "Διαγραφή κανόνα τείχους προστασίας...", +"message.remove.instance.failed" : "Απέτυχε η κατάργηση της εικονική μηχανής", +"message.remove.instance.processing" : "Αφαίρεση...", +"message.remove.iprange.processing" : "Κατάργηση περιοχής IP...", +"message.remove.ldap" : "Είστε βέβαιοι ότι θέλετε να διαγράψετε τη ρύθμιση παραμέτρων LDAP;", +"message.remove.nic.processing" : "Κατάργηση nic...", +"message.remove.port.forward.failed" : "Η κατάργηση του κανόνα προώθησης θυρών απέτυχε", +"message.remove.region" : "Είστε βέβαιοι ότι θέλετε να καταργήσετε αυτήν την περιοχή από αυτόν το διακομιστή διαχείρισης;", +"message.remove.rule.failed" : "Απέτυχε η διαγραφή του κανόνα", +"message.remove.secondary.ipaddress.processing" : "Κατάργηση δευτερεύουσας διεύθυνσης IP...", +"message.remove.securitygroup.rule.processing" : "Διαγραφή κανόνα ομάδας ασφαλείας...", +"message.remove.sticky.policy.failed" : "Απέτυχε η κατάργηση της sticky πολιτικής", +"message.remove.sticky.policy.processing" : "Κατάργηση sticky πολιτικής...", +"message.remove.vpc" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε το VPC", +"message.remove.vpn.access" : "Επιβεβαιώστε ότι θέλετε να καταργήσετε την πρόσβαση VPN από τον ακόλουθο χρήστη.", +"message.removed.ssh.key.pair" : "Καταργήθηκε ένα ζεύγος κλειδιών SSH", +"message.request.failed" : "Η αίτηση απέτυχε", +"message.required.add.least.ip" : "Προσθέστε τουλάχιστον 1 εύρος IP", +"message.required.traffic.type" : "Σφάλμα στη ρύθμιση παραμέτρων! Όλοι οι απαιτούμενοι τύποι κίνησης θα πρέπει να προστίθενται και με πολλαπλά φυσικά δίκτυα κάθε δίκτυο θα πρέπει να έχει ετικέτα.", +"message.reset.password.warning.notpasswordenabled" : "Το πρότυπο αυτής της εικονική μηχανής δημιουργήθηκε χωρίς να ενεργοποιηθεί ο κωδικός πρόσβασης", +"message.reset.password.warning.notstopped" : "Η εικονική μηχανή σας πρέπει να διακοπεί πριν επιχειρήσετε να αλλάξετε τον τρέχοντα κωδικό πρόσβασής της", +"message.reset.vpn.connection" : "Επιβεβαιώστε ότι θέλετε να επαναφέρετε τη σύνδεση VPN", +"message.resize.volume.failed" : "Απέτυχε η αλλαγή μεγέθους του τόμου", +"message.resource.not.found" : "Ο πόρος δεν βρέθηκε", +"message.restart.mgmt.server" : "Επανεκκινήστε τους διακομιστές διαχείρισης για να τεθούν σε ισχύ οι νέες ρυθμίσεις σας.", +"message.restart.mgmt.usage.server" : "Επανεκκινήστε τους διακομιστές διαχείρισης και τους διακομιστές χρήσης για να τεθούν σε ισχύ οι νέες ρυθμίσεις σας.", +"message.restart.network" : "Όλες οι υπηρεσίες που παρέχονται από αυτό το δίκτυο θα διακοπεί. Επιβεβαιώστε ότι θέλετε να επανεκκινήσετε αυτό το δίκτυο.", +"message.restart.vpc" : "Επιβεβαιώστε ότι θέλετε να επανεκκινήσετε το VPC", +"message.restart.vpc.remark" : "Επιβεβαιώστε ότι θέλετε να επανεκκινήσετε το VPC

Παρατήρηση: Αν κάνετε ένα απλο VPC πλεονάζον τα δεδομένα του θα καθαριστούν. Τα δίκτυα δεν θα είναι διαθέσιμα για κάποια λεπτά.

", +"message.restorevm" : "Θέλετε να επαναφέρετε την εικονική μηχανή;", +"message.role.ordering.fail" : "Η αναδιάταξη των δικαιωμάτων κανόνων ματαιώθηκε καθώς η λίστα έχει αλλάξει κατά την πραγματοποίηση αλλαγών. Προσπαθήστε ξανά.", +"message.role.update.fail" : "Απέτυχε η ενημέρωση του δικαιώματος κανόνα", +"message.scale.processing" : "Κλίμακα σε εξέλιξη", +"message.security.group.usage" : "(Χρησιμοποιήστε το πλήκτρο Ctrl-κλικ για να επιλέξετε όλες τις ισχύουσες ομάδες ασφαλείας)", +"message.select.a.zone" : "Μια ζώνη αντιστοιχεί συνήθως σε ένα μόνο κέντρο δεδομένων. Πολλές ζώνες συμβάλλουν στο να γίνει το cloud πιο αξιόπιστο, παρέχοντας φυσική απομόνωση και πλεονασμό.", +"message.select.affinity.groups" : "Επιλέξτε τις ομάδες συνάφειας που θέλετε αυτό το VM να ανήκει", +"message.select.destination.image.stores" : "Επιλέξτε Χώρους αποθήκευσης εικόνων στους οποίους πρόκειται να μετεγκατασταθούν δεδομένα", +"message.select.instance" : "Επιλέξτε μια εικονική μηχανή.", +"message.select.iso" : "Επιλέξτε ένα ISO για τη νέα εικονική εικονική μηχανή σας.", +"message.select.item" : "Επιλέξτε ένα στοιχείο.", +"message.select.migration.policy" : "Επιλέξτε μια πολιτική μετεγκατάστασης", +"message.select.security.groups" : "Επιλέξτε ομάδες ασφαλείας για τη νέα εικονική μηχανή", +"message.select.template" : "Επιλέξτε ένα πρότυπο για τη νέα εικονική εικονική μηχανή σας.", +"message.select.tier" : "Επιλέξτε ένα επίπεδο", +"message.select.zone.description" : "Επιλογή τύπου ζώνης βασικής/προηγμένης", +"message.select.zone.hint" : "Αυτοί είναι οι τύποι ζώνης που μπορείται να χρησμοποιήσετε. Βασική ζώνη: Υποστηρίζει ένα δίκτυο όπου όλες οι εικονικές μηχανές λαμβάνουν IPs απο το δίκτυο. Η απομόνηση των μηχανημάτων παρέχεται μέσω μηχανισμών layer-3 όπως είναι τα security groups (IP address source filtering). Ζώνη για προχωρημένους: H Ζώνη αυτή χρησιμοποιείται για πολύπλοκες τοπολογίες. Διαθέσιμες υπηρεσίες που παρέχονται είναι τείχος προστασίας, VPN, load balancing", +"message.server.description" : "NFS, iSCSI, or PreSetup: Διεύθυνση IP ή όνομα DNS της συσκευής αποθήκευσης. VMware PreSetup: Διεύθυνση IP ή όνομα DNS του vCenter διακομιστή.", +"message.set.default.nic" : "Επιβεβαιώστε ότι θέλετε να κάνετε αυτό το NIC προεπιλογή για αυτήν την εικονική μηχανή.", +"message.set.default.nic.manual" : "Ενημερώστε τώρα με μη αυτόματο τρόπο το προεπιλεγμένο NIC στην εικονική μηχανή.", +"message.setting.updated" : "Θέση αναβάθμισης:", +"message.setup.physical.network.during.zone.creation" : "Όταν προσθέτετε μια ζώνη, πρέπει να ρυθμίσετε ένα ή περισσότερα φυσικά δίκτυα. Κάθε δίκτυο αντιστοιχεί σε ένα NIC στον Hypervisor. Κάθε φυσικό δίκτυο μπορεί να μεταφέρει έναν ή περισσότερους τύπους κίνησης, με ορισμένους περιορισμούς στον τρόπο με τον οποίο μπορούν να συνδυαστούν. Προσθέστε ή καταργήστε έναν ή περισσότερους τύπους κίνησης σε κάθε φυσικό δίκτυο.", +"message.setup.physical.network.during.zone.creation.basic" : "Όταν προσθέτετε μια βασική ζώνη, μπορείτε να ρυθμίσετε ένα φυσικό δίκτυο, το οποίο αντιστοιχεί σε ένα NIC στον Hypervisor. Το δίκτυο μεταφέρει διάφορους τύπους κίνησης.

Μπορείτε επίσης να προσθέσετε άλλους τύπους κίνησης στο φυσικό δίκτυο.", +"message.setup.successful" : "Cloud setup επιτυχής!", +"message.specifiy.tag.key" : "Καθορίστε ένα κλειδί ετικέτας", +"message.specifiy.tag.key.value" : "Καθορίστε ένα κλειδί ετικέτας και μια τιμή", +"message.specifiy.tag.value" : "Καθορίστε μια τιμή ετικέτας", +"message.specify.url" : "Καθορίστε τη διεύθυνση URL", +"message.step.1.desc" : "Επιλέξτε ένα πρότυπο για τη νέα εικονική εικονική μηχανή σας. Μπορείτε επίσης να επιλέξετε ένα κενό πρότυπο από το οποίο μπορεί να εγκατασταθεί μια εικόνα ISO.", +"message.step.2.continue" : "Επιλέξτε μια προσφορά υπηρεσιών για να συνεχίσετε", +"message.step.3.continue" : "Επιλέξτε μια προσφορά δίσκου για να συνεχίσετε", +"message.step.4.continue" : "Επιλέξτε τουλάχιστον ένα δίκτυο για να συνεχίσετε", +"message.step.4.desc" : "Επιλέξτε το πρωτεύον δίκτυο με το οποίο θα συνδεθεί η εικονική εικονική μηχανή σας.", +"message.step.license.agreements.continue" : "Παρακαλούμε αποδεχτείτε όλες τις συμφωνίες άδειας χρήσης για να συνεχίσετε", +"message.storage.traffic" : "Η κίνηση μεταξύ των εσωτερικών πόρων του CloudStack, συμπεριλαμβανομένων τυχόν στοιχείων που επικοινωνούν με το διακομιστή διαχείρισης, όπως οι κεντρικοί υπολογιστές και οι VM του συστήματος CloudStack. Ρυθμίστε εδώ τις παραμέτρους της κίνησης αποθήκευσης.", +"message.success.acquire.ip" : "Επιτυχής απόκτηση IP", +"message.success.add.egress.rule" : "Προστέθηκε με επιτυχία νέος κανόνας εξόδου", +"message.success.add.firewall.rule" : "Προστέθηκε με επιτυχία νέος κανόνας τείχους προστασίας", +"message.success.add.guest.network" : "Δημιουργήθηκε με επιτυχία το δίκτυο επισκεπτών", +"message.success.add.iprange" : "Προστέθηκε με επιτυχία εύρος IP", +"message.success.add.kuberversion" : "Προστέθηκε με επιτυχία η έκδοση kubernetes", +"message.success.add.network" : "Προστέθηκε με επιτυχία το δίκτυο", +"message.success.add.network.acl" : "Προστέθηκε με επιτυχία η λίστα ACL δικτύου", +"message.success.add.port.forward" : "Προστέθηκε με επιτυχία ο νέος κανόνας προώθησης θυρών", +"message.success.add.private.gateway" : "Προστέθηκε με επιτυχία ιδιωτική πύλη", +"message.success.add.rule" : "Προστέθηκε με επιτυχία νέος κανόνας", +"message.success.add.secondary.ipaddress" : "Προστέθηκε με επιτυχία δευτερεύουσα διεύθυνση IP", +"message.success.add.static.route" : "Προστέθηκε με επιτυχία στατική διαδρομή", +"message.success.add.tag" : "Προστέθηκε με επιτυχία νέα ετικέτα", +"message.success.add.vpc.network" : "Προστέθηκε με επιτυχία δίκτυο VPC", +"message.success.add.vpn.customer.gateway" : "Προστέθηκε με επιτυχία πύλη πελάτη VPN", +"message.success.add.vpn.gateway" : "Προστέθηκε με επιτυχία πύλη VPN", +"message.success.asign.vm" : "Η εικονική μηχανή που εκχωρήθηκαν με επιτυχία ολοκληρώθηκε με επιτυχία", +"message.success.assigned.vms" : "Η αντιστοίχιση VM ολοκληρώθηκε με επιτυχία", +"message.success.certificate.upload" : "Η αποστολή του πιστοποιητικού ολοκληρώθηκε με επιτυχία", +"message.success.change.affinity.group" : "Η αλλαγή ομάδων συνάφειας ολοκληρώθηκε με επιτυχία", +"message.success.change.offering" : "Η προσφορά άλλαξε με επιτυχία", +"message.success.change.password" : "Ο κωδικός πρόσβασης που άλλαξε με επιτυχία για το χρήστη", +"message.success.config.backup.schedule" : "Ρύθμιση παραμέτρων χρονοδιαγράμματος δημιουργίας αντιγράφων ασφαλείας VM", +"message.success.config.sticky.policy" : "Η ρύθμιση παραμέτρων της πολιτικής κολλώδους ολοκληρώθηκε με επιτυχία", +"message.success.copy.clipboard" : "Η αντιγραφή ολοκληρώθηκε με επιτυχία στο Πρόχειρο", +"message.success.create.account" : "Λογαριασμός που δημιουργήθηκε με επιτυχία", +"message.success.create.internallb" : "Η εσωτερική lb ολοκληρώθηκε με επιτυχία", +"message.success.create.isolated.network" : "Δημιουργήθηκε με επιτυχία απομονωμένο δίκτυο", +"message.success.create.keypair" : "Δημιουργήθηκε με επιτυχία ζεύγος κλειδιών SSH", +"message.success.create.kubernetes.cluter" : "Δημιουργήθηκε με επιτυχία το σύμπλεγμα Kubernetes", +"message.success.create.l2.network" : "Δημιουργήθηκε με επιτυχία το δίκτυο L2", +"message.success.create.snapshot.from.vmsnapshot" : "Επιτυχής δημιουργία στιγμιότυπου από στιγμιότυπο VM", +"message.success.create.user" : "Ο χρήστης δημιουργήθηκε με επιτυχία", +"message.success.create.volume" : "Ο τόμος δημιουργήθηκε με επιτυχία", +"message.success.delete" : "Διαγραφή επιτυχίας", +"message.success.delete.acl.rule" : "Η κατάργηση του κανόνα ACL ολοκληρώθηκε με επιτυχία", +"message.success.delete.backup.schedule" : "Η διαγραφή του ολοκληρώθηκε με επιτυχία Ρύθμιση παραμέτρων χρονοδιαγράμματος δημιουργίας αντιγράφων ασφαλείας VM", +"message.success.delete.snapshot.policy" : "Η πολιτική στιγμιότυπων διαγράφηκε με επιτυχία", +"message.success.delete.static.route" : "Η διαγραφή της στατικής διαδρομής ολοκληρώθηκε με επιτυχία", +"message.success.delete.tag" : "Η ετικέτα διαγράφηκε με επιτυχία", +"message.success.delete.vm" : "Η εικονική μηχανή διαγράφηκε με επιτυχία", +"message.success.disable.saml.auth" : "Η εξουσιοδότηση SAML απενεργοποιήθηκε με επιτυχία", +"message.success.disable.vpn" : "Επιτυχής απενεργοποίηση vpn", +"message.success.edit.acl" : "Η επεξεργασία του κανόνα ACL ολοκληρώθηκε με επιτυχία", +"message.success.edit.rule" : "Επιτυχής επεξεργασία κανόνα", +"message.success.enable.saml.auth" : "Η εξουσιοδότηση SAML ενεργοποιήθηκε με επιτυχία", +"message.success.migrate.volume" : "Επιτυχής μετεγκατάσταση τόμου", +"message.success.migrating" : "Η μετεγκατάσταση ολοκληρώθηκε με επιτυχία για", +"message.success.move.acl.order" : "Η μετακίνηση του κανόνα ACL ολοκληρώθηκε με επιτυχία", +"message.success.recurring.snapshot" : "Επιτυχής επανάληψη στιγμιότυπα", +"message.success.register.iso" : "Επιτυχής καταχώρηση του ISO", +"message.success.register.keypair" : "Επιτυχής καταχώρηση ζεύγους κλειδιών SSH", +"message.success.register.template" : "Ολοκληρώθηκε με επιτυχία η καταχώρηση του προτύπου", +"message.success.release.ip" : "Η διεύθυνση IP αποδεσμέυτηκε με επιτυχία", +"message.success.remove.egress.rule" : "Η κατάργηση του κανόνα εξόδου ολοκληρώθηκε με επιτυχία", +"message.success.remove.firewall.rule" : "Ο κανόνας τείχους προστασίας καταργήθηκε με επιτυχία", +"message.success.remove.instance.rule" : "Η κατάργηση της εικονική μηχανής από τον κανόνα ολοκληρώθηκε με επιτυχία", +"message.success.remove.ip" : "Ολοκληρώθηκε με επιτυχία η ip", +"message.success.remove.iprange" : "Η περιοχή IP καταργήθηκε με επιτυχία", +"message.success.remove.nic" : "Η κατάργηση ολοκληρώθηκε με επιτυχία", +"message.success.remove.port.forward" : "Η κατάργηση του κανόνα προώθησης θυρών ολοκληρώθηκε με επιτυχία", +"message.success.remove.rule" : "Ο κανόνας διαγράφηκε με επιτυχία", +"message.success.remove.secondary.ipaddress" : "Η κατάργηση της δευτερεύουσας διεύθυνσης IP ολοκληρώθηκε με επιτυχία", +"message.success.remove.sticky.policy" : "Η κατάργηση της πολιτικής sticky ολοκληρώθηκε με επιτυχία", +"message.success.resize.volume" : "Επιτυχής αλλαγή μεγέθους τόμου", +"message.success.scale.kubernetes" : "Σύμπλεγμα Kubernetes με επιτυχία", +"message.success.update.ipaddress" : "Η ενημέρωση της διεύθυνσης IP ολοκληρώθηκε με επιτυχία", +"message.success.update.kubeversion" : "Η επικαιροποίηση υποστηριζόμενης έκδοσης του Kubernetes ολοκληρώθηκε με επιτυχία", +"message.success.update.user" : "Ο χρήστης ενημερώθηκε με επιτυχία", +"message.success.upgrade.kubernetes" : "Το σύμπλεγμα Kubernetes αναβαθμίστηκε με επιτυχία", +"message.success.upload" : "Η αποστολή ολοκληρώθηκε με επιτυχία", +"message.success.upload.description" : "Αυτό το αρχείο ISO έχει αποσταλεί. Ελέγξτε την κατάστασή του στο μενού \"Πρότυπα\"", +"message.success.upload.iso.description" : "Αυτό το αρχείο ISO έχει αποσταλεί. Ελέγξτε την κατάστασή του στο μενού Εικόνες > ISOs", +"message.success.upload.template.description" : "Αυτό το αρχείο προτύπου έχει αποσταλεί. Ελέγξτε την κατάστασή του στο μενού \"Πρότυπα\"", +"message.success.upload.volume.description" : "Αυτός ο τόμος έχει αποσταλεί. Ελέγξτε την κατάστασή του στο μενού \"Τόμοι\"", +"message.suspend.project" : "Είστε βέβαιοι ότι θέλετε να αναστείλετε αυτό το έργο;", +"message.sussess.discovering.feature" : "Ανακάλυψε όλα τα διαθέσιμα χαρακτηριστικά!", +"message.switch.to" : "Μετάβαση σε", +"message.systems.vms.ready" : "Σύστημα VM έτοιμο.", +"message.template.copy.select.zone" : "Επιλέξτε μια ζώνη για αντιγραφή προτύπου.", +"message.template.copying" : "Το πρότυπο αντιγράφεται.", +"message.template.desc" : "Εικόνα λειτουργικού συστήματος που μπορεί να χρησιμοποιηθεί για την εκκίνηση VM", +"message.template.iso" : "Επιλέξτε ένα πρότυπο ή iso για να συνεχίσετε", +"message.tier.required" : "Απαιτείται βαθμίδα", +"message.tooltip.dns.1" : "Όνομα διακομιστή DNS για χρήση από VM στη ζώνη. Οι δημόσιες διευθύνσεις IP για τη ζώνη πρέπει να έχουν μια διαδρομή προς αυτόν το διακομιστή.", +"message.tooltip.dns.2" : "Ένα δεύτερο όνομα διακομιστή DNS για χρήση από VM στη ζώνη. Οι δημόσιες διευθύνσεις IP για τη ζώνη πρέπει να έχουν μια διαδρομή προς αυτόν το διακομιστή.", +"message.tooltip.internal.dns.1" : "Όνομα διακομιστή DNS για χρήση από VM εσωτερικού συστήματος CloudStack στη ζώνη. Η ιδιωτική διεύθυνση IP για τα pods πρέπει να έχει μια διαδρομή προς αυτόν το διακομιστή.", +"message.tooltip.internal.dns.2" : "Όνομα διακομιστή DNS για χρήση από VM εσωτερικού συστήματος CloudStack στη ζώνη. Η ιδιωτική διεύθυνση IP για τα pods πρέπει να έχει μια διαδρομή προς αυτόν το διακομιστή.", +"message.tooltip.network.domain" : "Ένα επίθεμα DNS που θα δημιουργήσει ένα προσαρμοσμένο όνομα τομέα για το δίκτυο στο οποίο γίνεται πρόσβαση από VM επισκέπτη.", +"message.tooltip.pod.name" : "Ένα όνομα γι' αυτό το pod.", +"message.tooltip.reserved.system.gateway" : "Η πύλη για τους κεντρικούς υπολογιστές στο pod.", +"message.tooltip.reserved.system.netmask" : "Το πρόθεμα δικτύου που ορίζει το δευτερεύον δίκτυο pod χρησιμοποιεί σημειογραφία CIDR.", +"message.tooltip.zone.name" : "Ένα όνομα για τη ζώνη.", +"message.traffic.type.to.basic.zone" : "τύπος κίνησης στη βασική ζώνη", +"message.update.ipaddress.processing" : "Ενημέρωση διεύθυνσης IP...", +"message.update.os.preference" : "Επιλέξτε μια προτίμηση λειτουργικού συστήματος για αυτόν τον κεντρικό υπολογιστή. Όλες οι εικονικές περιστάσεις με παρόμοιες προτιμήσεις θα εκχωρηθούν πρώτα σε αυτόν τον κεντρικό υπολογιστή πριν επιλέξουν έναν άλλο.", +"message.update.resource.count" : "Επιβεβαιώστε ότι θέλετε να ενημερώσετε τις μετρήσεις πόρων για αυτόν το λογαριασμό.", +"message.update.resource.count.domain" : "Επιβεβαιώστε ότι θέλετε να ενημερώσετε τις μετρήσεις πόρων για αυτόν τον τομέα.", +"message.update.ssl" : "Παρακαλώ προσκομείστε ένα νέο πιστοποιητικό SSL X.509 μαζί με την αλυσίδα επαλήθευσης του για να αναβαθμιστούν τα συστημικά μηχανήματα Console Proxy και Secondary Storage", +"message.update.ssl.failed" : "Απέτυχε η ενημέρωση του πιστοποιητικού SSL.", +"message.update.ssl.succeeded" : "Η ενημέρωση των πιστοποιητικών SSL ολοκληρώθηκε με επιτυχία", +"message.upload.failed" : "Η αποστολή απέτυχε", +"message.upload.file.limit" : "Μόνο ένα αρχείο μπορεί να αποσταλεί κάθε φορά", +"message.upload.file.processing" : "Μην κλείσετε αυτήν τη φόρμα, η αποστολή αρχείου βρίσκεται σε εξέλιξη...", +"message.upload.iso.failed" : "Η αποστολή ISO απέτυχε", +"message.upload.iso.failed.description" : "Απέτυχε η αποστολή του ISO", +"message.upload.template.failed.description" : "Απέτυχε η αποστολή του προτύπου", +"message.upload.volume.failed" : "Η αποστολή τόμου απέτυχε", +"message.user.not.permitted.api" : "Ο χρήστης δεν επιτρέπεται να χρησιμοποιήσει το API", +"message.validate.accept" : "Εισαγάγετε μια τιμή με έγκυρη επέκταση.", +"message.validate.creditcard" : "Πληκτρολογήστε έναν έγκυρο αριθμό πιστωτικής κάρτας.", +"message.validate.date" : "Πληκτρολογήστε μια έγκυρη ημερομηνία.", +"message.validate.date.iso" : "Πληκτρολογήστε μια έγκυρη ημερομηνία (ISO).", +"message.validate.digits" : "Πληκτρολογήστε μόνο ψηφία.", +"message.validate.email.address" : "Πληκτρολογήστε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου.", +"message.validate.equalto" : "Πληκτρολογήστε ξανά την ίδια τιμή.", +"message.validate.fieldrequired" : "Αυτό το πεδίο είναι απαραίτητο.", +"message.validate.fixfield" : "Παρακαλώ διορθώστε αυτό το πεδίο.", +"message.validate.instance.name" : "Το όνομα εικονική μηχανής δεν μπορεί να υπερβαίνει τους 63 χαρακτήρες. Επιτρέπονται μόνο ascii γράμματα a~z, A~Z, ψηφία 0~9, παύλα. Πρέπει να ξεκινά με ένα γράμμα και να τελειώνει με ένα γράμμα ή ένα ψηφίο.", +"message.validate.invalid.characters" : "Βρέθηκαν μη έγκυροι χαρακτήρες. παρακαλώ διορθώστε.", +"message.validate.max" : "Πληκτρολογήστε μια τιμή μικρότερη ή ίση με {0}.", +"message.validate.maxlength" : "Πληκτρολογήστε όχι περισσότερους από {0} χαρακτήρες.", +"message.validate.minlength" : "Πληκτρολογήστε τουλάχιστον {0} χαρακτήρες.", +"message.validate.number" : "Πληκτρολογήστε έναν έγκυρο αριθμό.", +"message.validate.range" : "Εισαγάγετε μια τιμή μεταξύ {0} και {1}.", +"message.validate.range.length" : "Πληκτρολογήστε μια τιμή μεταξύ {0} και {1} χαρακτήρων.", +"message.validate.url" : "Πληκτρολογήστε μια έγκυρη διεύθυνση URL.", +"message.virtual.network.desc" : "Ένα αποκλειστικό δίκτυο εικονικής διαμόρφωσης για το λογαριασμό σας. Ο τομέας μετάδοσης περιέχεται σε ένα VLAN και όλη η πρόσβαση στο δημόσιο δίκτυο δρομολογείται από έναν εικονικό δρομολογητή.", +"message.virtual.router.not.return.elementid" : "Σφάλμα, η εντολή listVirtualRouterElement API δεν επέστρεψε δεδομένα Virtual Router Element Id", +"message.vm.create.template.confirm" : "Δημιουργία προτύπου θα επανεκκινήσει την εικονική μηχανή αυτόματα.", +"message.vm.review.launch" : "Ελέγξτε τις ακόλουθες πληροφορίες και επιβεβαιώστε ότι η εικονική εικονική μηχανή σας είναι σωστή πριν από την εκκίνηση.", +"message.vm.state.destroyed" : "Το VM έχει επισημανθεί για καταστροφή", +"message.vm.state.error" : "Η εικονική μηχανή είναι σε σφάλμα", +"message.vm.state.expunging" : "Το VM πρόκειται να διαγραφεί", +"message.vm.state.migrating" : "Γίνεται μετεγκατάσταση της εικονικής μηχανής", +"message.vm.state.running" : "Η εικονική μηχανή εκτελείται", +"message.vm.state.shutdown" : "Η κατάσταση VM τερματίζεται από μέσα", +"message.vm.state.starting" : "Γίνεται εκκίνηση της εικονικής μηχανής", +"message.vm.state.stopped" : "Η εικονική μηχανή διακόπηκε", +"message.vm.state.stopping" : "Η εικονική μηχανή διακόπτεται", +"message.vm.state.unknown" : "Η κατάσταση VM είναι άγνωστη.", +"message.vmsnapshot.state.allocated" : "Το στιγμιότυπο VM έχει εκχωρηθεί, αλλά δεν έχει δημιουργηθεί ακόμα", +"message.vmsnapshot.state.creating" : "Δημιουργείται το στιγμιότυπο εικονικής μηχανής", +"message.vmsnapshot.state.error" : "Το στιγμιότυπο VM βρίσκεται σε κατάσταση σφάλματος και δεν είναι δυνατή η ανάκτησή του", +"message.vmsnapshot.state.expunging" : "Το στιγμιότυπο VM είναι να διαγραφεί", +"message.vmsnapshot.state.ready" : "Το στιγμιότυπο VM είναι έτοιμο για χρήση", +"message.vmsnapshot.state.removed" : "Το στιγμιότυπο VM καταστρέφεται και δεν είναι δυνατή η ανάκτησή του", +"message.vmsnapshot.state.reverting" : "Το στιγμιότυπο VM χρησιμοποιείται για την επαναφορά", +"message.vnmc.available.list" : "Το VNMC δεν είναι διαθέσιμο από τη λίστα υπηρεσιών παροχής.", +"message.vnmc.not.available.list" : "Το VNMC δεν είναι διαθέσιμο από τη λίστα υπηρεσιών παροχής.", +"message.volume.create.template.confirm" : "Επιβεβαιώστε ότι θέλετε να δημιουργήσετε ένα πρότυπο για αυτόν τον τόμο δίσκου. Η δημιουργία του προτύπου μπορεί να κυμαίνεται από αρκετά λεπτά έως περισσότερο, ανάλογα με το μέγεθος του τόμου.", +"message.volume.root.shrink.disk.size" : "Η λειτουργία συρρίκνωσης σε τόμο ROOT δεν υποστηρίζεται", +"message.volume.state.allocated" : "Ο τόμος έχει εκχωρηθεί αλλά δεν έχει δημιουργηθεί ακόμα", +"message.volume.state.attaching" : "Ο τόμος συνδέεται σε έναν τόμο από την κατάσταση \"Έτοιμο\".", +"message.volume.state.copying" : "Ο τόμος αντιγράφεται από το χώρο αποθήκευσης εικόνων στο πρωτεύον, σε περίπτωση που είναι ένας τόμος που έχει αποσταλεί", +"message.volume.state.creating" : "Ο τόμος δημιουργείται", +"message.volume.state.destroy" : "Ο τόμος καταστρέφεται και δεν είναι δυνατή η ανάκτηση του", +"message.volume.state.destroying" : "Ο τόμος καταστρέφει και δεν μπορεί να ανακτηθεί", +"message.volume.state.expunged" : "Ο όγκος έχει διαγραφεί", +"message.volume.state.expunging" : "Ο όγκος είναι να διαγραφεί", +"message.volume.state.migrating" : "Ο τόμος μετεγκαθίσταται σε άλλο χώρο αποθήκευσης", +"message.volume.state.notuploaded" : "Η καταχώρηση τόμου μόλις δημιουργήθηκε σε DB, δεν έχει αποσταλεί ακόμα", +"message.volume.state.ready" : "Ο τόμος είναι έτοιμος για χρήση", +"message.volume.state.resizing" : "Γίνεται αλλαγή μεγέθους του τόμου", +"message.volume.state.revertsnapshotting" : "Υπάρχει ένα στιγμιότυπο που δημιουργήθηκε σε αυτόν τον τόμο, ο τόμος επανέρχεται από το στιγμιότυπο", +"message.volume.state.snapshotting" : "Υπάρχει ένα στιγμιότυπο που δημιουργήθηκε σε αυτόν τον τόμο, δεν έχει δημιουργηθεί αντίγραφο ασφαλείας σε δευτερεύοντα χώρο αποθήκευσης ακόμα", +"message.volume.state.uploadabandoned" : "Η αποστολή τόμου έχει εγκαταλειφθεί, καθώς η αποστολή δεν ξεκίνησε ποτέ εντός συγκεκριμένου χρόνου", +"message.volume.state.uploaded" : "Ο τόμος αποστέλλεται", +"message.volume.state.uploaderror" : "Η αποστολή τόμου αντιμετώπισε κάποιο σφάλμα", +"message.volume.state.uploadinprogress" : "Η αποστολή τόμου βρίσκεται σε εξέλιξη", +"message.volume.state.uploadop" : "Η λειτουργία αποστολής τόμου βρίσκεται σε εξέλιξη ή, εν ολίγοις, ο τόμος βρίσκεται σε δευτερεύουσα αποθήκευση", +"message.waiting.for.builtin.templates.to.load" : "Αναμονή για τη φόρτωση αρχικών προτύπων...", +"message.xstools61plus.update.failed" : "Αποτυχία ενημέρωσης εργαλείων XS στην έκδοση 6.1+. Σφάλμα:", +"message.you.must.have.at.least.one.physical.network" : "Πρέπει να έχετε τουλάχιστον ένα φυσικό δίκτυο", +"message.your.cloudstack.is.ready" : "Το CloudStack σας είναι έτοιμο!", +"message.zone.creation.complete" : "Η δημιουργία ζώνης ολοκληρώθηκε", +"message.zone.creation.complete.would.you.like.to.enable.this.zone" : "Η δημιουργία ζώνης ολοκληρώθηκε. Θέλετε να ενεργοποιήσετε αυτήν τη ζώνη;", +"message.zone.detail.description" : "Συμπλήρωση λεπτομερειών ζώνης", +"message.zone.detail.hint" : "Μια ζώνη είναι η μεγαλύτερη οργανική μονάδα στο CloudStack και συνήθως αντιστοιχεί σε ένα μόνο κέντρο δεδομένων. Οι ζώνες παρέχουν φυσική απομόνωση και πλεονασμό. Μια ζώνη αποτελείται από ένα ή περισσότερα pods (καθένα από τα οποία περιέχει κεντρικούς υπολογιστές και πρωτεύοντες διακομιστές αποθήκευσης) και έναν δευτερεύοντα διακομιστή αποθήκευσης, ο οποίος είναι κοινόχρηστος από όλα τα pods της ζώνης.", +"message.zone.no.network.selection" : "Η ζώνη που επιλέξατε δεν έχει επιλογές για την επιλογή δικτύου.", +"message.zone.step.1.desc" : "Επιλέξτε ένα μοντέλο δικτύου για τη ζώνη σας.", +"message.zone.step.2.desc" : "Πληκτρολογήστε τις ακόλουθες πληροφορίες για να προσθέσετε μια νέα ζώνη", +"message.zone.step.3.desc" : "Παρακαλώ εισάγετε τις ακόλουθες πληροφορίες για να προσθέσετε ένα νέο pod", +"message.zonewizard.enable.local.storage" : "Προειδοποίηση: Αν ενεργοποιηθεί ο τοπικός χώρος αποθήκευσης για την ζώνη πρέπει να ορίσετε απο που θα εκκινούνται οι συστημικές εικονικές μηχανές:

1. Αν θέλετε να εκκινούνται απο τον κοινό πρωτεύον χώρο αποθήκευσης ο χώρος αυτός πρέπει να προστεθεί στην ζώνη μετά την δημιουργία της καθώς και η ζώνη να βρίσκεται σε κατάσταση απενεργοποίησης.

2. Αν θέλετε να εκκινούνται απο τον τοπικό πρωτεύον χώρο αποθήκευσης, η τιμή της μεταβλητής system.vm.use.local.storage πρέπει να τεθεί στο αληθές (true) πριν ενεργοποιηθεί η ζώνη.


Θέλετε να συνεχίσετε;", +"messgae.validate.min" : "Πληκτρολογήστε μια τιμή μεγαλύτερη ή ίση με {0}.", +"migrate.from" : "Μετεγκατάσταση από", +"migrate.to" : "Μετεγκατάσταση σε", +"migrationPolicy" : "Μεταναστευτική Πολιτική", +"network.rate" : "Ρυθμός μετάδοσης δεδομένων δικτύου", +"router.health.checks" : "Έλεγχος ομαλής λειτουργείας", +"side.by.side" : "Δίπλα-δίπλα", +"state.accepted" : "Αποδεκτό", +"state.active" : "Ενεργό", +"state.allocating" : "Κατανομή", +"state.backedup" : "Αντίγραφα ασφαλείας", +"state.backingup" : "Δημιουργία αντιγράφων ασφαλείας", +"state.completed" : "Ολοκληρωθηκε", +"state.creating" : "Δημιουργείται", +"state.declined" : "Μειώμένο", +"state.destroyed" : "Κατεστραμένο", +"state.detached" : "Αποκολλημένο", +"state.disabled" : "Απενεργοποιημένο", +"state.enabled" : "Ενεργοποιημένο", +"state.error" : "Σφάλμα", +"state.expired" : "Έληξε", +"state.expunging" : "Διαγράφεται", +"state.migrating" : "Μετεγκαθίσταται", +"state.pending" : "Εκκρεμεί", +"state.running" : "Εκτέλείται", +"state.starting" : "Ξεκινάει", +"state.stopped" : "Σταμάτησε", +"state.stopping" : "Διακόπτεται", +"state.suspended" : "Ανεσταλμένο", +"title.upload.volume" : "Αναφόρτωση τόμου", +"user.login" : "Σύνδεση χρήστη", +"user.logout" : "Αποσύνδεση χρήστη" +} diff --git a/ui/src/components/header/TranslationMenu.vue b/ui/src/components/header/TranslationMenu.vue index 3240e4fc3c3a..cf43e96702b7 100644 --- a/ui/src/components/header/TranslationMenu.vue +++ b/ui/src/components/header/TranslationMenu.vue @@ -41,6 +41,7 @@ Polish Português brasileiro Русский + Ελληνικά From 006d0fe4c43adf7c2f2d4add2cccc711d7108a14 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 15 Jun 2021 16:58:38 +0530 Subject: [PATCH 005/120] ui: show read from ova only for ova format (#5108) Fixes #5107 Signed-off-by: Abhishek Kumar --- ui/src/views/image/RegisterOrUploadTemplate.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/src/views/image/RegisterOrUploadTemplate.vue b/ui/src/views/image/RegisterOrUploadTemplate.vue index 0f65cb56e4b6..db18b3a6248d 100644 --- a/ui/src/views/image/RegisterOrUploadTemplate.vue +++ b/ui/src/views/image/RegisterOrUploadTemplate.vue @@ -175,7 +175,8 @@ } ] }]" - :placeholder="apiParams.format.description"> + :placeholder="apiParams.format.description" + @change="val => { selectedFormat = val }"> {{ opt.name || opt.description }} @@ -209,7 +210,7 @@ - + Date: Wed, 16 Jun 2021 12:45:27 +0530 Subject: [PATCH 007/120] scaleio: Updated PowerFlex/ScaleIO gateway client with some improvements. (#5037) - Added connection manager to the gateway client. - Renew the client session on '401 Unauthorized' response. - Refactored the gateway client calls, for GET and POST methods. - Consume the http entity content after login/(re)authentication and close the content stream if exists. - Updated storage pool client connection timeout configuration 'storage.pool.client.timeout' to non-dynamic. - Added storage pool client max connections configuration 'storage.pool.client.max.connections' (default: 100) to specify the maximum connections for the ScaleIO storage pool client. - Updated unit tests. and blocked the attach volume operation for uploaded volume on ScaleIO/PowerFlex storage pool --- .../com/cloud/storage/StorageManager.java | 11 +- plugins/storage/volume/scaleio/pom.xml | 6 + .../client/ScaleIOGatewayClient.java | 4 +- .../ScaleIOGatewayClientConnectionPool.java | 3 +- .../client/ScaleIOGatewayClientImpl.java | 981 ++++++++---------- .../ScaleIOPrimaryDataStoreLifeCycle.java | 7 +- .../client/ScaleIOGatewayClientImplTest.java | 157 ++- .../ConfigurationManagerImpl.java | 3 + .../com/cloud/storage/StorageManagerImpl.java | 1 + .../cloud/storage/VolumeApiServiceImpl.java | 11 + 10 files changed, 600 insertions(+), 584 deletions(-) diff --git a/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java b/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java index db41a2f099ac..96cf333cb19a 100644 --- a/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java +++ b/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java @@ -124,7 +124,16 @@ public interface StorageManager extends StorageService { "Storage", "60", "Timeout (in secs) for the storage pool client connection timeout (for managed pools). Currently only supported for PowerFlex.", - true, + false, + ConfigKey.Scope.StoragePool, + null); + + ConfigKey STORAGE_POOL_CLIENT_MAX_CONNECTIONS = new ConfigKey<>(Integer.class, + "storage.pool.client.max.connections", + "Storage", + "100", + "Maximum connections for the storage pool client (for managed pools). Currently only supported for PowerFlex.", + false, ConfigKey.Scope.StoragePool, null); diff --git a/plugins/storage/volume/scaleio/pom.xml b/plugins/storage/volume/scaleio/pom.xml index e95087e7257f..36a385c0d09a 100644 --- a/plugins/storage/volume/scaleio/pom.xml +++ b/plugins/storage/volume/scaleio/pom.xml @@ -33,6 +33,12 @@ cloud-engine-storage-volume ${project.version} + + com.github.tomakehurst + wiremock-standalone + ${cs.wiremock.version} + test + diff --git a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClient.java b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClient.java index f6b10f888320..f497b10127d3 100644 --- a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClient.java +++ b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClient.java @@ -40,8 +40,8 @@ public interface ScaleIOGatewayClient { String STORAGE_POOL_SYSTEM_ID = "powerflex.storagepool.system.id"; static ScaleIOGatewayClient getClient(final String url, final String username, final String password, - final boolean validateCertificate, final int timeout) throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException { - return new ScaleIOGatewayClientImpl(url, username, password, validateCertificate, timeout); + final boolean validateCertificate, final int timeout, final int maxConnections) throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException { + return new ScaleIOGatewayClientImpl(url, username, password, validateCertificate, timeout, maxConnections); } // Volume APIs diff --git a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientConnectionPool.java b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientConnectionPool.java index 2daf8e4635ce..e557e0881328 100644 --- a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientConnectionPool.java +++ b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientConnectionPool.java @@ -62,8 +62,9 @@ public ScaleIOGatewayClient getClient(Long storagePoolId, StoragePoolDetailsDao final String encryptedPassword = storagePoolDetailsDao.findDetail(storagePoolId, ScaleIOGatewayClient.GATEWAY_API_PASSWORD).getValue(); final String password = DBEncryptionUtil.decrypt(encryptedPassword); final int clientTimeout = StorageManager.STORAGE_POOL_CLIENT_TIMEOUT.valueIn(storagePoolId); + final int clientMaxConnections = StorageManager.STORAGE_POOL_CLIENT_MAX_CONNECTIONS.valueIn(storagePoolId); - client = new ScaleIOGatewayClientImpl(url, username, password, false, clientTimeout); + client = new ScaleIOGatewayClientImpl(url, username, password, false, clientTimeout, clientMaxConnections); gatewayClients.put(storagePoolId, client); LOGGER.debug("Added gateway client for the storage pool: " + storagePoolId); } diff --git a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImpl.java b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImpl.java index 5e8568dede1f..fa195414b67f 100644 --- a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImpl.java +++ b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImpl.java @@ -56,11 +56,16 @@ import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.pool.PoolStats; import org.apache.http.util.EntityUtils; import org.apache.log4j.Logger; @@ -80,25 +85,27 @@ public class ScaleIOGatewayClientImpl implements ScaleIOGatewayClient { private final URI apiURI; private final HttpClient httpClient; - private static final String SESSION_HEADER = "X-RestSvcSessionId"; + private final PoolingHttpClientConnectionManager connectionManager; private static final String MDM_CONNECTED_STATE = "Connected"; - private String host; private String username; private String password; private String sessionKey = null; // The session token is valid for 8 hours from the time it was created, unless there has been no activity for 10 minutes // Reference: https://cpsdocs.dellemc.com/bundle/PF_REST_API_RG/page/GUID-92430F19-9F44-42B6-B898-87D5307AE59B.html - private static final long MAX_VALID_SESSION_TIME_IN_MILLISECS = 8 * 60 * 60 * 1000; // 8 hrs - private static final long MAX_IDLE_TIME_IN_MILLISECS = 10 * 60 * 1000; // 10 mins + private static final long MAX_VALID_SESSION_TIME_IN_HRS = 8; + private static final long MAX_VALID_SESSION_TIME_IN_MILLISECS = MAX_VALID_SESSION_TIME_IN_HRS * 60 * 60 * 1000; + private static final long MAX_IDLE_TIME_IN_MINS = 10; + private static final long MAX_IDLE_TIME_IN_MILLISECS = MAX_IDLE_TIME_IN_MINS * 60 * 1000; private static final long BUFFER_TIME_IN_MILLISECS = 30 * 1000; // keep 30 secs buffer before the expiration (to avoid any last-minute operations) + private boolean authenticating = false; private long createTime = 0; private long lastUsedTime = 0; public ScaleIOGatewayClientImpl(final String url, final String username, final String password, - final boolean validateCertificate, final int timeout) + final boolean validateCertificate, final int timeout, final int maxConnections) throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException { Preconditions.checkArgument(!Strings.isNullOrEmpty(url), "Gateway client url cannot be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(username) && !Strings.isNullOrEmpty(password), "Gateway client credentials cannot be null"); @@ -109,83 +116,141 @@ public ScaleIOGatewayClientImpl(final String url, final String username, final S .setSocketTimeout(timeout * 1000) .build(); + SSLConnectionSocketFactory factory = SSLConnectionSocketFactory.getSocketFactory(); if (!validateCertificate) { final SSLContext sslcontext = SSLUtils.getSSLContext(); sslcontext.init(null, new X509TrustManager[]{new TrustAllManager()}, new SecureRandom()); - final SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE); - this.httpClient = HttpClientBuilder.create() - .setDefaultRequestConfig(config) - .setSSLSocketFactory(factory) - .build(); - } else { - this.httpClient = HttpClientBuilder.create() - .setDefaultRequestConfig(config) - .build(); + factory = new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE); } + final Registry socketFactoryRegistry = RegistryBuilder. create() + .register("https", factory) + .build(); + connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + connectionManager.setMaxTotal(maxConnections); + connectionManager.setDefaultMaxPerRoute(maxConnections); + + this.httpClient = HttpClientBuilder.create() + .setConnectionManager(connectionManager) + .setDefaultRequestConfig(config) + .setSSLSocketFactory(factory) + .build(); + this.apiURI = new URI(url); - this.host = apiURI.getHost(); this.username = username; this.password = password; authenticate(); + LOG.debug("API client for the PowerFlex gateway " + apiURI.getHost() + " is created successfully, with max connections: " + + maxConnections + " and timeout: " + timeout + " secs"); } ///////////////////////////////////////////////////////////// //////////////// Private Helper Methods ///////////////////// ///////////////////////////////////////////////////////////// - private void authenticate() { + private synchronized void authenticate() { final HttpGet request = new HttpGet(apiURI.toString() + "/login"); request.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes())); + HttpResponse response = null; try { - final HttpResponse response = httpClient.execute(request); - checkAuthFailure(response); - this.sessionKey = EntityUtils.toString(response.getEntity()); - if (Strings.isNullOrEmpty(this.sessionKey)) { - throw new CloudRuntimeException("Failed to create a valid PowerFlex Gateway Session to perform API requests"); + authenticating = true; + LOG.debug("Authenticating gateway " + apiURI.getHost() + " with the request: " + request.toString()); + response = httpClient.execute(request); + if (isNullResponse(response)) { + LOG.warn("Invalid response received while authenticating, for the request: " + request.toString()); + throw new CloudRuntimeException("Failed to authenticate PowerFlex API Gateway due to invalid response from the Gateway " + apiURI.getHost()); } - this.sessionKey = this.sessionKey.replace("\"", ""); + + LOG.debug("Received response: " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase() + + ", for the authenticate request: " + request.toString()); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - throw new CloudRuntimeException("PowerFlex Gateway login failed, please check the provided settings"); + throw new CloudRuntimeException("PowerFlex Gateway " + apiURI.getHost() + " login failed, please check the provided settings"); } + + String sessionKeyInResponse = EntityUtils.toString(response.getEntity()); + if (Strings.isNullOrEmpty(sessionKeyInResponse)) { + throw new CloudRuntimeException("Failed to create a valid session for PowerFlex Gateway " + apiURI.getHost() + " to perform API requests"); + } + + LOG.info("PowerFlex API Gateway " + apiURI.getHost() + " authenticated successfully"); + this.sessionKey = sessionKeyInResponse.replace("\"", ""); + + long now = System.currentTimeMillis(); + createTime = lastUsedTime = now; } catch (final IOException e) { - throw new CloudRuntimeException("Failed to authenticate PowerFlex API Gateway due to:" + e.getMessage()); + LOG.error("Failed to authenticate PowerFlex API Gateway " + apiURI.getHost() + " due to: " + e.getMessage() + getConnectionManagerStats()); + throw new CloudRuntimeException("Failed to authenticate PowerFlex API Gateway " + apiURI.getHost() + " due to: " + e.getMessage()); + } finally { + authenticating = false; + if (response != null) { + EntityUtils.consumeQuietly(response.getEntity()); + } } - long now = System.currentTimeMillis(); - createTime = lastUsedTime = now; } private synchronized void renewClientSessionOnExpiry() { if (isSessionExpired()) { - LOG.debug("Session expired, renewing"); + LOG.debug("Session expired for the PowerFlex API Gateway " + apiURI.getHost() + ", renewing"); authenticate(); } } private boolean isSessionExpired() { long now = System.currentTimeMillis() + BUFFER_TIME_IN_MILLISECS; - if ((now - createTime) > MAX_VALID_SESSION_TIME_IN_MILLISECS || - (now - lastUsedTime) > MAX_IDLE_TIME_IN_MILLISECS) { + if ((now - createTime) > MAX_VALID_SESSION_TIME_IN_MILLISECS) { + LOG.debug("Session expired for the Gateway " + apiURI.getHost() + ", token is invalid after " + MAX_VALID_SESSION_TIME_IN_HRS + + " hours from the time it was created"); + return true; + } + + if ((now - lastUsedTime) > MAX_IDLE_TIME_IN_MILLISECS) { + LOG.debug("Session expired for the Gateway " + apiURI.getHost() + ", as there has been no activity for " + MAX_IDLE_TIME_IN_MINS + " mins"); return true; } + return false; } - private void checkAuthFailure(final HttpResponse response) { - if (response != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { - throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, "PowerFlex Gateway API call unauthorized, please check the provided settings"); + private boolean isNullResponse(final HttpResponse response) { + if (response == null) { + LOG.warn("Nil response"); + return true; + } + + if (response.getStatusLine() == null) { + LOG.warn("No status line in the response"); + return true; } + + return false; + } + + private boolean checkAuthFailure(final HttpResponse response, final boolean renewAndRetryOnAuthFailure) { + if (!isNullResponse(response) && response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { + if (!renewAndRetryOnAuthFailure) { + throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, "PowerFlex Gateway API call unauthorized, please check the provided settings"); + } + LOG.debug("PowerFlex Gateway API call unauthorized. Current token might be invalid, renew the session." + getConnectionManagerStats()); + return true; + } + return false; } private void checkResponseOK(final HttpResponse response) { + if (isNullResponse(response)) { + return; + } + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) { - LOG.debug("Requested resource does not exist"); + LOG.warn("Requested resource does not exist"); return; } + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_BAD_REQUEST) { throw new ServerApiException(ApiErrorCode.MALFORMED_PARAMETER_ERROR, "Bad API request"); } + if (!(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK || response.getStatusLine().getStatusCode() == HttpStatus.SC_ACCEPTED)) { String responseBody = response.toString(); @@ -193,54 +258,118 @@ private void checkResponseOK(final HttpResponse response) { responseBody = EntityUtils.toString(response.getEntity()); } catch (IOException ignored) { } - LOG.debug("HTTP request failed, status code is " + response.getStatusLine().getStatusCode() + ", response is: " + responseBody); + LOG.debug("HTTP request failed, status code: " + response.getStatusLine().getStatusCode() + ", response: " + + responseBody + getConnectionManagerStats()); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "API failed due to: " + responseBody); } } private void checkResponseTimeOut(final Exception e) { if (e instanceof ConnectTimeoutException || e instanceof SocketTimeoutException) { - throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, "API operation timed out, please try again."); + throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, "Gateway API operation timed out, please try again."); } } - private HttpResponse get(final String path) throws IOException { + private T get(final String path, final Class type) { + return get(path, type, true); + } + + private T get(final String path, final Class type, final boolean renewAndRetryOnAuthFailure) { renewClientSessionOnExpiry(); - final HttpGet request = new HttpGet(apiURI.toString() + path); - request.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((this.username + ":" + this.sessionKey).getBytes())); - final HttpResponse response = httpClient.execute(request); - synchronized (this) { - lastUsedTime = System.currentTimeMillis(); + HttpResponse response = null; + boolean responseConsumed = false; + try { + while (authenticating); // wait for authentication request (if any) to complete (and to pick the new session key) + final HttpGet request = new HttpGet(apiURI.toString() + path); + request.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((this.username + ":" + this.sessionKey).getBytes())); + LOG.debug("Sending GET request: " + request.toString()); + response = httpClient.execute(request); + String responseStatus = (!isNullResponse(response)) ? (response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()) : "nil"; + LOG.debug("Received response: " + responseStatus + ", for the sent GET request: " + request.toString()); + if (checkAuthFailure(response, renewAndRetryOnAuthFailure)) { + EntityUtils.consumeQuietly(response.getEntity()); + responseConsumed = true; + + authenticate(); + return get(path, type, false); + } + return processResponse(response, type); + } catch (final IOException e) { + LOG.error("Failed in GET method due to: " + e.getMessage() + getConnectionManagerStats(), e); + checkResponseTimeOut(e); + } finally { + if (!responseConsumed && response != null) { + EntityUtils.consumeQuietly(response.getEntity()); + } } - String responseStatus = (response != null) ? (response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()) : "nil"; - LOG.debug("GET request path: " + path + ", response: " + responseStatus); - checkAuthFailure(response); - return response; + return null; } - private HttpResponse post(final String path, final Object obj) throws IOException { + private T post(final String path, final Object obj, final Class type) { + return post(path, obj, type, true); + } + + private T post(final String path, final Object obj, final Class type, final boolean renewAndRetryOnAuthFailure) { renewClientSessionOnExpiry(); - final HttpPost request = new HttpPost(apiURI.toString() + path); - request.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((this.username + ":" + this.sessionKey).getBytes())); - request.setHeader("Content-type", "application/json"); - if (obj != null) { - if (obj instanceof String) { - request.setEntity(new StringEntity((String) obj)); - } else { - JsonMapper mapper = new JsonMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - String json = mapper.writer().writeValueAsString(obj); - request.setEntity(new StringEntity(json)); + HttpResponse response = null; + boolean responseConsumed = false; + try { + while (authenticating); // wait for authentication request (if any) to complete (and to pick the new session key) + final HttpPost request = new HttpPost(apiURI.toString() + path); + request.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((this.username + ":" + this.sessionKey).getBytes())); + request.setHeader("Content-type", "application/json"); + if (obj != null) { + if (obj instanceof String) { + request.setEntity(new StringEntity((String) obj)); + } else { + JsonMapper mapper = new JsonMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + String json = mapper.writer().writeValueAsString(obj); + request.setEntity(new StringEntity(json)); + } + } + LOG.debug("Sending POST request: " + request.toString()); + response = httpClient.execute(request); + String responseStatus = (!isNullResponse(response)) ? (response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()) : "nil"; + LOG.debug("Received response: " + responseStatus + ", for the sent POST request: " + request.toString()); + if (checkAuthFailure(response, renewAndRetryOnAuthFailure)) { + EntityUtils.consumeQuietly(response.getEntity()); + responseConsumed = true; + + authenticate(); + return post(path, obj, type, false); + } + return processResponse(response, type); + } catch (final IOException e) { + LOG.error("Failed in POST method due to: " + e.getMessage() + getConnectionManagerStats(), e); + checkResponseTimeOut(e); + } finally { + if (!responseConsumed && response != null) { + EntityUtils.consumeQuietly(response.getEntity()); } } - final HttpResponse response = httpClient.execute(request); + return null; + } + + private T processResponse(HttpResponse response, final Class type) throws IOException { + if (isNullResponse(response)) { + return null; + } + + checkResponseOK(response); synchronized (this) { lastUsedTime = System.currentTimeMillis(); } - String responseStatus = (response != null) ? (response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()) : "nil"; - LOG.debug("POST request path: " + path + ", response: " + responseStatus); - checkAuthFailure(response); - return response; + if (type == Boolean.class) { + return (T) Boolean.TRUE; + } else if (type == String.class) { + return (T) EntityUtils.toString(response.getEntity()); + } else if (type == JsonNode.class) { + return (T) new ObjectMapper().readTree(response.getEntity().getContent()); + } else { + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return mapper.readValue(response.getEntity().getContent(), type); + } } ////////////////////////////////////////////////// @@ -254,50 +383,25 @@ public Volume createVolume(final String name, final String storagePoolId, Preconditions.checkArgument(!Strings.isNullOrEmpty(storagePoolId), "Storage pool id cannot be null"); Preconditions.checkArgument(sizeInGb != null && sizeInGb > 0, "Size(GB) must be greater than 0"); - HttpResponse response = null; - try { - Volume newVolume = new Volume(); - newVolume.setName(name); - newVolume.setStoragePoolId(storagePoolId); - newVolume.setVolumeSizeInGb(sizeInGb); - if (Storage.ProvisioningType.FAT.equals(volumeType)) { - newVolume.setVolumeType(Volume.VolumeType.ThickProvisioned); - } else { - newVolume.setVolumeType(Volume.VolumeType.ThinProvisioned); - } - // The basic allocation granularity is 8GB. The volume size will be rounded up. - response = post("/types/Volume/instances", newVolume); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - Volume newVolumeObject = mapper.readValue(response.getEntity().getContent(), Volume.class); - return getVolume(newVolumeObject.getId()); - } catch (final IOException e) { - LOG.error("Failed to create PowerFlex volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + Volume newVolume = new Volume(); + newVolume.setName(name); + newVolume.setStoragePoolId(storagePoolId); + newVolume.setVolumeSizeInGb(sizeInGb); + if (Storage.ProvisioningType.FAT.equals(volumeType)) { + newVolume.setVolumeType(Volume.VolumeType.ThickProvisioned); + } else { + newVolume.setVolumeType(Volume.VolumeType.ThinProvisioned); } - return null; + // The basic allocation granularity is 8GB. The volume size will be rounded up. + Volume newVolumeObject = post("/types/Volume/instances", newVolume, Volume.class); + return getVolume(newVolumeObject.getId()); } @Override public List listVolumes() { - HttpResponse response = null; - try { - response = get("/types/Volume/instances"); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - Volume[] volumes = mapper.readValue(response.getEntity().getContent(), Volume[].class); + Volume[] volumes = get("/types/Volume/instances", Volume[].class); + if (volumes != null) { return Arrays.asList(volumes); - } catch (final IOException e) { - LOG.error("Failed to list PowerFlex volumes due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } } return new ArrayList<>(); } @@ -313,52 +417,24 @@ public List listSnapshotVolumes() { } } } - return snapshotVolumes; } @Override public Volume getVolume(String volumeId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(volumeId), "Volume id cannot be null"); - - HttpResponse response = null; - try { - response = get("/instances/Volume::" + volumeId); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return mapper.readValue(response.getEntity().getContent(), Volume.class); - } catch (final IOException e) { - LOG.error("Failed to get volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } - } - return null; + return get("/instances/Volume::" + volumeId, Volume.class); } @Override public Volume getVolumeByName(String name) { Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Volume name cannot be null"); - HttpResponse response = null; - try { - Volume searchVolume = new Volume(); - searchVolume.setName(name); - response = post("/types/Volume/instances/action/queryIdByKey", searchVolume); - checkResponseOK(response); - String volumeId = EntityUtils.toString(response.getEntity()); - if (!Strings.isNullOrEmpty(volumeId)) { - return getVolume(volumeId.replace("\"", "")); - } - } catch (final IOException e) { - LOG.error("Failed to get volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + Volume searchVolume = new Volume(); + searchVolume.setName(name); + String volumeId = post("/types/Volume/instances/action/queryIdByKey", searchVolume, String.class); + if (!Strings.isNullOrEmpty(volumeId)) { + return getVolume(volumeId.replace("\"", "")); } return null; } @@ -368,20 +444,11 @@ public boolean renameVolume(final String volumeId, final String newName) { Preconditions.checkArgument(!Strings.isNullOrEmpty(volumeId), "Volume id cannot be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(newName), "New name for volume cannot be null"); - HttpResponse response = null; - try { - response = post( - "/instances/Volume::" + volumeId + "/action/setVolumeName", - String.format("{\"newName\":\"%s\"}", newName)); - checkResponseOK(response); - return true; - } catch (final IOException e) { - LOG.error("Failed to rename PowerFlex volume due to: ", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + Boolean renameVolumeStatus = post( + "/instances/Volume::" + volumeId + "/action/setVolumeName", + String.format("{\"newName\":\"%s\"}", newName), Boolean.class); + if (renameVolumeStatus != null) { + return renameVolumeStatus; } return false; } @@ -392,21 +459,12 @@ public Volume resizeVolume(final String volumeId, final Integer sizeInGB) { Preconditions.checkArgument(sizeInGB != null && (sizeInGB > 0 && sizeInGB % 8 == 0), "Size(GB) must be greater than 0 and in granularity of 8"); - HttpResponse response = null; - try { - // Volume capacity can only be increased. sizeInGB must be a positive number in granularity of 8 GB. - response = post( - "/instances/Volume::" + volumeId + "/action/setVolumeSize", - String.format("{\"sizeInGB\":\"%s\"}", sizeInGB.toString())); - checkResponseOK(response); + // Volume capacity can only be increased. sizeInGB must be a positive number in granularity of 8 GB. + Boolean resizeVolumeStatus = post( + "/instances/Volume::" + volumeId + "/action/setVolumeSize", + String.format("{\"sizeInGB\":\"%s\"}", sizeInGB.toString()), Boolean.class); + if (resizeVolumeStatus != null && resizeVolumeStatus.booleanValue()) { return getVolume(volumeId); - } catch (final IOException e) { - LOG.error("Failed to resize PowerFlex volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } } return null; } @@ -426,33 +484,19 @@ public Volume cloneVolume(final String sourceVolumeId, final String destVolumeNa public SnapshotGroup takeSnapshot(final Map srcVolumeDestSnapshotMap) { Preconditions.checkArgument(srcVolumeDestSnapshotMap != null && !srcVolumeDestSnapshotMap.isEmpty(), "srcVolumeDestSnapshotMap cannot be null"); - HttpResponse response = null; - try { - final List defs = new ArrayList<>(); - for (final String volumeId : srcVolumeDestSnapshotMap.keySet()) { - final SnapshotDef snapshotDef = new SnapshotDef(); - snapshotDef.setVolumeId(volumeId); - String snapshotName = srcVolumeDestSnapshotMap.get(volumeId); - if (!Strings.isNullOrEmpty(snapshotName)) { - snapshotDef.setSnapshotName(srcVolumeDestSnapshotMap.get(volumeId)); - } - defs.add(snapshotDef); - } - final SnapshotDefs snapshotDefs = new SnapshotDefs(); - snapshotDefs.setSnapshotDefs(defs.toArray(new SnapshotDef[0])); - response = post("/instances/System/action/snapshotVolumes", snapshotDefs); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return mapper.readValue(response.getEntity().getContent(), SnapshotGroup.class); - } catch (final IOException e) { - LOG.error("Failed to take snapshot due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); + final List defs = new ArrayList<>(); + for (final String volumeId : srcVolumeDestSnapshotMap.keySet()) { + final SnapshotDef snapshotDef = new SnapshotDef(); + snapshotDef.setVolumeId(volumeId); + String snapshotName = srcVolumeDestSnapshotMap.get(volumeId); + if (!Strings.isNullOrEmpty(snapshotName)) { + snapshotDef.setSnapshotName(srcVolumeDestSnapshotMap.get(volumeId)); } + defs.add(snapshotDef); } - return null; + final SnapshotDefs snapshotDefs = new SnapshotDefs(); + snapshotDefs.setSnapshotDefs(defs.toArray(new SnapshotDef[0])); + return post("/instances/System/action/snapshotVolumes", snapshotDefs, SnapshotGroup.class); } @Override @@ -514,22 +558,12 @@ public int deleteSnapshotGroup(final String systemId, final String snapshotGroup Preconditions.checkArgument(!Strings.isNullOrEmpty(systemId), "System id cannot be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(snapshotGroupId), "Snapshot group id cannot be null"); - HttpResponse response = null; - try { - response = post( - "/instances/System::" + systemId + "/action/removeConsistencyGroupSnapshots", - String.format("{\"snapGroupId\":\"%s\"}", snapshotGroupId)); - checkResponseOK(response); - JsonNode node = new ObjectMapper().readTree(response.getEntity().getContent()); + JsonNode node = post( + "/instances/System::" + systemId + "/action/removeConsistencyGroupSnapshots", + String.format("{\"snapGroupId\":\"%s\"}", snapshotGroupId), JsonNode.class); + if (node != null) { JsonNode noOfVolumesNode = node.get("numberOfVolumes"); return noOfVolumesNode.asInt(); - } catch (final IOException e) { - LOG.error("Failed to delete PowerFlex snapshot group due to: " + e.getMessage(), e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } } return -1; } @@ -539,31 +573,18 @@ public Volume takeSnapshot(final String volumeId, final String snapshotVolumeNam Preconditions.checkArgument(!Strings.isNullOrEmpty(volumeId), "Volume id cannot be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(snapshotVolumeName), "Snapshot name cannot be null"); - HttpResponse response = null; - try { - final SnapshotDef[] snapshotDef = new SnapshotDef[1]; - snapshotDef[0] = new SnapshotDef(); - snapshotDef[0].setVolumeId(volumeId); - snapshotDef[0].setSnapshotName(snapshotVolumeName); - final SnapshotDefs snapshotDefs = new SnapshotDefs(); - snapshotDefs.setSnapshotDefs(snapshotDef); - - response = post("/instances/System/action/snapshotVolumes", snapshotDefs); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - SnapshotGroup snapshotGroup = mapper.readValue(response.getEntity().getContent(), SnapshotGroup.class); - if (snapshotGroup != null) { - List volumeIds = snapshotGroup.getVolumeIds(); - if (volumeIds != null && !volumeIds.isEmpty()) { - return getVolume(volumeIds.get(0)); - } - } - } catch (final IOException e) { - LOG.error("Failed to take snapshot due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); + final SnapshotDef[] snapshotDef = new SnapshotDef[1]; + snapshotDef[0] = new SnapshotDef(); + snapshotDef[0].setVolumeId(volumeId); + snapshotDef[0].setSnapshotName(snapshotVolumeName); + final SnapshotDefs snapshotDefs = new SnapshotDefs(); + snapshotDefs.setSnapshotDefs(snapshotDef); + + SnapshotGroup snapshotGroup = post("/instances/System/action/snapshotVolumes", snapshotDefs, SnapshotGroup.class); + if (snapshotGroup != null) { + List volumeIds = snapshotGroup.getVolumeIds(); + if (volumeIds != null && !volumeIds.isEmpty()) { + return getVolume(volumeIds.get(0)); } } return null; @@ -574,34 +595,25 @@ public boolean revertSnapshot(final String sourceSnapshotVolumeId, final String Preconditions.checkArgument(!Strings.isNullOrEmpty(sourceSnapshotVolumeId), "Source snapshot volume id cannot be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(destVolumeId), "Destination volume id cannot be null"); - HttpResponse response = null; - try { - Volume sourceSnapshotVolume = getVolume(sourceSnapshotVolumeId); - if (sourceSnapshotVolume == null) { - throw new CloudRuntimeException("Source snapshot volume: " + sourceSnapshotVolumeId + " doesn't exists"); - } + Volume sourceSnapshotVolume = getVolume(sourceSnapshotVolumeId); + if (sourceSnapshotVolume == null) { + throw new CloudRuntimeException("Source snapshot volume: " + sourceSnapshotVolumeId + " doesn't exists"); + } - Volume destVolume = getVolume(destVolumeId); - if (sourceSnapshotVolume == null) { - throw new CloudRuntimeException("Destination volume: " + destVolumeId + " doesn't exists"); - } + Volume destVolume = getVolume(destVolumeId); + if (sourceSnapshotVolume == null) { + throw new CloudRuntimeException("Destination volume: " + destVolumeId + " doesn't exists"); + } - if (!sourceSnapshotVolume.getVtreeId().equals(destVolume.getVtreeId())) { - throw new CloudRuntimeException("Unable to revert, source snapshot volume and destination volume doesn't belong to same volume tree"); - } + if (!sourceSnapshotVolume.getVtreeId().equals(destVolume.getVtreeId())) { + throw new CloudRuntimeException("Unable to revert, source snapshot volume and destination volume doesn't belong to same volume tree"); + } - response = post( - "/instances/Volume::" + destVolumeId + "/action/overwriteVolumeContent", - String.format("{\"srcVolumeId\":\"%s\",\"allowOnExtManagedVol\":\"TRUE\"}", sourceSnapshotVolumeId)); - checkResponseOK(response); - return true; - } catch (final IOException e) { - LOG.error("Failed to map PowerFlex volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + Boolean overwriteVolumeContentStatus = post( + "/instances/Volume::" + destVolumeId + "/action/overwriteVolumeContent", + String.format("{\"srcVolumeId\":\"%s\",\"allowOnExtManagedVol\":\"TRUE\"}", sourceSnapshotVolumeId), Boolean.class); + if (overwriteVolumeContentStatus != null) { + return overwriteVolumeContentStatus; } return false; } @@ -611,24 +623,15 @@ public boolean mapVolumeToSdc(final String volumeId, final String sdcId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(volumeId), "Volume id cannot be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(sdcId), "Sdc Id cannot be null"); - HttpResponse response = null; - try { - if (isVolumeMappedToSdc(volumeId, sdcId)) { - return true; - } - - response = post( - "/instances/Volume::" + volumeId + "/action/addMappedSdc", - String.format("{\"sdcId\":\"%s\",\"allowMultipleMappings\":\"TRUE\"}", sdcId)); - checkResponseOK(response); + if (isVolumeMappedToSdc(volumeId, sdcId)) { return true; - } catch (final IOException e) { - LOG.error("Failed to map PowerFlex volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + } + + Boolean mapVolumeToSdcStatus = post( + "/instances/Volume::" + volumeId + "/action/addMappedSdc", + String.format("{\"sdcId\":\"%s\",\"allowMultipleMappings\":\"TRUE\"}", sdcId), Boolean.class); + if (mapVolumeToSdcStatus != null) { + return mapVolumeToSdcStatus; } return false; } @@ -642,31 +645,22 @@ public boolean mapVolumeToSdcWithLimits(final String volumeId, final String sdcI Preconditions.checkArgument(bandwidthLimitInKbps != null && (bandwidthLimitInKbps == 0 || (bandwidthLimitInKbps > 0 && bandwidthLimitInKbps % 1024 == 0)), "Bandwidth limit(Kbps) must be 0 (unlimited) or in granularity of 1024"); - HttpResponse response = null; - try { - if (mapVolumeToSdc(volumeId, sdcId)) { - long iopsLimitVal = 0; - if (iopsLimit != null && iopsLimit.longValue() > 0) { - iopsLimitVal = iopsLimit.longValue(); - } - - long bandwidthLimitInKbpsVal = 0; - if (bandwidthLimitInKbps != null && bandwidthLimitInKbps.longValue() > 0) { - bandwidthLimitInKbpsVal = bandwidthLimitInKbps.longValue(); - } + if (mapVolumeToSdc(volumeId, sdcId)) { + long iopsLimitVal = 0; + if (iopsLimit != null && iopsLimit.longValue() > 0) { + iopsLimitVal = iopsLimit.longValue(); + } - response = post( - "/instances/Volume::" + volumeId + "/action/setMappedSdcLimits", - String.format("{\"sdcId\":\"%s\",\"bandwidthLimitInKbps\":\"%d\",\"iopsLimit\":\"%d\"}", sdcId, bandwidthLimitInKbpsVal, iopsLimitVal)); - checkResponseOK(response); - return true; + long bandwidthLimitInKbpsVal = 0; + if (bandwidthLimitInKbps != null && bandwidthLimitInKbps.longValue() > 0) { + bandwidthLimitInKbpsVal = bandwidthLimitInKbps.longValue(); } - } catch (final IOException e) { - LOG.error("Failed to map PowerFlex volume with limits due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); + + Boolean setVolumeSdcLimitsStatus = post( + "/instances/Volume::" + volumeId + "/action/setMappedSdcLimits", + String.format("{\"sdcId\":\"%s\",\"bandwidthLimitInKbps\":\"%d\",\"iopsLimit\":\"%d\"}", sdcId, bandwidthLimitInKbpsVal, iopsLimitVal), Boolean.class); + if (setVolumeSdcLimitsStatus != null) { + return setVolumeSdcLimitsStatus; } } return false; @@ -677,21 +671,12 @@ public boolean unmapVolumeFromSdc(final String volumeId, final String sdcId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(volumeId), "Volume id cannot be null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(sdcId), "Sdc Id cannot be null"); - HttpResponse response = null; - try { - if (isVolumeMappedToSdc(volumeId, sdcId)) { - response = post( - "/instances/Volume::" + volumeId + "/action/removeMappedSdc", - String.format("{\"sdcId\":\"%s\",\"skipApplianceValidation\":\"TRUE\"}", sdcId)); - checkResponseOK(response); - return true; - } - } catch (final IOException e) { - LOG.error("Failed to unmap PowerFlex volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); + if (isVolumeMappedToSdc(volumeId, sdcId)) { + Boolean unmapVolumeFromSdcStatus = post( + "/instances/Volume::" + volumeId + "/action/removeMappedSdc", + String.format("{\"sdcId\":\"%s\",\"skipApplianceValidation\":\"TRUE\"}", sdcId), Boolean.class); + if (unmapVolumeFromSdcStatus != null) { + return unmapVolumeFromSdcStatus; } } return false; @@ -701,30 +686,21 @@ public boolean unmapVolumeFromSdc(final String volumeId, final String sdcId) { public boolean unmapVolumeFromAllSdcs(final String volumeId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(volumeId), "Volume id cannot be null"); - HttpResponse response = null; - try { - Volume volume = getVolume(volumeId); - if (volume == null) { - return false; - } - - List mappedSdcList = volume.getMappedSdcList(); - if (mappedSdcList == null || mappedSdcList.isEmpty()) { - return true; - } + Volume volume = getVolume(volumeId); + if (volume == null) { + return false; + } - response = post( - "/instances/Volume::" + volumeId + "/action/removeMappedSdc", - "{\"allSdcs\": \"\"}"); - checkResponseOK(response); + List mappedSdcList = volume.getMappedSdcList(); + if (mappedSdcList == null || mappedSdcList.isEmpty()) { return true; - } catch (final IOException e) { - LOG.error("Failed to unmap PowerFlex volume from all SDCs due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + } + + Boolean unmapVolumeFromAllSdcsStatus = post( + "/instances/Volume::" + volumeId + "/action/removeMappedSdc", + "{\"allSdcs\": \"\"}", Boolean.class); + if (unmapVolumeFromAllSdcsStatus != null) { + return unmapVolumeFromAllSdcsStatus; } return false; } @@ -759,23 +735,14 @@ public boolean isVolumeMappedToSdc(final String volumeId, final String sdcId) { public boolean deleteVolume(final String volumeId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(volumeId), "Volume id cannot be null"); - HttpResponse response = null; try { - try { - unmapVolumeFromAllSdcs(volumeId); - } catch (Exception ignored) {} - response = post( - "/instances/Volume::" + volumeId + "/action/removeVolume", - "{\"removeMode\":\"ONLY_ME\"}"); - checkResponseOK(response); - return true; - } catch (final IOException e) { - LOG.error("Failed to delete PowerFlex volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + unmapVolumeFromAllSdcs(volumeId); + } catch (Exception ignored) {} + Boolean removeVolumeStatus = post( + "/instances/Volume::" + volumeId + "/action/removeVolume", + "{\"removeMode\":\"ONLY_ME\"}", Boolean.class); + if (removeVolumeStatus != null) { + return removeVolumeStatus; } return false; } @@ -797,21 +764,8 @@ public boolean migrateVolume(final String srcVolumeId, final String destPoolId, LOG.debug("Migrating the volume: " + srcVolumeId + " on the src pool: " + srcPoolId + " to the dest pool: " + destPoolId + " in the same PowerFlex cluster"); - HttpResponse response = null; - try { - response = post( - "/instances/Volume::" + srcVolumeId + "/action/migrateVTree", - String.format("{\"destSPId\":\"%s\"}", destPoolId)); - checkResponseOK(response); - } catch (final IOException e) { - LOG.error("Unable to migrate PowerFlex volume due to: ", e); - checkResponseTimeOut(e); - throw e; - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } - } + post("/instances/Volume::" + srcVolumeId + "/action/migrateVTree", + String.format("{\"destSPId\":\"%s\"}", destPoolId), Boolean.class); LOG.debug("Wait until the migration is complete for the volume: " + srcVolumeId); long migrationStartTime = System.currentTimeMillis(); @@ -899,22 +853,9 @@ private VTreeMigrationInfo.MigrationStatus getVolumeTreeMigrationStatus(final St return null; } - HttpResponse response = null; - try { - response = get("/instances/VTree::" + volumeTreeId); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - VTree volumeTree = mapper.readValue(response.getEntity().getContent(), VTree.class); - if (volumeTree != null && volumeTree.getVTreeMigrationInfo() != null) { - return volumeTree.getVTreeMigrationInfo().getMigrationStatus(); - } - } catch (final IOException e) { - LOG.error("Failed to migrate PowerFlex volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + VTree volumeTree = get("/instances/VTree::" + volumeTreeId, VTree.class); + if (volumeTree != null && volumeTree.getVTreeMigrationInfo() != null) { + return volumeTree.getVTreeMigrationInfo().getMigrationStatus(); } return null; } @@ -922,53 +863,49 @@ private VTreeMigrationInfo.MigrationStatus getVolumeTreeMigrationStatus(final St private boolean rollbackVolumeMigration(final String srcVolumeId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(srcVolumeId), "src volume id cannot be null"); - HttpResponse response = null; - try { - Volume volume = getVolume(srcVolumeId); - VTreeMigrationInfo.MigrationStatus migrationStatus = getVolumeTreeMigrationStatus(volume.getVtreeId()); - if (migrationStatus != null && migrationStatus == VTreeMigrationInfo.MigrationStatus.NotInMigration) { - LOG.debug("Volume: " + srcVolumeId + " is not migrating, no need to rollback"); - return true; - } + Volume volume = getVolume(srcVolumeId); + if (volume == null) { + LOG.warn("Unable to rollback volume migration, couldn't get details for the volume: " + srcVolumeId); + return false; + } - pauseVolumeMigration(srcVolumeId, true); // Pause forcefully - // Wait few secs for volume migration to change to Paused state - boolean paused = false; - int retryCount = 3; - while (retryCount > 0) { - try { - Thread.sleep(3000); // Try after few secs - migrationStatus = getVolumeTreeMigrationStatus(volume.getVtreeId()); // Get updated migration status - if (migrationStatus != null && migrationStatus == VTreeMigrationInfo.MigrationStatus.Paused) { - LOG.debug("Migration for the volume: " + srcVolumeId + " paused"); - paused = true; - break; - } - } catch (Exception ex) { - LOG.warn("Exception while checking for migration pause status of the volume: " + srcVolumeId + " - " + ex.getLocalizedMessage()); - // don't do anything - } finally { - retryCount--; + VTreeMigrationInfo.MigrationStatus migrationStatus = getVolumeTreeMigrationStatus(volume.getVtreeId()); + if (migrationStatus != null && migrationStatus == VTreeMigrationInfo.MigrationStatus.NotInMigration) { + LOG.debug("Volume: " + srcVolumeId + " is not migrating, no need to rollback"); + return true; + } + + pauseVolumeMigration(srcVolumeId, true); // Pause forcefully + // Wait few secs for volume migration to change to Paused state + boolean paused = false; + int retryCount = 3; + while (retryCount > 0) { + try { + Thread.sleep(3000); // Try after few secs + migrationStatus = getVolumeTreeMigrationStatus(volume.getVtreeId()); // Get updated migration status + if (migrationStatus != null && migrationStatus == VTreeMigrationInfo.MigrationStatus.Paused) { + LOG.debug("Migration for the volume: " + srcVolumeId + " paused"); + paused = true; + break; } + } catch (Exception ex) { + LOG.warn("Exception while checking for migration pause status of the volume: " + srcVolumeId + " - " + ex.getLocalizedMessage()); + // don't do anything + } finally { + retryCount--; } + } - if (paused) { - // Rollback migration to the src pool (should be quick) - response = post( - "/instances/Volume::" + srcVolumeId + "/action/migrateVTree", - String.format("{\"destSPId\":\"%s\"}", volume.getStoragePoolId())); - checkResponseOK(response); - return true; - } else { - LOG.warn("Migration for the volume: " + srcVolumeId + " didn't pause, couldn't rollback"); - } - } catch (final IOException e) { - LOG.error("Failed to rollback volume migration due to: ", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); + if (paused) { + // Rollback migration to the src pool (should be quick) + Boolean migrateVTreeStatus = post( + "/instances/Volume::" + srcVolumeId + "/action/migrateVTree", + String.format("{\"destSPId\":\"%s\"}", volume.getStoragePoolId()), Boolean.class); + if (migrateVTreeStatus != null) { + return migrateVTreeStatus; } + } else { + LOG.warn("Migration for the volume: " + srcVolumeId + " didn't pause, couldn't rollback"); } return false; } @@ -979,23 +916,14 @@ private boolean pauseVolumeMigration(final String volumeId, final boolean forced return false; } - HttpResponse response = null; - try { - // When paused gracefully, all data currently being moved is allowed to complete the migration. - // When paused forcefully, migration of unfinished data is aborted and data is left at the source, if possible. - // Pausing forcefully carries a potential risk to data. - response = post( - "/instances/Volume::" + volumeId + "/action/pauseVTreeMigration", - String.format("{\"pauseType\":\"%s\"}", forced ? "Forcefully" : "Gracefully")); - checkResponseOK(response); - return true; - } catch (final IOException e) { - LOG.error("Failed to pause migration of the volume due to: ", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + // When paused gracefully, all data currently being moved is allowed to complete the migration. + // When paused forcefully, migration of unfinished data is aborted and data is left at the source, if possible. + // Pausing forcefully carries a potential risk to data. + Boolean pauseVTreeMigrationStatus = post( + "/instances/Volume::" + volumeId + "/action/pauseVTreeMigration", + String.format("{\"pauseType\":\"%s\"}", forced ? "Forcefully" : "Gracefully"), Boolean.class); + if (pauseVTreeMigrationStatus != null) { + return pauseVTreeMigrationStatus; } return false; } @@ -1006,20 +934,9 @@ private boolean pauseVolumeMigration(final String volumeId, final boolean forced @Override public List listStoragePools() { - HttpResponse response = null; - try { - response = get("/types/StoragePool/instances"); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - StoragePool[] pools = mapper.readValue(response.getEntity().getContent(), StoragePool[].class); + StoragePool[] pools = get("/types/StoragePool/instances", StoragePool[].class); + if (pools != null) { return Arrays.asList(pools); - } catch (final IOException e) { - LOG.error("Failed to list PowerFlex storage pools due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } } return new ArrayList<>(); } @@ -1027,72 +944,29 @@ public List listStoragePools() { @Override public StoragePool getStoragePool(String poolId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(poolId), "Storage pool id cannot be null"); - - HttpResponse response = null; - try { - response = get("/instances/StoragePool::" + poolId); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return mapper.readValue(response.getEntity().getContent(), StoragePool.class); - } catch (final IOException e) { - LOG.error("Failed to get storage pool due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } - } - return null; + return get("/instances/StoragePool::" + poolId, StoragePool.class); } @Override public StoragePoolStatistics getStoragePoolStatistics(String poolId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(poolId), "Storage pool id cannot be null"); - - HttpResponse response = null; - try { - response = get("/instances/StoragePool::" + poolId + "/relationships/Statistics"); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return mapper.readValue(response.getEntity().getContent(), StoragePoolStatistics.class); - } catch (final IOException e) { - LOG.error("Failed to get storage pool due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } - } - return null; + return get("/instances/StoragePool::" + poolId + "/relationships/Statistics", StoragePoolStatistics.class); } @Override public VolumeStatistics getVolumeStatistics(String volumeId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(volumeId), "Volume id cannot be null"); - HttpResponse response = null; - try { - Volume volume = getVolume(volumeId); - if (volume != null) { - String volumeTreeId = volume.getVtreeId(); - if (!Strings.isNullOrEmpty(volumeTreeId)) { - response = get("/instances/VTree::" + volumeTreeId + "/relationships/Statistics"); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - VolumeStatistics volumeStatistics = mapper.readValue(response.getEntity().getContent(), VolumeStatistics.class); - if (volumeStatistics != null) { - volumeStatistics.setAllocatedSizeInKb(volume.getSizeInKb()); - return volumeStatistics; - } + Volume volume = getVolume(volumeId); + if (volume != null) { + String volumeTreeId = volume.getVtreeId(); + if (!Strings.isNullOrEmpty(volumeTreeId)) { + VolumeStatistics volumeStatistics = get("/instances/VTree::" + volumeTreeId + "/relationships/Statistics", VolumeStatistics.class); + if (volumeStatistics != null) { + volumeStatistics.setAllocatedSizeInKb(volume.getSizeInKb()); + return volumeStatistics; } } - } catch (final IOException e) { - LOG.error("Failed to get volume stats due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } } return null; @@ -1102,22 +976,9 @@ public VolumeStatistics getVolumeStatistics(String volumeId) { public String getSystemId(String protectionDomainId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(protectionDomainId), "Protection domain id cannot be null"); - HttpResponse response = null; - try { - response = get("/instances/ProtectionDomain::" + protectionDomainId); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - ProtectionDomain protectionDomain = mapper.readValue(response.getEntity().getContent(), ProtectionDomain.class); - if (protectionDomain != null) { - return protectionDomain.getSystemId(); - } - } catch (final IOException e) { - LOG.error("Failed to get protection domain details due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + ProtectionDomain protectionDomain = get("/instances/ProtectionDomain::" + protectionDomainId, ProtectionDomain.class); + if (protectionDomain != null) { + return protectionDomain.getSystemId(); } return null; } @@ -1126,20 +987,9 @@ public String getSystemId(String protectionDomainId) { public List listVolumesInStoragePool(String poolId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(poolId), "Storage pool id cannot be null"); - HttpResponse response = null; - try { - response = get("/instances/StoragePool::" + poolId + "/relationships/Volume"); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - Volume[] volumes = mapper.readValue(response.getEntity().getContent(), Volume[].class); + Volume[] volumes = get("/instances/StoragePool::" + poolId + "/relationships/Volume", Volume[].class); + if (volumes != null) { return Arrays.asList(volumes); - } catch (final IOException e) { - LOG.error("Failed to list volumes in storage pool due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } } return new ArrayList<>(); } @@ -1150,20 +1000,9 @@ public List listVolumesInStoragePool(String poolId) { @Override public List listSdcs() { - HttpResponse response = null; - try { - response = get("/types/Sdc/instances"); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - Sdc[] sdcs = mapper.readValue(response.getEntity().getContent(), Sdc[].class); + Sdc[] sdcs = get("/types/Sdc/instances", Sdc[].class); + if (sdcs != null) { return Arrays.asList(sdcs); - } catch (final IOException e) { - LOG.error("Failed to list SDCs due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } } return new ArrayList<>(); } @@ -1171,43 +1010,16 @@ public List listSdcs() { @Override public Sdc getSdc(String sdcId) { Preconditions.checkArgument(!Strings.isNullOrEmpty(sdcId), "Sdc id cannot be null"); - - HttpResponse response = null; - try { - response = get("/instances/Sdc::" + sdcId); - checkResponseOK(response); - ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return mapper.readValue(response.getEntity().getContent(), Sdc.class); - } catch (final IOException e) { - LOG.error("Failed to get volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } - } - return null; + return get("/instances/Sdc::" + sdcId, Sdc.class); } @Override public Sdc getSdcByIp(String ipAddress) { Preconditions.checkArgument(!Strings.isNullOrEmpty(ipAddress), "IP address cannot be null"); - HttpResponse response = null; - try { - response = post("/types/Sdc/instances/action/queryIdByKey", String.format("{\"ip\":\"%s\"}", ipAddress)); - checkResponseOK(response); - String sdcId = EntityUtils.toString(response.getEntity()); - if (!Strings.isNullOrEmpty(sdcId)) { - return getSdc(sdcId.replace("\"", "")); - } - } catch (final IOException e) { - LOG.error("Failed to get volume due to:", e); - checkResponseTimeOut(e); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + String sdcId = post("/types/Sdc/instances/action/queryIdByKey", String.format("{\"ip\":\"%s\"}", ipAddress), String.class); + if (!Strings.isNullOrEmpty(sdcId)) { + return getSdc(sdcId.replace("\"", "")); } return null; } @@ -1252,4 +1064,27 @@ public boolean isSdcConnected(String ipAddress) { return false; } + + private String getConnectionManagerStats() { + StringBuilder sb = new StringBuilder(); + sb.append("\n").append("Client Connection Manager Stats => "); + if (connectionManager != null) { + sb.append("MaxTotal: ").append(connectionManager.getMaxTotal()).append(", "); + sb.append("DefaultMaxPerRoute: ").append(connectionManager.getDefaultMaxPerRoute()); + + PoolStats poolStats = connectionManager.getTotalStats(); + if (poolStats != null) { + sb.append(", "); + sb.append("Available: ").append(poolStats.getAvailable()).append(", "); + sb.append("Leased: ").append(poolStats.getLeased()).append(", "); + sb.append("Max: ").append(poolStats.getMax()).append(", "); + sb.append("Pending: ").append(poolStats.getPending()); + } + } else { + sb.append("NULL"); + } + + sb.append("\n"); + return sb.toString(); + } } diff --git a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ScaleIOPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ScaleIOPrimaryDataStoreLifeCycle.java index 5c9ddea47526..edebdac79299 100644 --- a/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ScaleIOPrimaryDataStoreLifeCycle.java +++ b/plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ScaleIOPrimaryDataStoreLifeCycle.java @@ -106,7 +106,8 @@ public ScaleIOPrimaryDataStoreLifeCycle() { private org.apache.cloudstack.storage.datastore.api.StoragePool findStoragePool(String url, String username, String password, String storagePoolName) { try { final int clientTimeout = StorageManager.STORAGE_POOL_CLIENT_TIMEOUT.value(); - ScaleIOGatewayClient client = ScaleIOGatewayClient.getClient(url, username, password, false, clientTimeout); + final int clientMaxConnections = StorageManager.STORAGE_POOL_CLIENT_MAX_CONNECTIONS.value(); + ScaleIOGatewayClient client = ScaleIOGatewayClient.getClient(url, username, password, false, clientTimeout, clientMaxConnections); List storagePools = client.listStoragePools(); for (org.apache.cloudstack.storage.datastore.api.StoragePool pool : storagePools) { if (pool.getName().equals(storagePoolName)) { @@ -121,9 +122,9 @@ private org.apache.cloudstack.storage.datastore.api.StoragePool findStoragePool( } } catch (NoSuchAlgorithmException | KeyManagementException | URISyntaxException e) { LOGGER.error("Failed to add storage pool", e); - throw new CloudRuntimeException("Failed to establish connection with PowerFlex Gateway to validate storage pool"); + throw new CloudRuntimeException("Failed to establish connection with PowerFlex Gateway to find and validate storage pool: " + storagePoolName); } - throw new CloudRuntimeException("Failed to find the provided storage pool name in discovered PowerFlex storage pools"); + throw new CloudRuntimeException("Failed to find the provided storage pool name: " + storagePoolName + " in the discovered PowerFlex storage pools"); } @SuppressWarnings("unchecked") diff --git a/plugins/storage/volume/scaleio/src/test/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImplTest.java b/plugins/storage/volume/scaleio/src/test/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImplTest.java index 10823102cf8d..80a78c809095 100644 --- a/plugins/storage/volume/scaleio/src/test/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImplTest.java +++ b/plugins/storage/volume/scaleio/src/test/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImplTest.java @@ -19,30 +19,179 @@ package org.apache.cloudstack.storage.datastore.client; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.containing; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.unauthorized; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; + +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.storage.datastore.api.Volume; import org.junit.After; +import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; +import com.cloud.storage.Storage; import com.cloud.utils.exception.CloudRuntimeException; +import com.github.tomakehurst.wiremock.client.BasicCredentials; +import com.github.tomakehurst.wiremock.junit.WireMockRule; @RunWith(MockitoJUnitRunner.class) public class ScaleIOGatewayClientImplTest { + private final int port = 443; + private final int timeout = 30; + private final int maxConnections = 50; + private final String username = "admin"; + private final String password = "P@ssword123"; + private final String sessionKey = "YWRtaW46MTYyMzM0OTc4NDk0MTo2MWQ2NGQzZWJhMTVmYTVkNDIwNjZmOWMwZDg0ZGZmOQ"; + private ScaleIOGatewayClient client = null; - ScaleIOGatewayClientImpl client; + @Rule + public WireMockRule wireMockRule = new WireMockRule(wireMockConfig() + .httpsPort(port) + .needClientAuth(false) + .basicAdminAuthenticator(username, password) + .bindAddress("localhost")); @Before public void setUp() throws Exception { + wireMockRule.stubFor(get("/api/login") + .willReturn(ok() + .withHeader("Content-Type", "application/json;charset=UTF-8") + .withBody(sessionKey))); + + client = new ScaleIOGatewayClientImpl("https://localhost/api", username, password, false, timeout, maxConnections); + + wireMockRule.stubFor(post("/api/types/Volume/instances") + .willReturn(aResponse() + .withHeader("Content-Type", "application/json;charset=UTF-8") + .withStatus(200) + .withBody("{\"id\":\"c948d0b10000000a\"}"))); + + wireMockRule.stubFor(get("/api/instances/Volume::c948d0b10000000a") + .willReturn(aResponse() + .withHeader("Content-Type", "application/json;charset=UTF-8") + .withStatus(200) + .withBody("{\"storagePoolId\":\"4daaa55e00000000\",\"dataLayout\":\"MediumGranularity\",\"vtreeId\":\"657e289500000009\"," + + "\"sizeInKb\":8388608,\"snplIdOfAutoSnapshot\":null,\"volumeType\":\"ThinProvisioned\",\"consistencyGroupId\":null," + + "\"ancestorVolumeId\":null,\"notGenuineSnapshot\":false,\"accessModeLimit\":\"ReadWrite\",\"secureSnapshotExpTime\":0," + + "\"useRmcache\":false,\"managedBy\":\"ScaleIO\",\"lockedAutoSnapshot\":false,\"lockedAutoSnapshotMarkedForRemoval\":false," + + "\"autoSnapshotGroupId\":null,\"compressionMethod\":\"Invalid\",\"pairIds\":null,\"timeStampIsAccurate\":false,\"mappedSdcInfo\":null," + + "\"retentionLevels\":[],\"snplIdOfSourceVolume\":null,\"volumeReplicationState\":\"UnmarkedForReplication\",\"replicationJournalVolume\":false," + + "\"replicationTimeStamp\":0,\"originalExpiryTime\":0,\"creationTime\":1623335880,\"name\":\"testvolume\",\"id\":\"c948d0b10000000a\"}"))); } @After public void tearDown() throws Exception { } + @Test + public void testClientAuthSuccess() { + Assert.assertNotNull(client); + wireMockRule.verify(getRequestedFor(urlEqualTo("/api/login")) + .withBasicAuth(new BasicCredentials(username, password))); + + wireMockRule.stubFor(get("/api/types/StoragePool/instances") + .willReturn(aResponse() + .withHeader("Content-Type", "application/json;charset=UTF-8") + .withStatus(200) + .withBody(""))); + + client.listStoragePools(); + + wireMockRule.verify(getRequestedFor(urlEqualTo("/api/types/StoragePool/instances")) + .withBasicAuth(new BasicCredentials(username, sessionKey))); + } + @Test(expected = CloudRuntimeException.class) - public void testClient() throws Exception { - client = (ScaleIOGatewayClientImpl) ScaleIOGatewayClient.getClient("https://10.2.3.149/api", - "admin", "P@ssword123", false, 60); + public void testClientAuthFailure() throws Exception { + wireMockRule.stubFor(get("/api/login") + .willReturn(unauthorized() + .withHeader("Content-Type", "application/json;charset=UTF-8") + .withBody(""))); + + new ScaleIOGatewayClientImpl("https://localhost/api", username, password, false, timeout, maxConnections); + } + + @Test(expected = ServerApiException.class) + public void testRequestTimeout() { + Assert.assertNotNull(client); + wireMockRule.verify(getRequestedFor(urlEqualTo("/api/login")) + .withBasicAuth(new BasicCredentials(username, password))); + + wireMockRule.stubFor(get("/api/types/StoragePool/instances") + .willReturn(aResponse() + .withHeader("Content-Type", "application/json;charset=UTF-8") + .withStatus(200) + .withFixedDelay(2 * timeout * 1000) + .withBody(""))); + + client.listStoragePools(); + } + + @Test + public void testCreateSingleVolume() { + Assert.assertNotNull(client); + wireMockRule.verify(getRequestedFor(urlEqualTo("/api/login")) + .withBasicAuth(new BasicCredentials(username, password))); + + final String volumeName = "testvolume"; + final String scaleIOStoragePoolId = "4daaa55e00000000"; + final int sizeInGb = 8; + Volume scaleIOVolume = client.createVolume(volumeName, scaleIOStoragePoolId, sizeInGb, Storage.ProvisioningType.THIN); + + wireMockRule.verify(postRequestedFor(urlEqualTo("/api/types/Volume/instances")) + .withBasicAuth(new BasicCredentials(username, sessionKey)) + .withRequestBody(containing("\"name\":\"" + volumeName + "\"")) + .withHeader("Content-Type", equalTo("application/json"))); + wireMockRule.verify(getRequestedFor(urlEqualTo("/api/instances/Volume::c948d0b10000000a")) + .withBasicAuth(new BasicCredentials(username, sessionKey))); + + Assert.assertNotNull(scaleIOVolume); + Assert.assertEquals(scaleIOVolume.getId(), "c948d0b10000000a"); + Assert.assertEquals(scaleIOVolume.getName(), volumeName); + Assert.assertEquals(scaleIOVolume.getStoragePoolId(), scaleIOStoragePoolId); + Assert.assertEquals(scaleIOVolume.getSizeInKb(), Long.valueOf(sizeInGb * 1024 * 1024)); + Assert.assertEquals(scaleIOVolume.getVolumeType(), Volume.VolumeType.ThinProvisioned); + } + + @Test + public void testCreateMultipleVolumes() { + Assert.assertNotNull(client); + wireMockRule.verify(getRequestedFor(urlEqualTo("/api/login")) + .withBasicAuth(new BasicCredentials(username, password))); + + final String volumeNamePrefix = "testvolume_"; + final String scaleIOStoragePoolId = "4daaa55e00000000"; + final int sizeInGb = 8; + final int volumesCount = 1000; + + for (int i = 1; i <= volumesCount; i++) { + String volumeName = volumeNamePrefix + i; + Volume scaleIOVolume = client.createVolume(volumeName, scaleIOStoragePoolId, sizeInGb, Storage.ProvisioningType.THIN); + + Assert.assertNotNull(scaleIOVolume); + Assert.assertEquals(scaleIOVolume.getId(), "c948d0b10000000a"); + Assert.assertEquals(scaleIOVolume.getStoragePoolId(), scaleIOStoragePoolId); + Assert.assertEquals(scaleIOVolume.getSizeInKb(), Long.valueOf(sizeInGb * 1024 * 1024)); + Assert.assertEquals(scaleIOVolume.getVolumeType(), Volume.VolumeType.ThinProvisioned); + } + + wireMockRule.verify(volumesCount, postRequestedFor(urlEqualTo("/api/types/Volume/instances")) + .withBasicAuth(new BasicCredentials(username, sessionKey)) + .withRequestBody(containing("\"name\":\"" + volumeNamePrefix)) + .withHeader("Content-Type", equalTo("application/json"))); + wireMockRule.verify(volumesCount, getRequestedFor(urlEqualTo("/api/instances/Volume::c948d0b10000000a")) + .withBasicAuth(new BasicCredentials(username, sessionKey))); } } \ No newline at end of file diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java index cb7e4b5185d6..f431945c6321 100755 --- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java @@ -474,6 +474,9 @@ private void populateConfigValuesForValidationSet() { configValuesForValidation.add("externaldhcp.vmip.max.retry"); configValuesForValidation.add("externaldhcp.vmipFetch.threadPool.max"); configValuesForValidation.add("remote.access.vpn.psk.length"); + configValuesForValidation.add(StorageManager.STORAGE_POOL_DISK_WAIT.key()); + configValuesForValidation.add(StorageManager.STORAGE_POOL_CLIENT_TIMEOUT.key()); + configValuesForValidation.add(StorageManager.STORAGE_POOL_CLIENT_MAX_CONNECTIONS.key()); } private void weightBasedParametersForValidation() { diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 5e7be3083239..9e6cb3fc0409 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -3130,6 +3130,7 @@ public ConfigKey[] getConfigKeys() { MaxNumberOfManagedClusteredFileSystems, STORAGE_POOL_DISK_WAIT, STORAGE_POOL_CLIENT_TIMEOUT, + STORAGE_POOL_CLIENT_MAX_CONNECTIONS, PRIMARY_STORAGE_DOWNLOAD_WAIT, SecStorageMaxMigrateSessions, MaxDataMigrationWaitTime diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index a2b2a4978c0d..bdad40fc90fd 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -1485,6 +1485,13 @@ protected void cleanVolumesCache(VolumeVO volume) { } } + private void removeVolume(long volumeId) { + final VolumeVO volume = _volsDao.findById(volumeId); + if (volume != null) { + _volsDao.remove(volumeId); + } + } + protected boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException { return _volStateMachine.transitTo(vol, event, null, _volsDao); } @@ -1526,6 +1533,7 @@ public Volume destroyVolume(long volumeId, Account caller, boolean expunge, bool } } + removeVolume(volume.getId()); return volume; } @@ -1621,6 +1629,9 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device if (destPrimaryStorage != null && (volumeToAttach.getState() == Volume.State.Allocated || volumeOnSecondary)) { try { + if (volumeOnSecondary && destPrimaryStorage.getPoolType() == Storage.StoragePoolType.PowerFlex) { + throw new InvalidParameterValueException("Cannot attach uploaded volume, this operation is unsupported on storage pool type " + destPrimaryStorage.getPoolType()); + } newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType, destPrimaryStorage); } catch (NoTransitionException e) { s_logger.debug("Failed to create volume on primary storage", e); From 2e32c2fcd9c59be7a0697922717b603f63fa7ab3 Mon Sep 17 00:00:00 2001 From: dahn Date: Wed, 16 Jun 2021 12:55:54 +0200 Subject: [PATCH 008/120] travis: allow big contents from error output in marvin tests (#5113) Co-authored-by: Daan Hoogland --- tools/travis/xunit-reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/travis/xunit-reader.py b/tools/travis/xunit-reader.py index 659d3e60af96..5cfee094356d 100755 --- a/tools/travis/xunit-reader.py +++ b/tools/travis/xunit-reader.py @@ -78,7 +78,7 @@ def parse_reports(file_path_list): exit_code = 0 for file_path in file_path_list: - data = lxml.etree.iterparse(file_path, tag='testcase') + data = lxml.etree.iterparse(file_path, tag='testcase', huge_tree=True) for event, elem in data: name = '' status = 'Success' From 326e03bc9c5fbcc22e676f46ec005919f0bdc3d7 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Wed, 16 Jun 2021 17:58:46 +0530 Subject: [PATCH 009/120] ui: Fix typo in error message on login page (#5118) --- ui/public/locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 1f835756b6fe..cd07ee2f25b5 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -2766,7 +2766,7 @@ "message.error.custom.disk.size": "Please enter custom disk size", "message.error.date": "Please select a date", "message.error.description": "Please enter description", -"message.error.discovering.feature": "Exception caught while discoverying features", +"message.error.discovering.feature": "Exception caught while discovering features", "message.error.display.text": "Please enter display text", "message.error.domain": "Enter your domain, leave empty for ROOT domain", "message.error.enable.saml": "Unable to find users IDs to enable SAML Single Sign On, kindly enable it manually.", From 46a303217839a8abe22de300fce982a8ad662308 Mon Sep 17 00:00:00 2001 From: Wei Zhou <57355700+weizhouapache@users.noreply.github.com> Date: Wed, 16 Jun 2021 17:49:42 +0200 Subject: [PATCH 010/120] server: set correct gateway when update vm nic on shared networks (#5105) This PR fixes the issue that nic has wrong gateway after updating vm nic. Steps to reproduce the issue (1) create shared network (in advanced zone or advanced zone with sg) (2) create new shared network (with same startip/endip/netmask, but different gateway). (3) create a vm in new network (4) stop vm and update vm nic ip address Expected result: The vm has correct gateway and netmask (of second network) Actual result: The vm has wrong gateway and netmask (of first network) --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- server/src/test/java/com/cloud/vm/UserVmManagerTest.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index adc8c3240404..6d8587437457 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -1728,7 +1728,7 @@ public UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd) { throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, please choose another ip"); } - final IPAddressVO newIp = _ipAddressDao.findByIpAndDcId(dc.getId(), ipaddr); + final IPAddressVO newIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), ipaddr); final Vlan vlan = _vlanDao.findById(newIp.getVlanId()); nicVO.setIPv4Gateway(vlan.getVlanGateway()); nicVO.setIPv4Netmask(vlan.getVlanNetmask()); diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerTest.java index 9d58f4f00b5a..1103fb179611 100644 --- a/server/src/test/java/com/cloud/vm/UserVmManagerTest.java +++ b/server/src/test/java/com/cloud/vm/UserVmManagerTest.java @@ -604,6 +604,7 @@ public void testUpdateVmNicIpSuccess2() throws Exception { NicVO nic = new NicVO("nic", 1L, 2L, VirtualMachine.Type.User); when(_nicDao.findById(anyLong())).thenReturn(nic); + nic.setIPv4Address("10.10.10.9"); when(_vmDao.findById(anyLong())).thenReturn(_vmMock); when(_networkDao.findById(anyLong())).thenReturn(_networkMock); doReturn(9L).when(_networkMock).getNetworkOfferingId(); @@ -630,9 +631,9 @@ public void testUpdateVmNicIpSuccess2() throws Exception { when(vlan.getVlanNetmask()).thenReturn("255.255.255.0"); when(_ipAddrMgr.allocatePublicIpForGuestNic(Mockito.eq(_networkMock), nullable(Long.class), Mockito.eq(_accountMock), anyString())).thenReturn("10.10.10.10"); - lenient().when(_ipAddressDao.findByIpAndSourceNetworkId(anyLong(), anyString())).thenReturn(null); + when(_ipAddressDao.findByIpAndSourceNetworkId(anyLong(), eq("10.10.10.10"))).thenReturn(newIp); + when(_ipAddressDao.findByIpAndSourceNetworkId(anyLong(), eq("10.10.10.9"))).thenReturn(null); when(_nicDao.persist(any(NicVO.class))).thenReturn(nic); - when(_ipAddressDao.findByIpAndDcId(anyLong(), anyString())).thenReturn(newIp); when(_vlanDao.findById(anyLong())).thenReturn(vlan); Account caller = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString()); From a3f39db62b6e48e0e9677839f6bc6807be5b32be Mon Sep 17 00:00:00 2001 From: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> Date: Thu, 17 Jun 2021 03:27:52 -0300 Subject: [PATCH 011/120] server: Remove meaningless password regeneration on resetSSHKeyForVirtualMachine (#4819) On API `resetSSHKeyForVirtualMachine`, ACS also regenerates VM password when it uses a template with `Password Enabled` as true; there is already anAPI to reset VM password, therefore, the reset SSH keys API should not reset the VM SSH password as well. Besides running a meaningless process, the VM's password regeneration slows down the main process and may cause a confusion in operations due to password change in the VM without being explicity requested. Co-authored-by: Daniel Augusto Veronezi Salvador --- .../cloud/server/ManagementServerImpl.java | 23 +++++++-------- .../java/com/cloud/vm/UserVmManagerImpl.java | 29 +++++++++---------- .../com/cloud/vm/UserVmManagerImplTest.java | 13 +++++++++ 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java index 98937cad0e36..9ae7ddfd2079 100644 --- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java +++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java @@ -4233,26 +4233,23 @@ private SSHKeyPair createAndSaveSSHKeyPair(final String name, final String finge } @Override - public String getVMPassword(final GetVMPasswordCmd cmd) { - final Account caller = getCaller(); + public String getVMPassword(GetVMPasswordCmd cmd) { + Account caller = getCaller(); + long vmId = cmd.getId(); + UserVmVO vm = _userVmDao.findById(vmId); - final UserVmVO vm = _userVmDao.findById(cmd.getId()); if (vm == null) { - final InvalidParameterValueException ex = new InvalidParameterValueException("No VM with specified id found."); - ex.addProxyObject(cmd.getId().toString(), "vmId"); - throw ex; + throw new InvalidParameterValueException(String.format("No VM found with id [%s].", vmId)); } - // make permission check _accountMgr.checkAccess(caller, null, true, vm); _userVmDao.loadDetails(vm); - final String password = vm.getDetail("Encrypted.Password"); - if (password == null || password.equals("")) { - final InvalidParameterValueException ex = new InvalidParameterValueException( - "No password for VM with specified id found. " + "If VM is created from password enabled template and SSH keypair is assigned to VM then only password can be retrieved."); - ex.addProxyObject(vm.getUuid(), "vmId"); - throw ex; + String password = vm.getDetail("Encrypted.Password"); + + if (StringUtils.isEmpty(password)) { + throw new InvalidParameterValueException(String.format("No password found for VM with id [%s]. When the VM's SSH keypair is changed, the current encrypted password is " + + "removed due to incosistency in the encryptation, as the new SSH keypair is different from which the password was encrypted. To get a new password, it must be reseted.", vmId)); } return password; diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index fb32dc53d75a..c1743e74623d 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -862,22 +862,28 @@ public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableExce } _accountMgr.checkAccess(caller, null, true, userVm); - String password = null; + String sshPublicKey = s.getPublicKey(); - if (template != null && template.isEnablePassword()) { - password = _mgr.generateRandomPassword(); - } - boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey, password); + boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey); if (!result) { throw new CloudRuntimeException("Failed to reset SSH Key for the virtual machine "); } - userVm.setPassword(password); + + removeEncryptedPasswordFromUserVmVoDetails(userVm); + return userVm; } - private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String password) throws ResourceUnavailableException, InsufficientCapacityException { + protected void removeEncryptedPasswordFromUserVmVoDetails(UserVmVO userVmVo) { + Map details = userVmVo.getDetails(); + details.remove(VmDetailConstants.ENCRYPTED_PASSWORD); + userVmVo.setDetails(details); + _vmDao.saveDetails(userVmVo); + } + + private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey) throws ResourceUnavailableException, InsufficientCapacityException { Long userId = CallContext.current().getCallingUserId(); VMInstanceVO vmInstance = _vmDao.findById(vmId); @@ -894,10 +900,6 @@ private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String pas VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance); - if (template.isEnablePassword()) { - vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password); - } - UserDataServiceProvider element = _networkMgr.getSSHKeyResetProvider(defaultNetwork); if (element == null) { throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for SSH Key reset"); @@ -912,11 +914,6 @@ private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String pas final UserVmVO userVm = _vmDao.findById(vmId); _vmDao.loadDetails(userVm); userVm.setDetail(VmDetailConstants.SSH_PUBLIC_KEY, sshPublicKey); - if (template.isEnablePassword()) { - userVm.setPassword(password); - //update the encrypted password in vm_details table too - encryptAndStorePassword(userVm, password); - } _vmDao.saveDetails(userVm); if (vmInstance.getState() == State.Stopped) { diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java index da59f07a3a86..ae647f349df7 100644 --- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java +++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java @@ -558,4 +558,17 @@ private DiskOfferingVO prepareDiskOffering(long rootSize, long diskOfferingId, l Mockito.when(newRootDiskOffering.getName()).thenReturn("OfferingName"); return newRootDiskOffering; } + + @Test + public void validateRemoveEncryptedPasswordFromUserVmVoDetails(){ + Map detailsMock = Mockito.mock(HashMap.class); + + Mockito.doReturn(detailsMock).when(userVmVoMock).getDetails(); + Mockito.doNothing().when(userVmDao).saveDetails(userVmVoMock); + userVmManagerImpl.removeEncryptedPasswordFromUserVmVoDetails(userVmVoMock); + + Mockito.verify(detailsMock, Mockito.times(1)).remove(VmDetailConstants.ENCRYPTED_PASSWORD); + Mockito.verify(userVmVoMock, Mockito.times(1)).setDetails(detailsMock); + Mockito.verify(userVmDao, Mockito.times(1)).saveDetails(userVmVoMock); + } } From 85e4abf52231968233f39e62747541837d644189 Mon Sep 17 00:00:00 2001 From: davidjumani Date: Thu, 17 Jun 2021 12:55:31 +0530 Subject: [PATCH 012/120] ui: Show default nic/network in infocard (#5080) --- ui/src/components/view/InfoCard.vue | 6 ++++++ ui/src/views/compute/DeployVM.vue | 13 +++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ui/src/components/view/InfoCard.vue b/ui/src/components/view/InfoCard.vue index e25eb393983f..bfdac6a56947 100644 --- a/ui/src/components/view/InfoCard.vue +++ b/ui/src/components/view/InfoCard.vue @@ -281,6 +281,9 @@ style="margin-left: -24px; margin-top: 5px;"> eth{{ index }} {{ eth.ipaddress }} ({{ eth.networkname }}) + + {{ $t('label.default') }} + @@ -294,6 +297,9 @@ :key="network.id" style="margin-top: 5px;"> {{ network.name }} + + ({{ $t('label.default') }}) + diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index bccd9287e675..35bf5730b4a1 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -775,7 +775,7 @@ export default { 'sharedexecutable' ], initDataConfig: {}, - defaultNetwork: '', + defaultnetworkid: '', networkConfig: [], dataNetworkCreated: [], tabList: [ @@ -1065,6 +1065,7 @@ export default { if (this.networks) { this.vm.networks = this.networks + this.vm.defaultnetworkid = this.defaultnetworkid } if (this.template) { @@ -1147,6 +1148,7 @@ export default { this.form.getFieldDecorator('multidiskoffering', { initialValue: undefined, preserve: true }) this.form.getFieldDecorator('affinitygroupids', { initialValue: [], preserve: true }) this.form.getFieldDecorator('networkids', { initialValue: [], preserve: true }) + this.form.getFieldDecorator('defaultnetworkid', { initialValue: undefined, preserve: true }) this.form.getFieldDecorator('keypair', { initialValue: undefined, preserve: true }) this.form.getFieldDecorator('cpunumber', { initialValue: undefined, preserve: true }) this.form.getFieldDecorator('cpuSpeed', { initialValue: undefined, preserve: true }) @@ -1377,7 +1379,10 @@ export default { }) }, updateDefaultNetworks (id) { - this.defaultNetwork = id + this.defaultnetworkid = id + this.form.setFieldsValue({ + defaultnetworkid: id + }) }, updateNetworkConfig (networks) { this.networkConfig = networks @@ -1528,9 +1533,9 @@ export default { networkIds = values.networkids if (networkIds.length > 0) { for (let i = 0; i < networkIds.length; i++) { - if (networkIds[i] === this.defaultNetwork) { + if (networkIds[i] === this.defaultnetworkid) { const ipToNetwork = { - networkid: this.defaultNetwork + networkid: this.defaultnetworkid } arrNetwork.unshift(ipToNetwork) } else { From 2ececbf9942f966e9a637d758c66c073599de988 Mon Sep 17 00:00:00 2001 From: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> Date: Thu, 17 Jun 2021 04:51:30 -0300 Subject: [PATCH 013/120] kvm: Improve logs on agent start (#4958) This PR intends to improve logging on agent start to facilitate troubleshooting. Co-authored-by: Daniel Augusto Veronezi Salvador Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com> --- .../apache/cloudstack/utils/linux/KVMHostInfo.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java index 1f28304806a7..60e98f58e72c 100644 --- a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java @@ -42,6 +42,8 @@ public class KVMHostInfo { private long overCommitMemory; private List capabilities = new ArrayList<>(); + private static String cpuInfoMaxFreqFileName = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"; + public KVMHostInfo(long reservedMemory, long overCommitMemory) { this.reservedMemory = reservedMemory; this.overCommitMemory = overCommitMemory; @@ -78,11 +80,12 @@ public List getCapabilities() { } protected static long getCpuSpeed(final NodeInfo nodeInfo) { - try (final Reader reader = new FileReader( - "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq")) { - return Long.parseLong(IOUtils.toString(reader).trim()) / 1000; + try (Reader reader = new FileReader(cpuInfoMaxFreqFileName)) { + Long cpuInfoMaxFreq = Long.parseLong(IOUtils.toString(reader).trim()); + LOGGER.info(String.format("Retrieved value [%s] from file [%s]. This corresponds to a CPU speed of [%s] MHz.", cpuInfoMaxFreq, cpuInfoMaxFreqFileName, cpuInfoMaxFreq / 1000)); + return cpuInfoMaxFreq / 1000; } catch (IOException | NumberFormatException e) { - LOGGER.info("Could not read cpuinfo_max_freq, falling back on libvirt"); + LOGGER.error(String.format("Unable to retrieve the CPU speed from file [%s]. Using the value [%s] provided by the Libvirt.", cpuInfoMaxFreqFileName, nodeInfo.mhz), e); return nodeInfo.mhz; } } From 8e33cf715948e4d17e323ac8e83fd22c6195ed7b Mon Sep 17 00:00:00 2001 From: slavkap <51903378+slavkap@users.noreply.github.com> Date: Fri, 18 Jun 2021 04:21:49 +0300 Subject: [PATCH 014/120] kvm: fix of detach volume while OS is in boot state (#4572) * fix of detach volume while OS is in boot state * check that the VM could be accessed trough ssh --- .../hypervisor/kvm/storage/KVMStorageProcessor.java | 9 +++++++++ test/integration/smoke/test_volumes.py | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 34c610dd9a14..2ad3089cf371 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -70,6 +70,7 @@ import org.apache.cloudstack.utils.qemu.QemuImgFile; import org.apache.commons.collections.MapUtils; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.libvirt.Connect; import org.libvirt.Domain; @@ -1195,6 +1196,14 @@ protected synchronized String attachOrDetachDevice(final Connect conn, final boo } else { s_logger.debug("Detaching device: " + xml); dm.detachDevice(xml); + LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + parser.parseDomainXML(dm.getXMLDesc(0)); + List disks = parser.getDisks(); + for (DiskDef diskDef : disks) { + if (StringUtils.contains(xml, diskDef.getDiskPath())) { + throw new InternalErrorException("Could not detach volume. Probably the VM is in boot state at the moment"); + } + } } } catch (final LibvirtException e) { if (attach) { diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index 107403e2df3d..fa7bea0b9c12 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -385,11 +385,15 @@ def setUp(self): def tearDown(self): #Clean up, terminate the created volumes if self.attached: + self.virtual_machine.get_ssh_client(reconnect = True) + self.virtual_machine.detach_volume(self.apiClient, self.volume) if self.virtual_machine.hypervisor == "KVM": self.virtual_machine.stop(self.apiClient) self.virtual_machine.start(self.apiClient) + self.virtual_machine.get_ssh_client(reconnect = True) + cleanup_resources(self.apiClient, self.cleanup) return From 3a51540c24932d573564c56124231e3d527e2909 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Fri, 18 Jun 2021 19:27:22 +0530 Subject: [PATCH 015/120] ui: Notify vm password on reinstall of VM (for password enabled templates) (#5129) * ui: Notify vm password on reinstall of VM (for password enabled templates) * refactor --- ui/src/config/section/compute.js | 12 ++++++++++++ ui/src/views/AutogenView.vue | 3 +++ 2 files changed, 15 insertions(+) diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index 312c0903e392..48e9a10742bd 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -144,6 +144,18 @@ export default { virtualmachineid: { value: (record) => { return record.id } } + }, + successMethod: (obj, result) => { + console.log('here') + const vm = result.jobresult.virtualmachine || {} + if (result.jobstatus === 1 && vm.password) { + const name = vm.displayname || vm.name || vm.id + obj.$notification.success({ + message: `${obj.$t('label.reinstall.vm')}: ` + name, + description: `${obj.$t('label.password.reset.confirm')}: ` + vm.password, + duration: 0 + }) + } } }, { diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index c51487c3b7a5..ebeca6e4ab0c 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -871,6 +871,9 @@ export default { }) } } + if ('successMethod' in action) { + action.successMethod(this, result) + } }, errorMethod: () => this.fetchData(), loadingMessage: `${this.$t(action.label)} - ${resourceName}`, From 4f6851f4c057a9524231e75285ba2f5257ff640b Mon Sep 17 00:00:00 2001 From: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com> Date: Fri, 18 Jun 2021 20:40:11 +0530 Subject: [PATCH 016/120] Some missed inclusivity changes - use inclusive words/terms as appropriate. (#5131) --- .../api/command/user/network/MoveNetworkAclItemCmd.java | 2 +- test/integration/component/test_acl_isolatednetwork.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/MoveNetworkAclItemCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/MoveNetworkAclItemCmd.java index 0343e5012e4a..acc7fdff90f2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/network/MoveNetworkAclItemCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/MoveNetworkAclItemCmd.java @@ -43,7 +43,7 @@ public class MoveNetworkAclItemCmd extends BaseAsyncCustomIdCmd { @Parameter(name = ApiConstants.NEXT_ACL_RULE_ID, type = CommandType.STRING, description = "The ID of the rule that is right after the new position where the rule being moved is going to be placed. This value can be 'NULL' if the rule is being moved to the last position of the network ACL list.") private String nextAclRuleUuid; - @Parameter(name = ApiConstants.MOVE_ACL_CONSISTENCY_HASH, type = CommandType.STRING, description = "Md5 hash used to check the consistency of the ACL rule list before applying the ACL rule move. This check is useful to manage concurrency problems that may happen when multiple users are editing the same ACL rule listing. The parameter is not required. Therefore, if the user does not send it, he/she is assuming the risk of moving ACL rules without checking the consistency of the access control list before executing the move. We use MD5 hash function on a String that is composed of all UUIDs of the ACL rules in concatenated in their respective order (order defined via 'number' field).") + @Parameter(name = ApiConstants.MOVE_ACL_CONSISTENCY_HASH, type = CommandType.STRING, description = "Md5 hash used to check the consistency of the ACL rule list before applying the ACL rule move. This check is useful to manage concurrency problems that may happen when multiple users are editing the same ACL rule listing. The parameter is not required. Therefore, if the user does not send it, they assume the risk of moving ACL rules without checking the consistency of the access control list before executing the move. We use MD5 hash function on a String that is composed of all UUIDs of the ACL rules in concatenated in their respective order (order defined via 'number' field).") private String aclConsistencyHash; @Override diff --git a/test/integration/component/test_acl_isolatednetwork.py b/test/integration/component/test_acl_isolatednetwork.py index a1deb93b2623..2347b27a2ea9 100644 --- a/test/integration/component/test_acl_isolatednetwork.py +++ b/test/integration/component/test_acl_isolatednetwork.py @@ -926,7 +926,7 @@ def test_20_1_deployvm_user_incrossnetwork(self): self.cleanup.append(vm) self.fail("User is allowed to deploy VM in a network that is not self-owned ") except Exception as e: - self.debug("When user tries to deploy vm in a network that does not belong to him %s" % e) + self.debug("When user tries to deploy vm in a network that does not belong to the user %s" % e) if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.UNABLE_TO_USE_NETWORK): self.fail("Error message validation failed when User is allowed to deploy VM in a network that is not self-owned ") From fb6cb0acb6c96d6ce2da46c742e0af4bdb03e59f Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 23 Jun 2021 02:21:01 -0400 Subject: [PATCH 017/120] prepare the template impl --- .../api/command/user/vm/CloneVMCmd.java | 42 ++++++- .../cloud/template/TemplateManagerImpl.java | 114 ++++++++++++++++++ .../java/com/cloud/vm/UserVmManagerImpl.java | 1 + 3 files changed, 151 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index a740c6031baf..0bc6163e5756 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -7,10 +7,17 @@ import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.api.*; +import org.apache.cloudstack.api.ACL; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiCommandJobType; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCreateCustomIdCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ResponseObject; +import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.command.user.UserCmd; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.context.CallContext; @@ -32,6 +39,26 @@ public class CloneVMCmd extends BaseAsyncCreateCustomIdCmd implements UserCmd { required = true, description = "The ID of the virtual machine") private Long id; + public Long getVolumeId() { + return volumeId; + } + + public void setVolumeId(Long volumeId) { + this.volumeId = volumeId; + } + + private Long volumeId; + + private VirtualMachineTemplate createdTemplate; + + public void setCreatedTemplate(VirtualMachineTemplate template) { + this.createdTemplate = template; + } + + public VirtualMachineTemplate getCreatedTemplate() { + return this.createdTemplate; + } + public Long getId() { return this.id; } @@ -55,14 +82,17 @@ public void create() throws ResourceAllocationException { VirtualMachineTemplate template = null; try { _userVmService.checkCloneCondition(this); + template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId())); + setCreatedTemplate(template); +// _userVmService.createBasicSecurityGroupVirtualMachine(); // disabled since it crashes } catch (ResourceUnavailableException e) { s_logger.warn("Exception: ", e); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, e.getMessage()); } - template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId())); - if (template == null) { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to generate a template during clone!"); - } + } + + public boolean isPublic() { + return false; } public String getVMName() { diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 698e23119d2a..e972748ff5b8 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1790,8 +1790,122 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template boolean isAdmin = (_accountMgr.isAdmin(caller.getId())); _accountMgr.checkAccess(caller, null, true, templateOwner); String name = cmd.getTemplateName(); + if (name.length() > 32) { + name = name.substring(5) + "-QA"; + } + + int bits = 64; // where to specify + boolean requireHVM = true, sshKeyEnabled = true, featured = false; + boolean isPublic = cmd.isPublic(); + Long volumeId = cmd.getVolumeId(); + HypervisorType hyperType = null; + VolumeVO volume = _volumeDao.findById(volumeId); + if (volume == null) { + throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId); + } + // check permissions + _accountMgr.checkAccess(caller, null, true, volume); + + // If private template is created from Volume, check that the volume + // will not be active when the private template is + // created + if (!_volumeMgr.volumeInactive(volume)) { + String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM, please stop the VM first"; + if (s_logger.isInfoEnabled()) { + s_logger.info(msg); + } + throw new CloudRuntimeException(msg); + } + + hyperType = _volumeDao.getHypervisorType(volumeId); + if (HypervisorType.LXC.equals(hyperType)) { + throw new InvalidParameterValueException("Template creation is not supported for LXC volume: " + volumeId); + } + + _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template); + _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.secondary_storage, volume.getSize()); + + Long guestOSId = cmd.getTargetVM().getGuestOSId(); + GuestOSVO guestOS = _guestOSDao.findById(guestOSId); + if (guestOS == null) { + throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist."); + } + + Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id"); + String description = ""; // TODO: add this to clone parameter in the future + boolean isExtractable = false; + Long sourceTemplateId = null; + if (volume != null) { + VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId()); + isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; + if (volume.getIsoId() != null && volume.getIsoId() != 0) { + sourceTemplateId = volume.getIsoId(); + } else if (volume.getTemplateId() != null) { + sourceTemplateId = volume.getTemplateId(); + } + } + + VMTemplateVO privateTemplate = null; + privateTemplate = new VMTemplateVO(nextTemplateId, name, ImageFormat.RAW, isPublic, featured, isExtractable, + TemplateType.USER, null, true, 64, templateOwner.getId(), null, description, + true, guestOS.getId(), true, hyperType, null, new HashMap<>(){{put("template to be cleared", "yes");}}, false, false, false, false); + List stores = _imgStoreDao.findRegionImageStores(); + if (!CollectionUtils.isEmpty(stores)) { + privateTemplate.setCrossZones(true); + } + + privateTemplate.setSourceTemplateId(sourceTemplateId); + + VMTemplateVO template = _tmpltDao.persist(privateTemplate); + // Increment the number of templates + if (template != null) { + Map details = new HashMap(); + + if (sourceTemplateId != null) { + VMTemplateVO sourceTemplate = _tmpltDao.findById(sourceTemplateId); + if (sourceTemplate != null && sourceTemplate.getDetails() != null) { + details.putAll(sourceTemplate.getDetails()); + } + } + + if (volume != null) { + Long vmId = volume.getInstanceId(); + if (vmId != null) { + UserVmVO userVm = _userVmDao.findById(vmId); + if (userVm != null) { + _userVmDao.loadDetails(userVm); + Map vmDetails = userVm.getDetails(); + vmDetails = vmDetails.entrySet() + .stream() + .filter(map -> map.getValue() != null) + .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue())); + details.putAll(vmDetails); + } + } + } + + if (!details.isEmpty()) { + privateTemplate.setDetails(details); + _tmpltDao.saveDetails(privateTemplate); + } + + _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template); + _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage, + volume.getSize()); + } + + if (template != null) { + return template; + } else { + throw new CloudRuntimeException("Failed to create a template"); + } + } + + @Override + public VirtualMachineTemplate createPrivateTemplateRecord(CloneVMCmd cmd) throws CloudRuntimeException { return null; } + @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", create = true) public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 4fb7b83f93ad..60607b99a845 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4515,6 +4515,7 @@ public void checkCloneCondition(CloneVMCmd cmd) throws ResourceUnavailableExcept if (CollectionUtils.isEmpty(volumeInformation)) { throw new CloudRuntimeException("The VM to copy does not have a Volume attached!"); } + cmd.setVolumeId(volumeInformation.get(0).getId()); } @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CLONE, eventDescription = "clone vm", async = true) From 77c39c21bf5bcaa0888f411eba8e4002088e338c Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 23 Jun 2021 02:23:28 -0400 Subject: [PATCH 018/120] clear the dot record for later test --- api/src/main/java/com/cloud/template/TemplateApiService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/main/java/com/cloud/template/TemplateApiService.java b/api/src/main/java/com/cloud/template/TemplateApiService.java index bcda2bc2f2dc..f0e6f0b264a4 100644 --- a/api/src/main/java/com/cloud/template/TemplateApiService.java +++ b/api/src/main/java/com/cloud/template/TemplateApiService.java @@ -20,7 +20,6 @@ import java.net.URISyntaxException; import java.util.List; -import com.cloud.exception.ResourceUnavailableException; import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; From 53c2e19d5f010feed2d161f1275568b1d66f7746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Beims=20Br=C3=A4scher?= Date: Thu, 24 Jun 2021 02:33:46 -0300 Subject: [PATCH 019/120] ui: Fix UI issue when deploying VM with rootdisksize (GB now, not in bytes) (#5150) --- ui/src/views/compute/DeployVM.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index c0965bfd593e..16abfa80aa3a 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -1966,7 +1966,7 @@ export default { } } if (offering && offering.rootdisksize > 0) { - this.rootDiskSizeFixed = offering.rootdisksize / (1024 * 1024 * 1024.0).toFixed(2) + this.rootDiskSizeFixed = offering.rootdisksize this.showRootDiskSizeChanger = false } } From 347f8a5a73ab469c5a630e6dc736a0392dc1c37a Mon Sep 17 00:00:00 2001 From: Wei Zhou <57355700+weizhouapache@users.noreply.github.com> Date: Thu, 24 Jun 2021 07:35:24 +0200 Subject: [PATCH 020/120] VR: fix source cidr of egress rules are not applied (#5143) This reverts change in commit https://github.com/apache/cloudstack/commit/065fa1c849dd09dd734778913bc50c844aa0aee3#diff-c78f7f699938cf529cbcef26bda2ed93630b58f336986fd0753fbfa1a6adbc43L103-R103 --- systemvm/debian/opt/cloud/bin/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/systemvm/debian/opt/cloud/bin/configure.py b/systemvm/debian/opt/cloud/bin/configure.py index 8fdf134b506c..cafd739d7cab 100755 --- a/systemvm/debian/opt/cloud/bin/configure.py +++ b/systemvm/debian/opt/cloud/bin/configure.py @@ -111,7 +111,7 @@ def __init__(self, obj, fw): self.rule['allowed'] = True self.rule['action'] = "ACCEPT" - if self.rule['type'] == 'all' and obj['source_cidr_list']: + if self.rule['type'] == 'all' and not obj['source_cidr_list']: self.rule['cidr'] = [] else: self.rule['cidr'] = obj['source_cidr_list'] From 0eeb094949e70c242daebe2917f24f811cf007c7 Mon Sep 17 00:00:00 2001 From: Hoang Nguyen Date: Thu, 24 Jun 2021 12:36:05 +0700 Subject: [PATCH 021/120] ui: watch the systemVM for enabling quickview when newly resource (#5137) --- ui/src/components/view/QuickView.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/components/view/QuickView.vue b/ui/src/components/view/QuickView.vue index 05ffe3d408a2..d17ca9f5107f 100644 --- a/ui/src/components/view/QuickView.vue +++ b/ui/src/components/view/QuickView.vue @@ -58,7 +58,7 @@ export default { } }, watch: { - actions (item) { + resource () { this.actionsExist = this.doActionsExist() } }, From faa57434abfe81103387078494fc56d6ef6c479c Mon Sep 17 00:00:00 2001 From: Rakesh Date: Thu, 24 Jun 2021 07:37:06 +0200 Subject: [PATCH 022/120] systemvm: Change logrotate interval to hourly (#5132) * Change logrotate interval to hourly The logrotate config says interval as hourly but it relies on timer service to be invoked but in timer the frequency is mentioned as 12h. So it wont be invoked every hour. So change the frequency to hourly * Add change to vpc router --- systemvm/debian/opt/cloud/bin/setup/router.sh | 7 +++++++ systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/systemvm/debian/opt/cloud/bin/setup/router.sh b/systemvm/debian/opt/cloud/bin/setup/router.sh index 7c9549354e11..e8f6edf0ceb5 100755 --- a/systemvm/debian/opt/cloud/bin/setup/router.sh +++ b/systemvm/debian/opt/cloud/bin/setup/router.sh @@ -100,6 +100,13 @@ setup_router() { mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1 fi + # Setup hourly lograte in systemd timer + sed -i 's/OnCalendar=daily/OnCalendar=hourly/g' /usr/lib/systemd/system/logrotate.timer + sed -i 's/AccuracySec=12h/AccuracySec=5m/g' /usr/lib/systemd/system/logrotate.timer + + # reload daemon + /usr/bin/systemctl daemon-reload + # Load modules to support NAT traversal in VR modprobe nf_nat_pptp } diff --git a/systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh b/systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh index 68877821fb32..f97fb161f47f 100755 --- a/systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh +++ b/systemvm/debian/opt/cloud/bin/setup/vpcrouter.sh @@ -113,6 +113,13 @@ EOF mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1 fi + # Setup hourly lograte in systemd timer + sed -i 's/OnCalendar=daily/OnCalendar=hourly/g' /usr/lib/systemd/system/logrotate.timer + sed -i 's/AccuracySec=12h/AccuracySec=5m/g' /usr/lib/systemd/system/logrotate.timer + + # reload daemon + /usr/bin/systemctl daemon-reload + # Load modules to support NAT traversal in VR modprobe nf_nat_pptp } From b9712c65ca319022ea8decec9b0bc945a720ba24 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 24 Jun 2021 11:07:58 +0530 Subject: [PATCH 023/120] ui: fix missing component in SearchView (#5123) TooltipButton was not added as Vue component. It was leading to error in page load. Signed-off-by: Abhishek Kumar --- ui/src/components/view/SearchView.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index 100acf0d47bd..cbc93446bd7f 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -76,7 +76,7 @@ - + @@ -112,9 +112,13 @@ @@ -226,8 +187,8 @@ under the License. template_path - - + + removetemplate.sh @@ -247,8 +208,8 @@ under the License. - - + + ms.sh @@ -264,7 +225,7 @@ under the License. - + ms.sh @@ -280,8 +241,8 @@ under the License. - - + + sleep.sh @@ -292,29 +253,9 @@ under the License. 240 - - - - select download_state from template_host_ref - true - Checking download state of the template in the DB after the template was deleted on secondary storage and management server process was restarted - - - template_id - privatetemplateid - - - - - download_state - DOWNLOAD_ERROR - - - - - - + + createTemplate Create template @@ -351,45 +292,7 @@ under the License. - - - select download_state from template_host_ref - true - Getting volume path for the vm DATADISK volume - - - template_id - privatetemplateid - - - - - download_state - DOWNLOADED - - - - - - - select install_path from template_host_ref - true - Getting install_path from the template - - - template_id - privatetemplateid - - - - - install_path - template_path - - - - - + listtemplate.sh @@ -408,8 +311,8 @@ under the License. template_path - - + + corrupttemplate.sh @@ -433,8 +336,8 @@ under the License. - - + + ms.sh @@ -450,7 +353,7 @@ under the License. - + ms.sh @@ -466,8 +369,8 @@ under the License. - - + + sleep.sh @@ -478,26 +381,8 @@ under the License. 240 - - - - select download_state from template_host_ref - true - Checking download state of the template in the DB after the template was deleted on secondary storage and management server process was restarted - - - template_id - privatetemplateid - - - - - download_state - DOWNLOAD_ERROR - - - - + + listtemplate.sh @@ -517,9 +402,9 @@ under the License. template_path - - - + + + createTemplate @@ -557,45 +442,7 @@ under the License. - - - select download_state from template_host_ref - true - Getting volume path for the vm DATADISK volume - - - template_id - privatetemplateid - - - - - download_state - DOWNLOADED - - - - - - - select install_path from template_host_ref - true - Getting install_path from the template - - - template_id - privatetemplateid - - - - - install_path - template_path - - - - - + listtemplate.sh @@ -614,8 +461,8 @@ under the License. template_path - - + + createfaketemplate.sh @@ -643,8 +490,8 @@ under the License. - - + + ms.sh @@ -660,7 +507,7 @@ under the License. - + ms.sh @@ -676,8 +523,8 @@ under the License. - - + + sleep.sh @@ -688,8 +535,8 @@ under the License. 240 - - + + listtemplate.sh @@ -709,10 +556,10 @@ under the License. /template/tmpl/1/300556/template.properties - + - - + + createTemplate Create template @@ -749,45 +596,7 @@ under the License. - - - select download_state from template_host_ref - true - Getting volume path for the vm DATADISK volume - - - template_id - privatetemplateid - - - - - download_state - DOWNLOADED - - - - - - - select install_path from template_host_ref - true - Getting install_path from the template - - - template_id - privatetemplateid - - - - - install_path - template_path - - - - - + listtemplate.sh @@ -806,8 +615,8 @@ under the License. template_path - - + + removetemplate.sh @@ -827,8 +636,8 @@ under the License. - - + + ms.sh @@ -844,7 +653,7 @@ under the License. - + ms.sh @@ -860,8 +669,8 @@ under the License. - - + + ms.sh @@ -877,7 +686,7 @@ under the License. - + ms.sh @@ -893,7 +702,7 @@ under the License. - + sleep.sh @@ -904,29 +713,9 @@ under the License. 240 - - - - select download_state from template_host_ref - true - Checking download state of the template in the DB after the template was deleted on secondary storage and management server process was restarted - - - template_id - privatetemplateid - - - - - download_state - DOWNLOAD_ERROR - - - - - - + + createTemplate Create template @@ -963,45 +752,7 @@ under the License. - - - select download_state from template_host_ref - true - Getting volume path for the vm DATADISK volume - - - template_id - privatetemplateid - - - - - download_state - DOWNLOADED - - - - - - - select install_path from template_host_ref - true - Getting install_path from the template - - - template_id - privatetemplateid - - - - - install_path - template_path - - - - - + listtemplate.sh @@ -1020,8 +771,8 @@ under the License. template_path - - + + ms.sh @@ -1037,7 +788,7 @@ under the License. - + ms.sh @@ -1053,8 +804,8 @@ under the License. - - + + sleep.sh @@ -1065,27 +816,8 @@ under the License. 240 - - - - select download_state from template_host_ref - true - Checking download state of the template in the DB after the template was deleted on secondary storage and management server process was restarted - - - template_id - privatetemplateid - - - - - download_state - DOWNLOADED - - - - + deployVirtualMachine Deploy vm from private template after management server was rebooted @@ -1101,7 +833,7 @@ under the License. diskofferingid globaldiskofferingid - + templateid privatetemplateid @@ -1125,7 +857,7 @@ under the License. networkids globalnetworkid - + @@ -1134,8 +866,8 @@ under the License. - - + + registerTemplate @@ -1180,8 +912,8 @@ under the License. privatetemplateid - - + + sleep.sh @@ -1192,47 +924,8 @@ under the License. 300 - - - - - select download_state from template_host_ref - true - Getting volume path for the vm DATADISK volume - - - template_id - privatetemplateid - - - - - download_state - DOWNLOADED - - - - - - select install_path from template_host_ref - true - Getting install_path from the template - - - template_id - privatetemplateid - - - - - install_path - template_path - - - - - + listtemplate.sh @@ -1251,8 +944,8 @@ under the License. template_path - - + + removetemplate.sh @@ -1272,8 +965,8 @@ under the License. - - + + ms.sh @@ -1289,7 +982,7 @@ under the License. - + ms.sh @@ -1305,8 +998,8 @@ under the License. - - + + ms.sh @@ -1322,7 +1015,7 @@ under the License. - + ms.sh @@ -1338,7 +1031,7 @@ under the License. - + sleep.sh @@ -1349,26 +1042,7 @@ under the License. 15 - - - - select download_state from template_host_ref - true - Checking download state of the template in the DB after the template was deleted on secondary storage and management server process was restarted - - - template_id - privatetemplateid - - - - - download_state - DOWNLOAD_IN_PROGRESS - - - From d82909318f64b6bcc2dec83174c2e6475071ba98 Mon Sep 17 00:00:00 2001 From: slavkap <51903378+slavkap@users.noreply.github.com> Date: Fri, 25 Jun 2021 09:34:36 +0300 Subject: [PATCH 028/120] server: Fix of delete of Ceph's snapshots from secondary storage (#5130) This PR fixes the deletion will be handled by DefaultSnapshotStrategy::deleteSnapshot #4797 --- .../cloudstack/storage/snapshot/CephSnapshotStrategy.java | 4 ---- .../cloudstack/storage/snapshot/CephSnapshotStrategyTest.java | 2 -- 2 files changed, 6 deletions(-) diff --git a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/CephSnapshotStrategy.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/CephSnapshotStrategy.java index 87f9e100be7e..039cd82595d1 100644 --- a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/CephSnapshotStrategy.java +++ b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/CephSnapshotStrategy.java @@ -64,10 +64,6 @@ public StrategyPriority canHandle(Snapshot snapshot, SnapshotOperation op) { return StrategyPriority.HIGHEST; } - if (SnapshotOperation.DELETE.equals(op)) { - return StrategyPriority.HIGHEST; - } - return StrategyPriority.CANT_HANDLE; } diff --git a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/CephSnapshotStrategyTest.java b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/CephSnapshotStrategyTest.java index 260a21d87a01..dcc6acf983fe 100644 --- a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/CephSnapshotStrategyTest.java +++ b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/CephSnapshotStrategyTest.java @@ -87,8 +87,6 @@ private void configureAndVerifyCanHandle(Date removed, boolean isSnapshotStoredO StrategyPriority strategyPriority = cephSnapshotStrategy.canHandle(snapshot, snapshotOps[i]); if (snapshotOps[i] == SnapshotOperation.REVERT && isSnapshotStoredOnRbdStoragePool) { Assert.assertEquals(StrategyPriority.HIGHEST, strategyPriority); - } else if (snapshotOps[i] == SnapshotOperation.DELETE && isSnapshotStoredOnRbdStoragePool) { - Assert.assertEquals(StrategyPriority.HIGHEST, strategyPriority); } else { Assert.assertEquals(StrategyPriority.CANT_HANDLE, strategyPriority); } From 5edcf33ff0c7c7322434f3e6d28eedf0fdcc0a9d Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Fri, 25 Jun 2021 12:33:54 +0530 Subject: [PATCH 029/120] vxlan: Fix failure to delete vxlan (#5079) --- .../com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java index 37a8c762e0eb..741aa72172eb 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java @@ -376,7 +376,9 @@ private void deleteVnetBr(String brName, boolean deleteBr) { command.add("-v", vNetId); command.add("-p", pName); command.add("-b", brName); - command.add("-d", String.valueOf(deleteBr)); + if (cmdout != null && !cmdout.contains("vxlan")) { + command.add("-d", String.valueOf(deleteBr)); + } final String result = command.execute(); if (result != null) { From 1971a39f4bdb9ac2d09cfd3334dbaf28a7c6a51b Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 25 Jun 2021 11:49:00 -0400 Subject: [PATCH 030/120] checks for VM are implemented --- .../main/java/com/cloud/vm/UserVmService.java | 5 +- .../api/command/user/vm/CloneVMCmd.java | 49 ++++++----- .../cloud/template/TemplateManagerImpl.java | 2 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 83 +++++++++++++++---- 4 files changed, 101 insertions(+), 38 deletions(-) diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index 02b67c8e7695..a7fe2824763c 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -96,7 +96,7 @@ public interface UserVmService { * */ Optional cloneVirtualMachine(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException; - void checkCloneCondition(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException; + void checkCloneCondition(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ResourceAllocationException; /** * Resets the password of a virtual machine. @@ -442,6 +442,9 @@ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffe UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException; + UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, + StorageUnavailableException, ResourceAllocationException; + UserVm getUserVm(long vmId); /** diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 0bc6163e5756..b834c95dc55f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -1,9 +1,7 @@ package org.apache.cloudstack.api.command.user.vm; import com.cloud.event.EventTypes; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.*; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; @@ -19,6 +17,7 @@ import org.apache.cloudstack.api.ResponseObject; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.command.user.UserCmd; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; @@ -39,24 +38,19 @@ public class CloneVMCmd extends BaseAsyncCreateCustomIdCmd implements UserCmd { required = true, description = "The ID of the virtual machine") private Long id; - public Long getVolumeId() { - return volumeId; - } - - public void setVolumeId(Long volumeId) { - this.volumeId = volumeId; - } + //Owner information + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the virtual machine. Must be used with domainId.") + private String accountName; - private Long volumeId; + @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.") + private Long domainId; - private VirtualMachineTemplate createdTemplate; - - public void setCreatedTemplate(VirtualMachineTemplate template) { - this.createdTemplate = template; + public String getAccountName() { + return accountName; } - public VirtualMachineTemplate getCreatedTemplate() { - return this.createdTemplate; + public Long getDomainId() { + return domainId; } public Long getId() { @@ -79,15 +73,21 @@ public String getEventDescription() { @Override public void create() throws ResourceAllocationException { - VirtualMachineTemplate template = null; try { _userVmService.checkCloneCondition(this); - template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId())); - setCreatedTemplate(template); + UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); + if (vmRecord == null) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "unable to record a new VM to db!"); + } + setEntityId(vmRecord.getId()); + setEntityUuid(vmRecord.getUuid()); // _userVmService.createBasicSecurityGroupVirtualMachine(); // disabled since it crashes - } catch (ResourceUnavailableException e) { + } catch (ResourceUnavailableException | InsufficientCapacityException e) { s_logger.warn("Exception: ", e); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, e.getMessage()); + } catch (InvalidParameterValueException e) { + s_logger.warn("Exception: ", e); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); } } @@ -107,7 +107,8 @@ public String getTemplateName() { public void execute() { Optional result; try { - CallContext.current().setEventDetails("Vm Id for full clone: " + getId()); +// CallContext.current().setEventDetails("Vm Id for full clone: " + getId()); +// VirtualMachineTemplate template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId())); result = _userVmService.cloneVirtualMachine(this); } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); @@ -116,6 +117,10 @@ public void execute() { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); } +// catch (ResourceAllocationException ex) { +// s_logger.warn("Exception: ", ex); +// throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage()); +// } result.ifPresentOrElse((userVm)-> { UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), "virtualmachine", userVm).get(0); response.setResponseName("test_clone"); diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index e972748ff5b8..fc91584b2d44 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1797,7 +1797,7 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template int bits = 64; // where to specify boolean requireHVM = true, sshKeyEnabled = true, featured = false; boolean isPublic = cmd.isPublic(); - Long volumeId = cmd.getVolumeId(); + Long volumeId = _volumeDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT).get(0).getId(); HypervisorType hyperType = null; VolumeVO volume = _volumeDao.findById(volumeId); if (volume == null) { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 60607b99a845..f6973b940dfa 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -51,6 +51,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import com.cloud.user.*; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; @@ -292,16 +293,6 @@ import com.cloud.template.TemplateApiService; import com.cloud.template.TemplateManager; import com.cloud.template.VirtualMachineTemplate; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.AccountService; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.SSHKeyPair; -import com.cloud.user.SSHKeyPairVO; -import com.cloud.user.User; -import com.cloud.user.UserStatisticsVO; -import com.cloud.user.UserVO; -import com.cloud.user.VmDiskStatisticsVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.SSHKeyPairDao; import com.cloud.user.dao.UserDao; @@ -4502,7 +4493,17 @@ protected String validateUserData(String userData, HTTPMethod httpmethod) { } @Override - public void checkCloneCondition(CloneVMCmd cmd) throws ResourceUnavailableException, CloudRuntimeException, ConcurrentOperationException { + public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueException, ResourceUnavailableException, CloudRuntimeException, ResourceAllocationException { + final DomainVO domain = _domainDao.findById(cmd.getDomainId()); + final Account account = _accountService.getActiveAccountByName(cmd.getAccountName(), cmd.getDomainId()); + if (domain != null && account != null) { + if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + throw new InvalidParameterValueException("Invalid user type: project to clone the VM"); + } + if (account.getState() != Account.State.enabled) { + throw new InvalidParameterValueException("User is not enabled to clone this VM"); + } + } UserVm curVm = cmd.getTargetVM(); if (curVm == null) { throw new CloudRuntimeException("the VM doesn't exist or not registered in management server!"); @@ -4511,11 +4512,59 @@ public void checkCloneCondition(CloneVMCmd cmd) throws ResourceUnavailableExcept if (vmStatus.state != State.Shutdown) { throw new CloudRuntimeException("You should clone an instance that's shutdown!"); } - List volumeInformation = _volsDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); - if (CollectionUtils.isEmpty(volumeInformation)) { + List volumes = _volsDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); + if (CollectionUtils.isEmpty(volumes)) { throw new CloudRuntimeException("The VM to copy does not have a Volume attached!"); } - cmd.setVolumeId(volumeInformation.get(0).getId()); + // verify that the VM doesn't expire + Map details = curVm.getDetails(); + verifyDetails(details); +// Account activeOwner = _accountDao.findById(cmd.getEntityOwnerId()); + long zoneId = curVm.getDataCenterId(); + DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId); + if (zone == null) { + throw new InvalidParameterValueException("Unable to find a zone in the current VM by zone id=" + zoneId); + } + // service offering check + long serviceOfferingId = curVm.getServiceOfferingId(); + ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId); + if (serviceOffering == null) { + throw new InvalidParameterValueException("Service offering Id for this VM: " + serviceOfferingId + " doesn't exist now"); + } + if (!serviceOffering.isDynamic()) { + for(String detail: details.keySet()) { + if(detail.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) || detail.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) || detail.equalsIgnoreCase(VmDetailConstants.MEMORY)) { + throw new InvalidParameterValueException("cpuNumber or cpuSpeed or memory should not be specified for static service offering"); + } + } + } + // disk offering check + VolumeVO rootDisk = volumes.get(0); + Long diskOfferingID = rootDisk.getDiskOfferingId(); + DiskOfferingVO diskOffering =null; + if (diskOfferingID != null) { + diskOffering = _diskOfferingDao.findById(diskOfferingID); + if (diskOffering == null) { + throw new CloudRuntimeException("Unable to find disk offering " + diskOfferingID); + } + } + if (!zone.isLocalStorageEnabled()) { + if (serviceOffering.isUseLocalStorage()) { + throw new CloudRuntimeException("Zone is not configured to use local storage now but this service offering " + serviceOffering.getName() + " uses it"); + } + if (diskOffering != null && diskOffering.isUseLocalStorage()) { + throw new CloudRuntimeException("Zone is not configured to use local storage but disk offering " + diskOffering.getName() + " uses it"); + } + } + // resource limit checks & account check + AccountVO activeOwner = _accountDao.findById(cmd.getEntityOwnerId()); + List totalVolumes = _volsDao.findByInstance(cmd.getId()); + _resourceLimitMgr.checkResourceLimit(activeOwner, ResourceType.volume, totalVolumes.size()); + Long totalSize = 0L; + for (VolumeVO volumeToCheck : totalVolumes) { + totalSize += volumeToCheck.getSize(); + } + _resourceLimitMgr.checkResourceLimit(activeOwner, ResourceType.primary_storage, totalSize); } @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CLONE, eventDescription = "clone vm", async = true) @@ -5508,6 +5557,12 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE return vm; } + @Override + public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperationException { + //network configurations and check, then create the template + return null; + } + /** * Persist extra configuration data in the user_vm_details table as key/value pair * @param decodedUrl String consisting of the extra config data to appended onto the vmx file for VMware instances From 368711043ee79256466d61a17ee1066fca985764 Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 25 Jun 2021 11:52:02 -0400 Subject: [PATCH 031/120] fix checkstyle --- .../cloudstack/api/command/user/vm/CloneVMCmd.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index b834c95dc55f..83a95b46ba3e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -1,8 +1,11 @@ package org.apache.cloudstack.api.command.user.vm; import com.cloud.event.EventTypes; -import com.cloud.exception.*; -import com.cloud.template.VirtualMachineTemplate; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.vm.VirtualMachine; @@ -19,7 +22,7 @@ import org.apache.cloudstack.api.command.user.UserCmd; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.context.CallContext; +//import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import java.util.Optional; From fbb886cfb0af4fd87f58040635f8ae7c5dba636c Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 25 Jun 2021 11:53:58 -0400 Subject: [PATCH 032/120] compilation fixed --- .../main/java/com/cloud/vm/UserVmManagerImpl.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index f6973b940dfa..a5dbc3cc8a9e 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -51,7 +51,17 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import com.cloud.user.*; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.AccountService; +import com.cloud.user.AccountVO; +import com.cloud.user.ResourceLimitService; +import com.cloud.user.SSHKeyPair; +import com.cloud.user.SSHKeyPairVO; +import com.cloud.user.User; +import com.cloud.user.UserStatisticsVO; +import com.cloud.user.UserVO; +import com.cloud.user.VmDiskStatisticsVO; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; From 16d75daafe4f4a56af95328158314905efc6bf0d Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 25 Jun 2021 17:26:26 -0400 Subject: [PATCH 033/120] checkClone debug --- .../main/java/com/cloud/vm/UserVmManagerImpl.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index a5dbc3cc8a9e..e9281f9a416d 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4504,8 +4504,11 @@ protected String validateUserData(String userData, HTTPMethod httpmethod) { @Override public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueException, ResourceUnavailableException, CloudRuntimeException, ResourceAllocationException { - final DomainVO domain = _domainDao.findById(cmd.getDomainId()); - final Account account = _accountService.getActiveAccountByName(cmd.getAccountName(), cmd.getDomainId()); + if (cmd.getAccountName() != null && cmd.getDomainId() == null) { + throw new InvalidParameterValueException("You must input the domainId together with the account name"); + } + final DomainVO domain = cmd.getDomainId() == null ? null : _domainDao.findById(cmd.getDomainId()); + final Account account = cmd.getAccountName() == null ? null : _accountService.getActiveAccountByName(cmd.getAccountName(), cmd.getDomainId()); if (domain != null && account != null) { if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { throw new InvalidParameterValueException("Invalid user type: project to clone the VM"); @@ -5570,6 +5573,12 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE @Override public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperationException { //network configurations and check, then create the template + UserVm curVm = cmd.getTargetVM(); + // check if host is available + Long hostId = curVm.getHostId(); + getDestinationHost(hostId, true); + + return null; } From 779681cf2ab17880efa5340a8cf5c2e9224a6358 Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 25 Jun 2021 19:14:00 -0400 Subject: [PATCH 034/120] server state update --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index e9281f9a416d..3722e75faf5a 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4522,7 +4522,7 @@ public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueExce throw new CloudRuntimeException("the VM doesn't exist or not registered in management server!"); } UserVmVO vmStatus = _vmDao.findById(cmd.getId()); - if (vmStatus.state != State.Shutdown) { + if (vmStatus.state != State.Shutdown || vmStatus.state != State.Stopped) { throw new CloudRuntimeException("You should clone an instance that's shutdown!"); } List volumes = _volsDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); From 5a81d2b7e81e88acb0b783313b5e48ccec2a2744 Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 25 Jun 2021 19:20:26 -0400 Subject: [PATCH 035/120] add and statement --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 3722e75faf5a..354f849cab1e 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4522,7 +4522,7 @@ public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueExce throw new CloudRuntimeException("the VM doesn't exist or not registered in management server!"); } UserVmVO vmStatus = _vmDao.findById(cmd.getId()); - if (vmStatus.state != State.Shutdown || vmStatus.state != State.Stopped) { + if (vmStatus.state != State.Shutdown && vmStatus.state != State.Stopped) { throw new CloudRuntimeException("You should clone an instance that's shutdown!"); } List volumes = _volsDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); From 6f4fca9a9a5793a211be41190b1e87107d4b84d5 Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 25 Jun 2021 19:35:44 -0400 Subject: [PATCH 036/120] fix null error --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 354f849cab1e..6b0e739dfed1 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4544,7 +4544,7 @@ public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueExce if (serviceOffering == null) { throw new InvalidParameterValueException("Service offering Id for this VM: " + serviceOfferingId + " doesn't exist now"); } - if (!serviceOffering.isDynamic()) { + if (!serviceOffering.isDynamic() && details != null) { for(String detail: details.keySet()) { if(detail.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) || detail.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) || detail.equalsIgnoreCase(VmDetailConstants.MEMORY)) { throw new InvalidParameterValueException("cpuNumber or cpuSpeed or memory should not be specified for static service offering"); From aa809727a8ebcdd9178cc5594ab9fc4691cf5e38 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Sat, 26 Jun 2021 18:16:36 +0530 Subject: [PATCH 037/120] Fix configuration of ntp server list in systemVMs (#5160) --- .../secondarystorage/SecondaryStorageManagerImpl.java | 2 +- systemvm/debian/opt/cloud/bin/setup/common.sh | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java index f0b3c9172f93..4123ddbbc52b 100644 --- a/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java +++ b/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java @@ -263,7 +263,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName()); static final ConfigKey NTPServerConfig = new ConfigKey(String.class, "ntp.server.list", "Advanced", null, - "Comma separated list of NTP servers to configure in Secondary storage VM", false, ConfigKey.Scope.Global, null); + "Comma separated list of NTP servers to configure in Secondary storage VM", true, ConfigKey.Scope.Global, null); static final ConfigKey MaxNumberOfSsvmsForMigration = new ConfigKey("Advanced", Integer.class, "max.ssvm.count", "5", "Number of additional SSVMs to handle migration of data objects concurrently", true, ConfigKey.Scope.Global); diff --git a/systemvm/debian/opt/cloud/bin/setup/common.sh b/systemvm/debian/opt/cloud/bin/setup/common.sh index e24642fc6035..987f07d7659d 100755 --- a/systemvm/debian/opt/cloud/bin/setup/common.sh +++ b/systemvm/debian/opt/cloud/bin/setup/common.sh @@ -567,14 +567,12 @@ setup_ntp() { if [ -f $NTP_CONF_FILE ] then IFS=',' read -a server_list <<< "$NTP_SERVER_LIST" + sed -i "/^server /d" $NTP_CONF_FILE for (( iterator=${#server_list[@]}-1 ; iterator>=0 ; iterator-- )) do server=$(echo ${server_list[iterator]} | tr -d '\r') PATTERN="server $server" - if grep -q "^$PATTERN$" $NTP_CONF_FILE ; then - sed -i "/^$PATTERN$/d" $NTP_CONF_FILE - fi - sed -i "0,/^server/s//$PATTERN\nserver/" $NTP_CONF_FILE + sed -i "0,/^#server/s//$PATTERN\n#server/" $NTP_CONF_FILE done systemctl enable ntp else From 53963256d85aef95928bbdddd87963c78721e183 Mon Sep 17 00:00:00 2001 From: DK101010 <57522802+DK101010@users.noreply.github.com> Date: Sun, 27 Jun 2021 03:10:30 +0200 Subject: [PATCH 038/120] server: Bug/false positive success message vm start (#5148) * add throws statement during the retry process * Update engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java Co-authored-by: dahn Co-authored-by: DK101010 Co-authored-by: dahn --- .../cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java index 567675ab0534..02ffb37ba158 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java @@ -253,6 +253,8 @@ public void deployVirtualMachine(String reservationId, VMEntityVO vmEntityVO, St } _itMgr.start(vm.getUuid(), params, plan, null); + } else { + throw ex; } } } else { From 379454caae76279329c52aa6ae3eea389741d935 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Mon, 28 Jun 2021 15:27:27 +0530 Subject: [PATCH 039/120] Updating pom.xml version numbers for release 4.15.1.0 Signed-off-by: Rohit Yadav --- agent/pom.xml | 2 +- api/pom.xml | 2 +- client/pom.xml | 2 +- core/pom.xml | 2 +- debian/changelog | 6 ++++++ developer/pom.xml | 2 +- engine/api/pom.xml | 2 +- engine/components-api/pom.xml | 2 +- engine/network/pom.xml | 2 +- engine/orchestration/pom.xml | 2 +- engine/pom.xml | 2 +- engine/schema/pom.xml | 2 +- engine/service/pom.xml | 2 +- engine/storage/cache/pom.xml | 2 +- engine/storage/configdrive/pom.xml | 2 +- engine/storage/datamotion/pom.xml | 2 +- engine/storage/image/pom.xml | 2 +- engine/storage/integration-test/pom.xml | 2 +- engine/storage/pom.xml | 2 +- engine/storage/snapshot/pom.xml | 2 +- engine/storage/volume/pom.xml | 2 +- framework/agent-lb/pom.xml | 2 +- framework/ca/pom.xml | 2 +- framework/cluster/pom.xml | 2 +- framework/config/pom.xml | 2 +- framework/db/pom.xml | 2 +- framework/direct-download/pom.xml | 2 +- framework/events/pom.xml | 2 +- framework/ipc/pom.xml | 2 +- framework/jobs/pom.xml | 2 +- framework/managed-context/pom.xml | 2 +- framework/pom.xml | 2 +- framework/quota/pom.xml | 2 +- framework/rest/pom.xml | 2 +- framework/security/pom.xml | 2 +- framework/spring/lifecycle/pom.xml | 2 +- framework/spring/module/pom.xml | 2 +- plugins/acl/dynamic-role-based/pom.xml | 2 +- plugins/acl/project-role-based/pom.xml | 2 +- plugins/acl/static-role-based/pom.xml | 2 +- .../affinity-group-processors/explicit-dedication/pom.xml | 2 +- plugins/affinity-group-processors/host-affinity/pom.xml | 2 +- .../affinity-group-processors/host-anti-affinity/pom.xml | 2 +- plugins/alert-handlers/snmp-alerts/pom.xml | 2 +- plugins/alert-handlers/syslog-alerts/pom.xml | 2 +- plugins/api/discovery/pom.xml | 2 +- plugins/api/rate-limit/pom.xml | 2 +- plugins/api/solidfire-intg-test/pom.xml | 2 +- plugins/api/vmware-sioc/pom.xml | 2 +- plugins/backup/dummy/pom.xml | 2 +- plugins/backup/veeam/pom.xml | 2 +- plugins/ca/root-ca/pom.xml | 2 +- plugins/database/mysql-ha/pom.xml | 2 +- plugins/database/quota/pom.xml | 2 +- plugins/dedicated-resources/pom.xml | 2 +- plugins/deployment-planners/implicit-dedication/pom.xml | 2 +- plugins/deployment-planners/user-concentrated-pod/pom.xml | 2 +- plugins/deployment-planners/user-dispersing/pom.xml | 2 +- plugins/event-bus/inmemory/pom.xml | 2 +- plugins/event-bus/kafka/pom.xml | 2 +- plugins/event-bus/rabbitmq/pom.xml | 2 +- plugins/ha-planners/skip-heurestics/pom.xml | 2 +- plugins/host-allocators/random/pom.xml | 2 +- plugins/hypervisors/baremetal/pom.xml | 2 +- plugins/hypervisors/hyperv/pom.xml | 2 +- plugins/hypervisors/kvm/pom.xml | 2 +- plugins/hypervisors/ovm/pom.xml | 2 +- plugins/hypervisors/ovm3/pom.xml | 2 +- plugins/hypervisors/simulator/pom.xml | 2 +- plugins/hypervisors/ucs/pom.xml | 2 +- plugins/hypervisors/vmware/pom.xml | 2 +- plugins/hypervisors/xenserver/pom.xml | 2 +- plugins/integrations/cloudian/pom.xml | 2 +- plugins/integrations/kubernetes-service/pom.xml | 2 +- plugins/integrations/prometheus/pom.xml | 2 +- plugins/metrics/pom.xml | 2 +- plugins/network-elements/bigswitch/pom.xml | 2 +- plugins/network-elements/brocade-vcs/pom.xml | 2 +- plugins/network-elements/cisco-vnmc/pom.xml | 2 +- plugins/network-elements/dns-notifier/pom.xml | 2 +- plugins/network-elements/elastic-loadbalancer/pom.xml | 2 +- plugins/network-elements/f5/pom.xml | 2 +- plugins/network-elements/globodns/pom.xml | 2 +- plugins/network-elements/internal-loadbalancer/pom.xml | 2 +- plugins/network-elements/juniper-contrail/pom.xml | 2 +- plugins/network-elements/juniper-srx/pom.xml | 2 +- plugins/network-elements/netscaler/pom.xml | 2 +- plugins/network-elements/nicira-nvp/pom.xml | 2 +- plugins/network-elements/opendaylight/pom.xml | 2 +- plugins/network-elements/ovs/pom.xml | 2 +- plugins/network-elements/palo-alto/pom.xml | 2 +- plugins/network-elements/stratosphere-ssp/pom.xml | 2 +- plugins/network-elements/vxlan/pom.xml | 2 +- plugins/outofbandmanagement-drivers/ipmitool/pom.xml | 2 +- .../outofbandmanagement-drivers/nested-cloudstack/pom.xml | 2 +- plugins/outofbandmanagement-drivers/redfish/pom.xml | 2 +- plugins/pom.xml | 2 +- plugins/storage-allocators/random/pom.xml | 2 +- plugins/storage/image/default/pom.xml | 2 +- plugins/storage/image/s3/pom.xml | 2 +- plugins/storage/image/sample/pom.xml | 2 +- plugins/storage/image/swift/pom.xml | 2 +- plugins/storage/volume/cloudbyte/pom.xml | 2 +- plugins/storage/volume/datera/pom.xml | 2 +- plugins/storage/volume/default/pom.xml | 2 +- plugins/storage/volume/nexenta/pom.xml | 2 +- plugins/storage/volume/sample/pom.xml | 2 +- plugins/storage/volume/solidfire/pom.xml | 2 +- plugins/user-authenticators/ldap/pom.xml | 2 +- plugins/user-authenticators/md5/pom.xml | 2 +- plugins/user-authenticators/pbkdf2/pom.xml | 2 +- plugins/user-authenticators/plain-text/pom.xml | 2 +- plugins/user-authenticators/saml2/pom.xml | 2 +- plugins/user-authenticators/sha256salted/pom.xml | 2 +- pom.xml | 2 +- quickcloud/pom.xml | 2 +- server/pom.xml | 2 +- services/console-proxy/pom.xml | 2 +- services/console-proxy/rdpconsole/pom.xml | 2 +- services/console-proxy/server/pom.xml | 2 +- services/pom.xml | 2 +- services/secondary-storage/controller/pom.xml | 2 +- services/secondary-storage/pom.xml | 2 +- services/secondary-storage/server/pom.xml | 2 +- systemvm/pom.xml | 2 +- test/pom.xml | 2 +- tools/apidoc/pom.xml | 2 +- tools/checkstyle/pom.xml | 2 +- tools/devcloud-kvm/pom.xml | 2 +- tools/devcloud4/pom.xml | 2 +- tools/docker/Dockerfile | 2 +- tools/docker/Dockerfile.marvin | 4 ++-- tools/marvin/pom.xml | 2 +- tools/marvin/setup.py | 2 +- tools/pom.xml | 2 +- usage/pom.xml | 2 +- utils/pom.xml | 2 +- vmware-base/pom.xml | 2 +- 138 files changed, 144 insertions(+), 138 deletions(-) diff --git a/agent/pom.xml b/agent/pom.xml index 317b9f56fdee..42655b17e7c3 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/api/pom.xml b/api/pom.xml index d1cc731894e8..8fb03ca2875d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/client/pom.xml b/client/pom.xml index ba7f7556c252..169d0a6c982c 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/core/pom.xml b/core/pom.xml index 6738dcd55fac..db467500be4c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/debian/changelog b/debian/changelog index e6f233393ccc..df7bc1e7103b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cloudstack (4.15.1.0) unstable; urgency=low + + * Update the version to 4.15.1.0 + + -- the Apache CloudStack project Mon, 28 Jun 2021 15:27:27 +0530 + cloudstack (4.15.1.0-SNAPSHOT) unstable; urgency=low * Update the version to 4.15.1.0-SNAPSHOT diff --git a/developer/pom.xml b/developer/pom.xml index df1be353de2e..b5dfabe0841d 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/engine/api/pom.xml b/engine/api/pom.xml index d2474f809497..7d0355a5d574 100644 --- a/engine/api/pom.xml +++ b/engine/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml index 26f22a7539b6..649f1308c3b9 100644 --- a/engine/components-api/pom.xml +++ b/engine/components-api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/engine/network/pom.xml b/engine/network/pom.xml index e8888c7b3405..0929fe961ab6 100644 --- a/engine/network/pom.xml +++ b/engine/network/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml index 846d48ec2e00..90e2995294cb 100755 --- a/engine/orchestration/pom.xml +++ b/engine/orchestration/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/engine/pom.xml b/engine/pom.xml index e81b09d4809d..893fc11198dc 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml index da91749641d1..efcc9bad10a1 100644 --- a/engine/schema/pom.xml +++ b/engine/schema/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/engine/service/pom.xml b/engine/service/pom.xml index 7c7ecaa8783d..67fe5bab7f02 100644 --- a/engine/service/pom.xml +++ b/engine/service/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 cloud-engine-service war diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml index 1f3f5f627431..d78a2ffb44bc 100644 --- a/engine/storage/cache/pom.xml +++ b/engine/storage/cache/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/engine/storage/configdrive/pom.xml b/engine/storage/configdrive/pom.xml index 9570adc26a32..05eff5fe62be 100644 --- a/engine/storage/configdrive/pom.xml +++ b/engine/storage/configdrive/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml index db4e53d1e3fd..bc37fcaa5714 100644 --- a/engine/storage/datamotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml index 979f181c2e00..fe86d1ab9a1b 100644 --- a/engine/storage/image/pom.xml +++ b/engine/storage/image/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 475ebd0fc0af..a835074ffe2b 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index c03f9ffebe75..f1cb2e20022c 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index c19adc43936e..3b0f0517567e 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml index 38f364780323..127c02faea5b 100644 --- a/engine/storage/volume/pom.xml +++ b/engine/storage/volume/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/framework/agent-lb/pom.xml b/framework/agent-lb/pom.xml index ed58da736342..abba5ccce9fe 100644 --- a/framework/agent-lb/pom.xml +++ b/framework/agent-lb/pom.xml @@ -24,7 +24,7 @@ cloudstack-framework org.apache.cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/ca/pom.xml b/framework/ca/pom.xml index 2262e7e22deb..73af795ae54d 100644 --- a/framework/ca/pom.xml +++ b/framework/ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml index 0af846601d29..1b15106d29da 100644 --- a/framework/cluster/pom.xml +++ b/framework/cluster/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/config/pom.xml b/framework/config/pom.xml index aded63b18393..218410ba31bd 100644 --- a/framework/config/pom.xml +++ b/framework/config/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/db/pom.xml b/framework/db/pom.xml index 4142ba23abcc..28ce27c96448 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/direct-download/pom.xml b/framework/direct-download/pom.xml index 4f2719e47669..14f7ccc6086d 100644 --- a/framework/direct-download/pom.xml +++ b/framework/direct-download/pom.xml @@ -24,7 +24,7 @@ cloudstack-framework org.apache.cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml \ No newline at end of file diff --git a/framework/events/pom.xml b/framework/events/pom.xml index 284f92d4fbff..92b46b68de33 100644 --- a/framework/events/pom.xml +++ b/framework/events/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index 7fd681b99295..3bfbaabf2359 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index 401c7d15fda5..53bfd748fbe6 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml index 29f36aab30da..5114af8727fc 100644 --- a/framework/managed-context/pom.xml +++ b/framework/managed-context/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/framework/pom.xml b/framework/pom.xml index e2edbe0d887a..0b7656798ca5 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml index 35a9cc06a9b5..abfeb4731b6a 100644 --- a/framework/quota/pom.xml +++ b/framework/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml index a43d57b32275..954cd9bb518d 100644 --- a/framework/rest/pom.xml +++ b/framework/rest/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml cloud-framework-rest diff --git a/framework/security/pom.xml b/framework/security/pom.xml index 0216ee98113d..726a3e3adbc7 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml index a93c76e198b3..255c5228411d 100644 --- a/framework/spring/lifecycle/pom.xml +++ b/framework/spring/lifecycle/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml index b680d800126f..a4983cd6ef02 100644 --- a/framework/spring/module/pom.xml +++ b/framework/spring/module/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/acl/dynamic-role-based/pom.xml b/plugins/acl/dynamic-role-based/pom.xml index 3ba0b672e1ad..cad38280a0f0 100644 --- a/plugins/acl/dynamic-role-based/pom.xml +++ b/plugins/acl/dynamic-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/acl/project-role-based/pom.xml b/plugins/acl/project-role-based/pom.xml index 4618683bcb73..cc0561052929 100644 --- a/plugins/acl/project-role-based/pom.xml +++ b/plugins/acl/project-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml index 6e7f00cf5e98..d9d2be2adaa5 100644 --- a/plugins/acl/static-role-based/pom.xml +++ b/plugins/acl/static-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml index ab306ea06ea0..561474137a0b 100644 --- a/plugins/affinity-group-processors/explicit-dedication/pom.xml +++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/affinity-group-processors/host-affinity/pom.xml b/plugins/affinity-group-processors/host-affinity/pom.xml index a71ff7a9dcdc..d4656ed12bc3 100644 --- a/plugins/affinity-group-processors/host-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml index a54c5949d142..97b01a7a60b3 100644 --- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml index c25de1520797..690a9cf3dce8 100644 --- a/plugins/alert-handlers/snmp-alerts/pom.xml +++ b/plugins/alert-handlers/snmp-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml index 50cb3f460cb4..9ba0758ecbf0 100644 --- a/plugins/alert-handlers/syslog-alerts/pom.xml +++ b/plugins/alert-handlers/syslog-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml index d86a9287c652..46d8453b445c 100644 --- a/plugins/api/discovery/pom.xml +++ b/plugins/api/discovery/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml index 8bd6c567432a..c30383165eef 100644 --- a/plugins/api/rate-limit/pom.xml +++ b/plugins/api/rate-limit/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml index cd0011cc1c5d..db66187b24f0 100644 --- a/plugins/api/solidfire-intg-test/pom.xml +++ b/plugins/api/solidfire-intg-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/api/vmware-sioc/pom.xml b/plugins/api/vmware-sioc/pom.xml index e50f36eb22a5..e6be8bf59fc5 100644 --- a/plugins/api/vmware-sioc/pom.xml +++ b/plugins/api/vmware-sioc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/backup/dummy/pom.xml b/plugins/backup/dummy/pom.xml index d309b6cca8ba..f20231d4dee7 100644 --- a/plugins/backup/dummy/pom.xml +++ b/plugins/backup/dummy/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/backup/veeam/pom.xml b/plugins/backup/veeam/pom.xml index 4fab8af125db..cf64399dfe59 100644 --- a/plugins/backup/veeam/pom.xml +++ b/plugins/backup/veeam/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/ca/root-ca/pom.xml b/plugins/ca/root-ca/pom.xml index 94f09fae7356..38d115938f15 100644 --- a/plugins/ca/root-ca/pom.xml +++ b/plugins/ca/root-ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml index 9a86e57cdd5e..657449a567e1 100644 --- a/plugins/database/mysql-ha/pom.xml +++ b/plugins/database/mysql-ha/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml index c9e9f75fcc4b..1807b09514a1 100644 --- a/plugins/database/quota/pom.xml +++ b/plugins/database/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml index 3da0f296f206..8176d522c860 100644 --- a/plugins/dedicated-resources/pom.xml +++ b/plugins/dedicated-resources/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml index ec79c9907610..334e1c2f61ff 100644 --- a/plugins/deployment-planners/implicit-dedication/pom.xml +++ b/plugins/deployment-planners/implicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml index edcfb59ca6b9..ad1f85629f6f 100644 --- a/plugins/deployment-planners/user-concentrated-pod/pom.xml +++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml index 726a613c6e96..aff6ca5aeffd 100644 --- a/plugins/deployment-planners/user-dispersing/pom.xml +++ b/plugins/deployment-planners/user-dispersing/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml index 6f3b2bdbc07e..329bbcd414ac 100644 --- a/plugins/event-bus/inmemory/pom.xml +++ b/plugins/event-bus/inmemory/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml index 4f8bdf4d5bdd..fbe14ded76e3 100644 --- a/plugins/event-bus/kafka/pom.xml +++ b/plugins/event-bus/kafka/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml index a171ecf03215..29b858f83cec 100644 --- a/plugins/event-bus/rabbitmq/pom.xml +++ b/plugins/event-bus/rabbitmq/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml index 3a59ec4ce08b..3611d8bd2e24 100644 --- a/plugins/ha-planners/skip-heurestics/pom.xml +++ b/plugins/ha-planners/skip-heurestics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml index afe1a0a083c4..55e42f432af8 100644 --- a/plugins/host-allocators/random/pom.xml +++ b/plugins/host-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index a14332cbc573..044b7381a1bd 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml cloud-plugin-hypervisor-baremetal diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index b8eb356b0b8b..cda66be4eb0b 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index e2e14f8ad85b..28a172b28603 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml index 2e2c9401ff5f..001ee2ba136a 100644 --- a/plugins/hypervisors/ovm/pom.xml +++ b/plugins/hypervisors/ovm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml index d9c6d2819d5d..46304de4858b 100644 --- a/plugins/hypervisors/ovm3/pom.xml +++ b/plugins/hypervisors/ovm3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml index e81cccfd3e40..93e7d508d0a3 100644 --- a/plugins/hypervisors/simulator/pom.xml +++ b/plugins/hypervisors/simulator/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml cloud-plugin-hypervisor-simulator diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml index 08712dc924b0..8d822deacc73 100644 --- a/plugins/hypervisors/ucs/pom.xml +++ b/plugins/hypervisors/ucs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml cloud-plugin-hypervisor-ucs diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index 01b31cf69467..18fd3cc0b03d 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml index 1fc65dfb233e..28f1f2ee03a6 100644 --- a/plugins/hypervisors/xenserver/pom.xml +++ b/plugins/hypervisors/xenserver/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/integrations/cloudian/pom.xml b/plugins/integrations/cloudian/pom.xml index 7cc53d4efcb9..505ddf93fa3a 100644 --- a/plugins/integrations/cloudian/pom.xml +++ b/plugins/integrations/cloudian/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/integrations/kubernetes-service/pom.xml b/plugins/integrations/kubernetes-service/pom.xml index a85dd1dade2a..ab81c5bbc66b 100644 --- a/plugins/integrations/kubernetes-service/pom.xml +++ b/plugins/integrations/kubernetes-service/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/integrations/prometheus/pom.xml b/plugins/integrations/prometheus/pom.xml index 99cb2cf021ff..f1abbaa0b05f 100644 --- a/plugins/integrations/prometheus/pom.xml +++ b/plugins/integrations/prometheus/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/metrics/pom.xml b/plugins/metrics/pom.xml index 943487d4e46a..0627ce4a9f36 100644 --- a/plugins/metrics/pom.xml +++ b/plugins/metrics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/plugins/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml index 197b78eddecf..1f397655f0a6 100644 --- a/plugins/network-elements/bigswitch/pom.xml +++ b/plugins/network-elements/bigswitch/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml index 29ad385d59cf..fef1294aa79a 100644 --- a/plugins/network-elements/brocade-vcs/pom.xml +++ b/plugins/network-elements/brocade-vcs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml index 87aab3305628..2f32d856191f 100644 --- a/plugins/network-elements/cisco-vnmc/pom.xml +++ b/plugins/network-elements/cisco-vnmc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml index 57b49d1c8680..c8a6447619c2 100644 --- a/plugins/network-elements/dns-notifier/pom.xml +++ b/plugins/network-elements/dns-notifier/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml cloud-plugin-example-dns-notifier diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml index 06006987ccaf..b6f0d1714a32 100644 --- a/plugins/network-elements/elastic-loadbalancer/pom.xml +++ b/plugins/network-elements/elastic-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/f5/pom.xml b/plugins/network-elements/f5/pom.xml index e2456f3dbdf4..ea90410b9e0f 100644 --- a/plugins/network-elements/f5/pom.xml +++ b/plugins/network-elements/f5/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml index cb8b8bc6f677..56719ebcd728 100644 --- a/plugins/network-elements/globodns/pom.xml +++ b/plugins/network-elements/globodns/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml index 167e2e547f64..5daf5cb575ee 100644 --- a/plugins/network-elements/internal-loadbalancer/pom.xml +++ b/plugins/network-elements/internal-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index 09c41a958d15..d66ae56e213b 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/juniper-srx/pom.xml b/plugins/network-elements/juniper-srx/pom.xml index 64ce0d7895eb..1723ea2f7e56 100644 --- a/plugins/network-elements/juniper-srx/pom.xml +++ b/plugins/network-elements/juniper-srx/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml index ad08d1d3d42c..c91e91f09e64 100644 --- a/plugins/network-elements/netscaler/pom.xml +++ b/plugins/network-elements/netscaler/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 11bf1c9628aa..88ace033b975 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml index 68c1271ec1c0..6c982cc0b6fc 100644 --- a/plugins/network-elements/opendaylight/pom.xml +++ b/plugins/network-elements/opendaylight/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml index baae799e2437..78213eb062c3 100644 --- a/plugins/network-elements/ovs/pom.xml +++ b/plugins/network-elements/ovs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml index 33d51a3d329d..30e59af7fdcc 100644 --- a/plugins/network-elements/palo-alto/pom.xml +++ b/plugins/network-elements/palo-alto/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml index c749501e6ae4..1de47b870313 100644 --- a/plugins/network-elements/stratosphere-ssp/pom.xml +++ b/plugins/network-elements/stratosphere-ssp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml index 4af0eaf68d54..0d6100b0ae0f 100644 --- a/plugins/network-elements/vxlan/pom.xml +++ b/plugins/network-elements/vxlan/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml index 6d371a3c8f85..bf41e865752a 100644 --- a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml +++ b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml index 012d176a2359..6c9f96484a49 100644 --- a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml +++ b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/redfish/pom.xml b/plugins/outofbandmanagement-drivers/redfish/pom.xml index c1418d548712..2c3292b05357 100644 --- a/plugins/outofbandmanagement-drivers/redfish/pom.xml +++ b/plugins/outofbandmanagement-drivers/redfish/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/pom.xml b/plugins/pom.xml index f9a7c29a469c..686ad4d79308 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml index 9efbb38092ea..ee5c2047e55b 100644 --- a/plugins/storage-allocators/random/pom.xml +++ b/plugins/storage-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index 735a70e7ed35..3228910bce05 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index b8b2836109f6..32488110eab6 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index 9dc04e809f60..3176740d55da 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index aaf40072aa02..4b4da9807aa7 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml index 5ba51f886c34..6b054c43ce10 100644 --- a/plugins/storage/volume/cloudbyte/pom.xml +++ b/plugins/storage/volume/cloudbyte/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/volume/datera/pom.xml b/plugins/storage/volume/datera/pom.xml index 1104237300e7..daa52330939d 100644 --- a/plugins/storage/volume/datera/pom.xml +++ b/plugins/storage/volume/datera/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml index 884491cc883d..31148796eb3c 100644 --- a/plugins/storage/volume/default/pom.xml +++ b/plugins/storage/volume/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml index 4959f59c1e89..43ac0cd1e31d 100644 --- a/plugins/storage/volume/nexenta/pom.xml +++ b/plugins/storage/volume/nexenta/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml index 8c40100b9c8b..9dbeeb1ad34f 100644 --- a/plugins/storage/volume/sample/pom.xml +++ b/plugins/storage/volume/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml index 3551ccda0405..21a9ae63dbc1 100644 --- a/plugins/storage/volume/solidfire/pom.xml +++ b/plugins/storage/volume/solidfire/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../../pom.xml diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml index 7972cd88a371..a5ba9b4d1d6e 100644 --- a/plugins/user-authenticators/ldap/pom.xml +++ b/plugins/user-authenticators/ldap/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml index 5218e68f6ce0..bb2b0bd501cc 100644 --- a/plugins/user-authenticators/md5/pom.xml +++ b/plugins/user-authenticators/md5/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml index 6d62236a2ab1..475e4c01d1b0 100644 --- a/plugins/user-authenticators/pbkdf2/pom.xml +++ b/plugins/user-authenticators/pbkdf2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml index 7b4c12080a78..3496e290684d 100644 --- a/plugins/user-authenticators/plain-text/pom.xml +++ b/plugins/user-authenticators/plain-text/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml index 9a9524e1c422..5e873878f547 100644 --- a/plugins/user-authenticators/saml2/pom.xml +++ b/plugins/user-authenticators/saml2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml index f86d8018a87a..4040745542f7 100644 --- a/plugins/user-authenticators/sha256salted/pom.xml +++ b/plugins/user-authenticators/sha256salted/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../../pom.xml diff --git a/pom.xml b/pom.xml index 06014a3109ef..ff19c9ff8347 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 pom Apache CloudStack Apache CloudStack is an IaaS ("Infrastructure as a Service") cloud orchestration platform. diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml index 5f37d680efb3..898d4acfad27 100644 --- a/quickcloud/pom.xml +++ b/quickcloud/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/server/pom.xml b/server/pom.xml index 72dd1ae8e011..3f0f75669373 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index 10797fba6221..ce9922446729 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/services/console-proxy/rdpconsole/pom.xml b/services/console-proxy/rdpconsole/pom.xml index 6b8d4f8a1857..5f7610828af3 100644 --- a/services/console-proxy/rdpconsole/pom.xml +++ b/services/console-proxy/rdpconsole/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index 09431d6e2d81..02f47cd0b222 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/services/pom.xml b/services/pom.xml index 03d90f1949e3..d3f331524a40 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml index a5b558cc0a7a..f9cb8f351001 100644 --- a/services/secondary-storage/controller/pom.xml +++ b/services/secondary-storage/controller/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index 205bd5af0637..d7d7dd652fee 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml index f1b451cd5f6b..751ebc3b6914 100644 --- a/services/secondary-storage/server/pom.xml +++ b/services/secondary-storage/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/systemvm/pom.xml b/systemvm/pom.xml index 43ad109380f5..bceae9721ee6 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/test/pom.xml b/test/pom.xml index 735bcf26505f..db396e7d8012 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml index 2f528c9ddc19..b5f54dc92c61 100644 --- a/tools/apidoc/pom.xml +++ b/tools/apidoc/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml index 53ca24e2e5bb..0790c89b2c39 100644 --- a/tools/checkstyle/pom.xml +++ b/tools/checkstyle/pom.xml @@ -22,7 +22,7 @@ Apache CloudStack Developer Tools - Checkstyle Configuration org.apache.cloudstack checkstyle - 4.15.1.0-SNAPSHOT + 4.15.1.0 UTF-8 diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml index 1d5d2d83b5ba..79b988ac1f4d 100644 --- a/tools/devcloud-kvm/pom.xml +++ b/tools/devcloud-kvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml index a2aad9bc87e7..b678eacfe4ad 100644 --- a/tools/devcloud4/pom.xml +++ b/tools/devcloud4/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index a3e5276b1c91..451184bf18bf 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:18.04 MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.15.1.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.15.1.0" ARG DEBIAN_FRONTEND=noninteractive diff --git a/tools/docker/Dockerfile.marvin b/tools/docker/Dockerfile.marvin index 76175aad1249..d1a2eeb19005 100644 --- a/tools/docker/Dockerfile.marvin +++ b/tools/docker/Dockerfile.marvin @@ -20,11 +20,11 @@ FROM python:2 MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.15.1.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.15.1.0" ENV WORK_DIR=/marvin -ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.15.1.0-SNAPSHOT.tar.gz +ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.15.1.0.tar.gz RUN apt-get update && apt-get install -y vim RUN pip install --upgrade paramiko nose requests diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 5fe69f2835b8..12c2a5d7f5dc 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index 67f632cf1fe3..93467f898842 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -27,7 +27,7 @@ raise RuntimeError("python setuptools is required to build Marvin") -VERSION = "4.15.1.0-SNAPSHOT" +VERSION = "4.15.1.0" setup(name="Marvin", version=VERSION, diff --git a/tools/pom.xml b/tools/pom.xml index 3fec1374ebae..7df173d32830 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/usage/pom.xml b/usage/pom.xml index 853828c43b9b..51efb1841f12 100644 --- a/usage/pom.xml +++ b/usage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 diff --git a/utils/pom.xml b/utils/pom.xml index 481631d3cdd9..4934d26152d3 100755 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 ../pom.xml diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index 8cc7272e8bc2..6c778b9c3c39 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0-SNAPSHOT + 4.15.1.0 From 896b0331d7750a88aa4c4aa656f99b0a69a597b4 Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 09:17:36 -0400 Subject: [PATCH 040/120] test hit the current vm information --- .../api/command/user/vm/CloneVMCmd.java | 10 ++++ .../cloud/template/TemplateManagerImpl.java | 1 - .../java/com/cloud/vm/UserVmManagerImpl.java | 46 ++++++++++++++++--- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 83a95b46ba3e..0479a7d3fb36 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -48,6 +48,8 @@ public class CloneVMCmd extends BaseAsyncCreateCustomIdCmd implements UserCmd { @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.") private Long domainId; + private Long temporaryTemlateId; + public String getAccountName() { return accountName; } @@ -74,6 +76,14 @@ public String getEventDescription() { return "Cloning user VM: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()); } + public Long getTemporaryTemlateId() { + return this.temporaryTemlateId; + } + + public void setTemporaryTemlateId(Long tempId) { + this.temporaryTemlateId = tempId; + } + @Override public void create() throws ResourceAllocationException { try { diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index fc91584b2d44..b96ab18841f0 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1783,7 +1783,6 @@ public void doInTransactionWithoutResult(TransactionStatus status) { } @Override - @DB @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template from clone", create = true) public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account templateOwner) throws ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 6b0e739dfed1..bc260b2a506a 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -51,6 +51,8 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import com.cloud.network.*; +import com.cloud.network.security.SecurityGroupVO; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountService; @@ -226,14 +228,10 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.hypervisor.kvm.dpdk.DpdkHelper; -import com.cloud.network.IpAddressManager; -import com.cloud.network.Network; import com.cloud.network.Network.IpAddresses; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkModel; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetwork; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; @@ -4525,6 +4523,14 @@ public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueExce if (vmStatus.state != State.Shutdown && vmStatus.state != State.Stopped) { throw new CloudRuntimeException("You should clone an instance that's shutdown!"); } + if (vmStatus.getHypervisorType() != HypervisorType.KVM && vmStatus.getHypervisorType() != HypervisorType.Simulator) { + throw new CloudRuntimeException("The clone operation is only supported on KVM and Simulator!"); + } + Long accountId = curVm.getAccountId(); + Account vmOwner = _accountDao.findById(accountId); + if (vmOwner == null) { + throw new CloudRuntimeException("This VM doesn't have an owner account, please assign one to it"); + } List volumes = _volsDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); if (CollectionUtils.isEmpty(volumes)) { throw new CloudRuntimeException("The VM to copy does not have a Volume attached!"); @@ -5571,14 +5577,40 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE } @Override - public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperationException { + public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException { //network configurations and check, then create the template UserVm curVm = cmd.getTargetVM(); // check if host is available Long hostId = curVm.getHostId(); getDestinationHost(hostId, true); - - + Long zoneId = curVm.getDataCenterId(); + DataCenter dataCenter = _entityMgr.findById(DataCenter.class, zoneId); + Map vmProperties = curVm.getDetails(); + String keyboard = vmProperties.get(VmDetailConstants.KEYBOARD); + HypervisorType hypervisorType = curVm.getHypervisorType(); + Account curAccount = _accountDao.findById(curVm.getAccountId()); + long callingUserId = CallContext.current().getCallingUserId(); + Account callerAccount = CallContext.current().getCallingAccount(); +// IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, curAccount.getId() == Account.ACCOUNT_ID_SYSTEM, callerAccount, callingUserId, dataCenter, null, null); + long serviceOfferingId = curVm.getServiceOfferingId(); + ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); + List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); + List securityGroupIdList = securityGroupList.stream().map(SecurityGroupVO::getId).collect(Collectors.toList()); + String uuidName = _uuidMgr.generateUuid(UserVm.class, null); + String hostName = generateHostName(uuidName); + String displayName = hostName + "-Clone"; + Long diskOfferingId = curVm.getDiskOfferingId(); + Long size = null; // mutual exclusive with disk offering id + HTTPMethod httpMethod = cmd.getHttpMethod(); + String userData = curVm.getUserData(); + String sshKeyPair = null; + Map ipToNetoworkMap = null; // Since we've specified Ip + boolean isDisplayVM = curVm.isDisplayVm(); + boolean dynamicScalingEnabled = curVm.isDynamicallyScalable(); + +// if (dataCenter.getNetworkType() == NetworkType.Basic) { +// +// } return null; } From cfd131c3c83b9421660fa03aae76e0b4e364fa31 Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 09:34:31 -0400 Subject: [PATCH 041/120] fix typo of star import --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index bc260b2a506a..c22ea5c83907 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -51,7 +51,11 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import com.cloud.network.*; +import com.cloud.network.IpAddress; +import com.cloud.network.IpAddressManager; +import com.cloud.network.Network; +import com.cloud.network.NetworkModel; +import com.cloud.network.PhysicalNetwork; import com.cloud.network.security.SecurityGroupVO; import com.cloud.user.Account; import com.cloud.user.AccountManager; From 9677858d48b56ba4903bac5dcc63f413966d95fc Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 09:41:19 -0400 Subject: [PATCH 042/120] fix the null pt except --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index c22ea5c83907..2dac8084911d 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5589,7 +5589,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio getDestinationHost(hostId, true); Long zoneId = curVm.getDataCenterId(); DataCenter dataCenter = _entityMgr.findById(DataCenter.class, zoneId); - Map vmProperties = curVm.getDetails(); + Map vmProperties = curVm.getDetails() != null ? curVm.getDetails() : new HashMap<>(); String keyboard = vmProperties.get(VmDetailConstants.KEYBOARD); HypervisorType hypervisorType = curVm.getHypervisorType(); Account curAccount = _accountDao.findById(curVm.getAccountId()); From 85129eea652cb6c483946a26e0f2795e53a47c00 Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 10:21:29 -0400 Subject: [PATCH 043/120] add vm record creation code --- .../apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 5 +++++ .../main/java/com/cloud/template/TemplateManagerImpl.java | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 0479a7d3fb36..ac8f3eebbca6 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -6,6 +6,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.vm.VirtualMachine; @@ -88,6 +89,10 @@ public void setTemporaryTemlateId(Long tempId) { public void create() throws ResourceAllocationException { try { _userVmService.checkCloneCondition(this); + VirtualMachineTemplate template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId())); + if (template == null) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "failed to create a template to db"); + } UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); if (vmRecord == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "unable to record a new VM to db!"); diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index b96ab18841f0..6d7fc7b2ca23 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1786,7 +1786,6 @@ public void doInTransactionWithoutResult(TransactionStatus status) { @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template from clone", create = true) public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account templateOwner) throws ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); - boolean isAdmin = (_accountMgr.isAdmin(caller.getId())); _accountMgr.checkAccess(caller, null, true, templateOwner); String name = cmd.getTemplateName(); if (name.length() > 32) { @@ -1794,7 +1793,7 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template } int bits = 64; // where to specify - boolean requireHVM = true, sshKeyEnabled = true, featured = false; + boolean featured = false; boolean isPublic = cmd.isPublic(); Long volumeId = _volumeDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT).get(0).getId(); HypervisorType hyperType = null; From b6607f4f270411f9d0a6bbeff27fd781f6d3b734 Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 12:00:25 -0400 Subject: [PATCH 044/120] add the user vm db creation code --- .../api/command/user/vm/CloneVMCmd.java | 1 + .../java/com/cloud/vm/UserVmManagerImpl.java | 32 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index ac8f3eebbca6..1879cd27b3eb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -93,6 +93,7 @@ public void create() throws ResourceAllocationException { if (template == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "failed to create a template to db"); } + setTemporaryTemlateId(template.getId()); UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); if (vmRecord == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "unable to record a new VM to db!"); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 2dac8084911d..8cc906273ebf 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -68,6 +68,8 @@ import com.cloud.user.UserStatisticsVO; import com.cloud.user.UserVO; import com.cloud.user.VmDiskStatisticsVO; +import com.cloud.utils.net.MacAddress; +import com.googlecode.ipv6.IPv6Address; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; @@ -5581,7 +5583,7 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE } @Override - public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException { + public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperationException, ResourceAllocationException, InsufficientCapacityException, ResourceUnavailableException { //network configurations and check, then create the template UserVm curVm = cmd.getTargetVM(); // check if host is available @@ -5595,7 +5597,10 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio Account curAccount = _accountDao.findById(curVm.getAccountId()); long callingUserId = CallContext.current().getCallingUserId(); Account callerAccount = CallContext.current().getCallingAccount(); -// IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, curAccount.getId() == Account.ACCOUNT_ID_SYSTEM, callerAccount, callingUserId, dataCenter, null, null); + IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, curAccount.getId() == Account.ACCOUNT_ID_SYSTEM, callerAccount, callingUserId, dataCenter, null, null); + String ipv6Address = null; + String macAddress = null; + IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); @@ -5608,14 +5613,25 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio HTTPMethod httpMethod = cmd.getHttpMethod(); String userData = curVm.getUserData(); String sshKeyPair = null; - Map ipToNetoworkMap = null; // Since we've specified Ip + Map ipToNetoworkMap = null; // Since we've specified Ip boolean isDisplayVM = curVm.isDisplayVm(); boolean dynamicScalingEnabled = curVm.isDynamicallyScalable(); - -// if (dataCenter.getNetworkType() == NetworkType.Basic) { -// -// } - return null; + Long templateId = cmd.getTemporaryTemlateId(); + VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId); + if (template == null) { + throw new CloudRuntimeException("the temporary template is not created, server error, contact your sys admin"); + } + List networkIds = null; + String group = null; + InstanceGroupVO groupVo = getGroupForVm(cmd.getId()); + if (groupVo != null) { + group = groupVo.getName(); + } + UserVm vmResult = createBasicSecurityGroupVirtualMachine(dataCenter, serviceOffering, template, securityGroupIdList, curAccount, hostName, displayName, diskOfferingId, + size , group , hypervisorType, cmd.getHttpMethod(), userData , sshKeyPair , ipToNetoworkMap, addr, isDisplayVM , keyboard , null, + curVm.getDetails(), cmd.getCustomId(), new HashMap<>(), + null, new HashMap<>(), dynamicScalingEnabled); + return vmResult; } /** From afae56078259caabf3d271cf3f9f51c89c997cd6 Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 12:03:01 -0400 Subject: [PATCH 045/120] add vm creation typo fix --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 8cc906273ebf..16d540034dc7 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -68,8 +68,6 @@ import com.cloud.user.UserStatisticsVO; import com.cloud.user.UserVO; import com.cloud.user.VmDiskStatisticsVO; -import com.cloud.utils.net.MacAddress; -import com.googlecode.ipv6.IPv6Address; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; From 0a1405d0790e3e29fb805b020b3ec1d5ef322bcf Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 12:19:19 -0400 Subject: [PATCH 046/120] change ip to available --- .../apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 4 ++++ server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 1879cd27b3eb..a7de9630736d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -107,6 +107,10 @@ public void create() throws ResourceAllocationException { } catch (InvalidParameterValueException e) { s_logger.warn("Exception: ", e); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); + } finally { + if (getTemporaryTemlateId() != null) { + // TODO: delete template in the service + } } } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 16d540034dc7..2bfa26ee5b28 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5595,10 +5595,11 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio Account curAccount = _accountDao.findById(curVm.getAccountId()); long callingUserId = CallContext.current().getCallingUserId(); Account callerAccount = CallContext.current().getCallingAccount(); - IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, curAccount.getId() == Account.ACCOUNT_ID_SYSTEM, callerAccount, callingUserId, dataCenter, null, null); +// IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, curAccount.getId() == Account.ACCOUNT_ID_SYSTEM, callerAccount, callingUserId, dataCenter, null, null); String ipv6Address = null; String macAddress = null; - IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); +// IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); + IpAddresses addr = new IpAddresses("127.20.0.183", ipv6Address, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); From 64c0fd51ec6eef65bc62b9c09051da729181a5ef Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 12:21:41 -0400 Subject: [PATCH 047/120] fix ip issue --- .../org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 1 + server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index a7de9630736d..074e47b1671a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -110,6 +110,7 @@ public void create() throws ResourceAllocationException { } finally { if (getTemporaryTemlateId() != null) { // TODO: delete template in the service + s_logger.warn("clearing the temporary template: " + getTemporaryTemlateId()); } } } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 2bfa26ee5b28..9f24fd8b3620 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -51,7 +51,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import com.cloud.network.IpAddress; +//import com.cloud.network.IpAddress; import com.cloud.network.IpAddressManager; import com.cloud.network.Network; import com.cloud.network.NetworkModel; From e04dc22896699b24ac3a64e8e5efcf6d6087862c Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 28 Jun 2021 12:31:36 -0400 Subject: [PATCH 048/120] fix the vm creation detail --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 9f24fd8b3620..224f9f6ed38e 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5628,7 +5628,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio } UserVm vmResult = createBasicSecurityGroupVirtualMachine(dataCenter, serviceOffering, template, securityGroupIdList, curAccount, hostName, displayName, diskOfferingId, size , group , hypervisorType, cmd.getHttpMethod(), userData , sshKeyPair , ipToNetoworkMap, addr, isDisplayVM , keyboard , null, - curVm.getDetails(), cmd.getCustomId(), new HashMap<>(), + curVm.getDetails() == null ? new HashMap<>() : curVm.getDetails(), cmd.getCustomId(), new HashMap<>(), null, new HashMap<>(), dynamicScalingEnabled); return vmResult; } From ee2c9cead24b490bdbcbd0d93d95e9f754fc6ac2 Mon Sep 17 00:00:00 2001 From: davidjumani Date: Tue, 29 Jun 2021 04:37:03 +0530 Subject: [PATCH 049/120] tests: Skip test_persistent_networks if kvm and ovs (#5128) * tests: Skip test_persistent_networks if kvm and ovs * Skip if any host has ovs * addressing comments --- .../smoke/test_persistent_network.py | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/test/integration/smoke/test_persistent_network.py b/test/integration/smoke/test_persistent_network.py index cf14b04b5635..65f37bfa0e15 100644 --- a/test/integration/smoke/test_persistent_network.py +++ b/test/integration/smoke/test_persistent_network.py @@ -52,6 +52,22 @@ def setUpClass(cls): cls.testClient = super(TestL2PersistentNetworks, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.hypervisor = cls.testClient.getHypervisorInfo() + + isKVM = cls.hypervisor.lower() in ["kvm"] + isOVSEnabled = False + hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__ + if isKVM : + # Test only if all the hosts use OVS + grepCmd = 'grep "network.bridge.type=openvswitch" /etc/cloudstack/agent/agent.properties' + hosts = list_hosts(cls.api_client, type='Routing', hypervisor='kvm') + for host in hosts : + if len(SshClient(host.ipaddress, port=22, user=hostConfig["username"], + passwd=hostConfig["password"]).execute(grepCmd)) != 0 : + isOVSEnabled = True + break + if isKVM and isOVSEnabled : + cls.skipTest(cls, "KVM with OVS doesn't support persistent networks, skipping") + # Fill services from the external config file cls.services = cls.testClient.getParsedTestDataConfig() cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][ @@ -152,7 +168,7 @@ def list_all_hosts_in_zone(self, zone_id): return hosts ''' - Verifies creation of bridge on KVM host + Verifies creation of bridge on KVM host ''' def verify_bridge_creation(self, host, vlan_id): username = self.hostConfig["username"] @@ -186,7 +202,7 @@ def get_port_group_name(self, switch_type, vlan_id, network_rate): return None ''' - Verifies creation of port group on the Distributed vSwitch or a host in a cluster connected to + Verifies creation of port group on the Distributed vSwitch or a host in a cluster connected to a Standard vSwitch ''' def verify_port_group_creation(self, vlan_id): @@ -264,7 +280,7 @@ def verify_network_setup_on_host_per_cluster(self, hypervisor, vlan_id): "Failed to find port group on hosts of cluster: " + cluster.name) ''' - This test verifies that on creation of an Isolated network with network offering with isPersistent flag + This test verifies that on creation of an Isolated network with network offering with isPersistent flag set to true the corresponding network resources are created without having to deploy a VM - VR created ''' @attr(tags=["advanced", "isolated", "persistent", "network"], required_hardware="false") @@ -303,7 +319,7 @@ def test_01_isolated_persistent_network(self): self.verify_network_setup_on_host_per_cluster(host.hypervisor.lower(), networkVlan) ''' - This test verifies that on creation of an L2 network with network offering with isPersistent flag + This test verifies that on creation of an L2 network with network offering with isPersistent flag set to true the corresponding network resources are created without having to deploy a VM - VR created ''' @attr(tags=["advanced", "l2", "persistent", "network"], required_hardware="false") From 9ac3925936c385065ff6629d3bb7e0b46b579500 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 29 Jun 2021 09:22:24 +0200 Subject: [PATCH 050/120] server: list routers by healthchecksfailed (#4886) * server: list routers by healthchecksfailed * #4886: fix build error * #4886: ignore global setting Co-authored-by: Wei Zhou --- .../apache/cloudstack/api/ApiConstants.java | 1 + .../command/admin/router/ListRoutersCmd.java | 8 +++++ .../api/response/DomainRouterResponse.java | 2 +- .../com/cloud/api/query/QueryManagerImpl.java | 33 +++++++++++++++++-- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 28e4ba3bb30f..b060b5a21762 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -711,6 +711,7 @@ public class ApiConstants { public static final String UCS_BLADE_DN = "bladedn"; public static final String UCS_BLADE_ID = "bladeid"; public static final String VM_GUEST_IP = "vmguestip"; + public static final String HEALTHCHECK_FAILED = "healthchecksfailed"; public static final String HEALTHCHECK_RESPONSE_TIMEOUT = "responsetimeout"; public static final String HEALTHCHECK_INTERVAL_TIME = "intervaltime"; public static final String HEALTHCHECK_HEALTHY_THRESHOLD = "healthythreshold"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java index 4fabcf5df768..3c9b684c0c86 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java @@ -81,6 +81,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @Parameter(name = ApiConstants.VERSION, type = CommandType.STRING, description = "list virtual router elements by version") private String version; + @Parameter(name = ApiConstants.HEALTHCHECK_FAILED, type = CommandType.BOOLEAN, since = "4.16", + description = "if this parameter is passed, list only routers by health check results") + private Boolean healthCheckFailed; + @Parameter(name = ApiConstants.FETCH_ROUTER_HEALTH_CHECK_RESULTS, type = CommandType.BOOLEAN, since = "4.14", description = "if true is passed for this parameter, also fetch last executed health check results for the router. Default is false") private Boolean fetchHealthCheckResults; @@ -137,6 +141,10 @@ public String getRole() { return Role.VIRTUAL_ROUTER.toString(); } + public Boolean isHealthCheckFailed() { + return healthCheckFailed; + } + public boolean shouldFetchHealthCheckResults() { return BooleanUtils.isTrue(fetchHealthCheckResults); } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/DomainRouterResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/DomainRouterResponse.java index 0a4a456aed2a..563d6a9f961c 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/DomainRouterResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/DomainRouterResponse.java @@ -225,7 +225,7 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView @Param(description = "true if the router template requires upgrader") private boolean requiresUpgrade; - @SerializedName("healthchecksfailed") + @SerializedName(ApiConstants.HEALTHCHECK_FAILED) @Param(description = "true if any health checks had failed") private boolean healthChecksFailed; diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java index e388a7539ec8..0c8a7f794355 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -187,6 +187,7 @@ import com.cloud.network.RouterHealthCheckResult; import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.dao.RouterHealthCheckResultDao; +import com.cloud.network.dao.RouterHealthCheckResultVO; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.security.SecurityGroupVMMapVO; import com.cloud.network.security.dao.SecurityGroupVMMapDao; @@ -232,6 +233,7 @@ import com.cloud.utils.StringUtils; import com.cloud.utils.Ternary; import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -1262,7 +1264,7 @@ private Pair, Integer> listSecurityGroupRulesByVM(long @Override public ListResponse searchForRouters(ListRoutersCmd cmd) { Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getClusterId(), - cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getVersion()); + cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getVersion(), cmd.isHealthCheckFailed()); ListResponse response = new ListResponse(); List routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()])); if (VirtualNetworkApplianceManager.RouterHealthChecksEnabled.value()) { @@ -1282,7 +1284,7 @@ public ListResponse searchForRouters(ListRoutersCmd cmd) { @Override public ListResponse searchForInternalLbVms(ListInternalLBVMsCmd cmd) { Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), null, cmd.getHostId(), - cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), null); + cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), null, null); ListResponse response = new ListResponse(); List routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()])); if (VirtualNetworkApplianceManager.RouterHealthChecksEnabled.value()) { @@ -1301,7 +1303,7 @@ public ListResponse searchForInternalLbVms(ListInternalLBV } private Pair, Integer> searchForRoutersInternal(BaseListProjectAndAccountResourcesCmd cmd, Long id, String name, String state, Long zoneId, Long podId, Long clusterId, - Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String version) { + Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String version, Boolean isHealthCheckFailed) { Account caller = CallContext.current().getCallingAccount(); List permittedAccounts = new ArrayList(); @@ -1345,6 +1347,27 @@ private Pair, Integer> searchForRoutersInternal(BaseLis sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ); } + List routersWithFailures = null; + if (isHealthCheckFailed != null) { + GenericSearchBuilder routerHealthCheckResultSearch = routerHealthCheckResultDao.createSearchBuilder(Long.class); + routerHealthCheckResultSearch.and("checkResult", routerHealthCheckResultSearch.entity().getCheckResult(), SearchCriteria.Op.EQ); + routerHealthCheckResultSearch.selectFields(routerHealthCheckResultSearch.entity().getRouterId()); + routerHealthCheckResultSearch.done(); + SearchCriteria ssc = routerHealthCheckResultSearch.create(); + ssc.setParameters("checkResult", false); + routersWithFailures = routerHealthCheckResultDao.customSearch(ssc, null); + + if (routersWithFailures != null && ! routersWithFailures.isEmpty()) { + if (isHealthCheckFailed) { + sb.and("routerId", sb.entity().getId(), SearchCriteria.Op.IN); + } else { + sb.and("routerId", sb.entity().getId(), SearchCriteria.Op.NIN); + } + } else if (isHealthCheckFailed) { + return new Pair, Integer>(Collections.emptyList(), 0); + } + } + SearchCriteria sc = sb.create(); _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -1403,6 +1426,10 @@ private Pair, Integer> searchForRoutersInternal(BaseLis sc.setParameters("version", "Cloudstack Release " + version + "%"); } + if (routersWithFailures != null && ! routersWithFailures.isEmpty()) { + sc.setParameters("routerId", routersWithFailures.toArray(new Object[routersWithFailures.size()])); + } + // search VR details by ids Pair, Integer> uniqueVrPair = _routerJoinDao.searchAndCount(sc, searchFilter); Integer count = uniqueVrPair.second(); From 9fd38c4da093e85564d2465d55292ee575abfb08 Mon Sep 17 00:00:00 2001 From: Rakesh Date: Tue, 29 Jun 2021 09:33:31 +0200 Subject: [PATCH 051/120] server: Display proper names in error message (#5140) Display the proper account and other names rather than the uuid representation of the object --- server/src/main/java/com/cloud/acl/DomainChecker.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/com/cloud/acl/DomainChecker.java b/server/src/main/java/com/cloud/acl/DomainChecker.java index 24b6b2a42b42..aba0d456bfa2 100644 --- a/server/src/main/java/com/cloud/acl/DomainChecker.java +++ b/server/src/main/java/com/cloud/acl/DomainChecker.java @@ -105,7 +105,7 @@ protected DomainChecker() { @Override public boolean checkAccess(Account caller, Domain domain) throws PermissionDeniedException { if (caller.getState() != Account.State.enabled) { - throw new PermissionDeniedException(caller + " is disabled."); + throw new PermissionDeniedException("Account " + caller.getAccountName() + " is disabled."); } if (domain == null) { @@ -116,10 +116,10 @@ public boolean checkAccess(Account caller, Domain domain) throws PermissionDenie if (_accountService.isNormalUser(caller.getId())) { if (caller.getDomainId() != domainId) { - throw new PermissionDeniedException(caller + " does not have permission to operate within domain id=" + domain.getUuid()); + throw new PermissionDeniedException("Account " + caller.getAccountName() + " does not have permission to operate within domain id=" + domain.getUuid()); } } else if (!_domainDao.isChildDomain(caller.getDomainId(), domainId)) { - throw new PermissionDeniedException(caller + " does not have permission to operate within domain id=" + domain.getUuid()); + throw new PermissionDeniedException("Account " + caller.getAccountName() + " does not have permission to operate within domain id=" + domain.getUuid()); } return true; @@ -155,7 +155,8 @@ public boolean checkAccess(Account caller, ControlledEntity entity, AccessType a // account can launch a VM from this template LaunchPermissionVO permission = _launchPermissionDao.findByTemplateAndAccount(template.getId(), caller.getId()); if (permission == null) { - throw new PermissionDeniedException(caller + " does not have permission to launch instances from " + template); + throw new PermissionDeniedException("Account " + caller.getAccountName() + + " does not have permission to launch instances from template " + template.getName()); } } else { // Domain admin and regular user can delete/modify only templates created by them From 7835c0812062381c7e5dd5ab9d719297cd3187dc Mon Sep 17 00:00:00 2001 From: dahn Date: Tue, 29 Jun 2021 09:36:08 +0200 Subject: [PATCH 052/120] tests: formatting and cleanup fixes for test_volumes (#5146) * (auto) formatting and cleanup fixes * ssh fail and detach in all cases * message format and removed overcleaning Co-authored-by: Daan Hoogland --- test/integration/smoke/test_volumes.py | 634 ++++++++++++------------- 1 file changed, 308 insertions(+), 326 deletions(-) diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index fa7bea0b9c12..e1d419ff150b 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -16,41 +16,42 @@ # under the License. """ BVT tests for Volumes """ -#Import Local Modules -from marvin.cloudstackTestCase import cloudstackTestCase +import os +import tempfile +import time import unittest -#from marvin.cloudstackException import * +import urllib.error +import urllib.parse +import urllib.request + from marvin.cloudstackAPI import (deleteVolume, extractVolume, resizeVolume) -#from marvin.sshClient import SshClient -from marvin.lib.utils import (cleanup_resources, - format_volume_to_ext3, - wait_until) + +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.codes import SUCCESS, FAILED, XEN_SERVER from marvin.lib.base import (ServiceOffering, VirtualMachine, Account, Volume, Host, DiskOffering, - StoragePool,) + StoragePool) from marvin.lib.common import (get_domain, - get_suitable_test_template, - get_zone, - find_storage_pool_type, - get_pod, - list_disk_offering) + get_suitable_test_template, + get_zone, + find_storage_pool_type, + get_pod, + list_disk_offering) from marvin.lib.utils import checkVolumeSize -from marvin.codes import SUCCESS, FAILED, XEN_SERVER +from marvin.lib.utils import (format_volume_to_ext3, + wait_until) + from nose.plugins.attrib import attr -#Import System modules -import os -import urllib.request, urllib.parse, urllib.error -import time -import tempfile _multiprocess_shared_ = True + class TestCreateVolume(cloudstackTestCase): @classmethod @@ -65,25 +66,28 @@ def setUpClass(cls): cls.hypervisor = testClient.getHypervisorInfo() cls.services['mode'] = cls.zone.networktype cls.invalidStoragePoolType = False - #for LXC if the storage pool of type 'rbd' ex: ceph is not available, skip the test + # for LXC if the storage pool of type 'rbd' ex: ceph is not available, skip the test if cls.hypervisor.lower() == 'lxc': if not find_storage_pool_type(cls.apiclient, storagetype='rbd'): # RBD storage type is required for data volumes for LXC cls.invalidStoragePoolType = True return cls.disk_offering = DiskOffering.create( - cls.apiclient, - cls.services["disk_offering"] - ) + cls.apiclient, + cls.services["disk_offering"] + ) + cls._cleanup.append(cls.disk_offering) cls.sparse_disk_offering = DiskOffering.create( - cls.apiclient, - cls.services["sparse_disk_offering"] - ) + cls.apiclient, + cls.services["sparse_disk_offering"] + ) + cls._cleanup.append(cls.sparse_disk_offering) cls.custom_disk_offering = DiskOffering.create( - cls.apiclient, - cls.services["disk_offering"], - custom=True - ) + cls.apiclient, + cls.services["disk_offering"], + custom=True + ) + cls._cleanup.append(cls.custom_disk_offering) template = get_suitable_test_template( cls.apiclient, @@ -101,28 +105,24 @@ def setUpClass(cls): cls.services["diskname"] = cls.services["volume"]["diskname"] # Create VMs, NAT Rules etc cls.account = Account.create( - cls.apiclient, - cls.services["account"], - domainid=cls.domain.id - ) + cls.apiclient, + cls.services["account"], + domainid=cls.domain.id + ) + cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create( - cls.apiclient, - cls.services["service_offerings"]["tiny"] - ) + cls.apiclient, + cls.services["service_offerings"]["tiny"] + ) cls.virtual_machine = VirtualMachine.create( - cls.apiclient, - cls.services, - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.custom_disk_offering, - cls.account - ] + cls.apiclient, + cls.services, + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.services["mode"] + ) + cls._cleanup.append(cls.virtual_machine) def setUp(self): @@ -134,81 +134,81 @@ def setUp(self): self.skipTest("Skipping test because of valid storage\ pool not available") - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_01_create_volume(self): """Test Volume creation for all Disk Offerings (incl. custom) - """ # Validate the following # 1. Create volumes from the different sizes # 2. Verify the size of volume with actual size allocated + """ self.volumes = [] for k, v in list(self.services["volume_offerings"].items()): volume = Volume.create( - self.apiClient, - v, - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.debug("Created a volume with ID: %s" % volume.id) + self.apiClient, + v, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid, + diskofferingid=self.disk_offering.id + ) self.volumes.append(volume) + self.debug("Created a volume with ID: %s" % volume.id) if self.virtual_machine.hypervisor == "KVM": sparse_volume = Volume.create( - self.apiClient, - self.services, - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid, - diskofferingid=self.sparse_disk_offering.id - ) - self.debug("Created a sparse volume: %s" % sparse_volume.id) + self.apiClient, + self.services, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid, + diskofferingid=self.sparse_disk_offering.id + ) self.volumes.append(sparse_volume) + self.debug("Created a sparse volume: %s" % sparse_volume.id) volume = Volume.create_custom_disk( - self.apiClient, - self.services, - account=self.account.name, - domainid=self.account.domainid, - ) - self.debug("Created a volume with custom offering: %s" % volume.id) + self.apiClient, + self.services, + account=self.account.name, + domainid=self.account.domainid, + ) self.volumes.append(volume) + self.debug("Created a volume with custom offering: %s" % volume.id) - #Attach a volume with different disk offerings - #and check the memory allocated to each of them + # Attach a volume with different disk offerings + # and check the memory allocated to each of them for volume in self.volumes: list_volume_response = Volume.list( - self.apiClient, - id=volume.id) + self.apiClient, + id=volume.id) self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list response returns a valid list" - ) + isinstance(list_volume_response, list), + True, + "Check list response returns a valid list" + ) self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) + list_volume_response, + None, + "Check if volume exists in ListVolumes" + ) self.debug( "Attaching volume (ID: %s) to VM (ID: %s)" % ( - volume.id, - self.virtual_machine.id - )) + volume.id, + self.virtual_machine.id + )) self.virtual_machine.attach_volume( - self.apiClient, - volume - ) + self.apiClient, + volume + ) try: ssh = self.virtual_machine.get_ssh_client() self.debug("Rebooting VM %s" % self.virtual_machine.id) ssh.execute("reboot") except Exception as e: self.fail("SSH access failed for VM %s - %s" % - (self.virtual_machine.ipaddress, e)) + (self.virtual_machine.ipaddress, e)) # Poll listVM to ensure VM is started properly timeout = self.services["timeout"] @@ -217,9 +217,9 @@ def test_01_create_volume(self): # Ensure that VM is in running state list_vm_response = VirtualMachine.list( - self.apiClient, - id=self.virtual_machine.id - ) + self.apiClient, + id=self.virtual_machine.id + ) if isinstance(list_vm_response, list): vm = list_vm_response[0] @@ -234,41 +234,35 @@ def test_01_create_volume(self): vol_sz = str(list_volume_response[0].size) ssh = self.virtual_machine.get_ssh_client( - reconnect=True - ) + reconnect=True + ) # Get the updated volume information list_volume_response = Volume.list( - self.apiClient, - id=volume.id) + self.apiClient, + id=volume.id) if list_volume_response[0].hypervisor.lower() == XEN_SERVER.lower(): volume_name = "/dev/xvd" + chr(ord('a') + int(list_volume_response[0].deviceid)) self.debug(" Using XenServer volume_name: %s" % (volume_name)) - ret = checkVolumeSize(ssh_handle=ssh,volume_name=volume_name,size_to_verify=vol_sz) + ret = checkVolumeSize(ssh_handle=ssh, volume_name=volume_name, size_to_verify=vol_sz) elif list_volume_response[0].hypervisor.lower() == "kvm": volume_name = "/dev/vd" + chr(ord('a') + int(list_volume_response[0].deviceid)) self.debug(" Using KVM volume_name: %s" % (volume_name)) - ret = checkVolumeSize(ssh_handle=ssh,volume_name=volume_name,size_to_verify=vol_sz) + ret = checkVolumeSize(ssh_handle=ssh, volume_name=volume_name, size_to_verify=vol_sz) elif list_volume_response[0].hypervisor.lower() == "hyperv": - ret = checkVolumeSize(ssh_handle=ssh,volume_name="/dev/sdb",size_to_verify=vol_sz) + ret = checkVolumeSize(ssh_handle=ssh, volume_name="/dev/sdb", size_to_verify=vol_sz) else: - ret = checkVolumeSize(ssh_handle=ssh,size_to_verify=vol_sz) - self.debug(" Volume Size Expected %s Actual :%s" %(vol_sz,ret[1])) + ret = checkVolumeSize(ssh_handle=ssh, size_to_verify=vol_sz) + self.debug(" Volume Size Expected %s Actual :%s" % (vol_sz, ret[1])) self.virtual_machine.detach_volume(self.apiClient, volume) - self.assertEqual(ret[0],SUCCESS,"Check if promised disk size actually available") + self.assertEqual(ret[0], SUCCESS, "Check if promised disk size actually available") time.sleep(self.services["sleep"]) def tearDown(self): - #Clean up, terminate the created volumes - cleanup_resources(self.apiClient, self.cleanup) - return + super(TestCreateVolume, self).tearDown() @classmethod def tearDownClass(cls): - try: - cls.apiclient = super(TestCreateVolume, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.apiclient, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + super(TestCreateVolume, cls).tearDownClass() class TestVolumes(cloudstackTestCase): @@ -285,25 +279,28 @@ def setUpClass(cls): cls.services['mode'] = cls.zone.networktype cls.hypervisor = testClient.getHypervisorInfo() cls.invalidStoragePoolType = False - #for LXC if the storage pool of type 'rbd' ex: ceph is not available, skip the test + # for LXC if the storage pool of type 'rbd' ex: ceph is not available, skip the test if cls.hypervisor.lower() == 'lxc': if not find_storage_pool_type(cls.apiclient, storagetype='rbd'): # RBD storage type is required for data volumes for LXC cls.invalidStoragePoolType = True return cls.disk_offering = DiskOffering.create( - cls.apiclient, - cls.services["disk_offering"] - ) + cls.apiclient, + cls.services["disk_offering"] + ) + cls._cleanup.append(cls.disk_offering) cls.resized_disk_offering = DiskOffering.create( - cls.apiclient, - cls.services["resized_disk_offering"] - ) + cls.apiclient, + cls.services["resized_disk_offering"] + ) + cls._cleanup.append(cls.resized_disk_offering) cls.custom_resized_disk_offering = DiskOffering.create( - cls.apiclient, - cls.services["resized_disk_offering"], - custom=True - ) + cls.apiclient, + cls.services["resized_disk_offering"], + custom=True + ) + cls._cleanup.append(cls.custom_resized_disk_offering) cls.template = get_suitable_test_template( cls.apiclient, @@ -324,53 +321,40 @@ def setUpClass(cls): # Create VMs, VMs etc cls.account = Account.create( - cls.apiclient, - cls.services["account"], - domainid=cls.domain.id - ) + cls.apiclient, + cls.services["account"], + domainid=cls.domain.id + ) + cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create( - cls.apiclient, - cls.services["service_offerings"]["tiny"] - ) + cls.apiclient, + cls.services["service_offerings"]["tiny"] + ) + cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create( - cls.apiclient, - cls.services, - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) + cls.apiclient, + cls.services, + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.services["mode"] + ) + cls._cleanup.append(cls.virtual_machine) pools = StoragePool.list(cls.apiclient) - # cls.assertEqual( - # validateList(pools)[0], - # PASS, - # "storage pool list validation failed") - - if cls.hypervisor.lower() == 'lxc' and cls.storage_pools.type.lower() != 'rbd': raise unittest.SkipTest("Snapshots not supported on Hyper-V or LXC") cls.volume = Volume.create( - cls.apiclient, - cls.services, - account=cls.account.name, - domainid=cls.account.domainid - ) - cls._cleanup = [ - cls.resized_disk_offering, - cls.custom_resized_disk_offering, - cls.service_offering, - cls.disk_offering, - cls.volume, - cls.account - ] + cls.apiclient, + cls.services, + account=cls.account.name, + domainid=cls.account.domainid + ) + cls._cleanup.append(cls.volume) @classmethod def tearDownClass(cls): - try: - cleanup_resources(cls.apiclient, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + super(TestVolumes, cls).tearDownClass() def setUp(self): self.apiClient = self.testClient.getApiClient() @@ -383,29 +367,29 @@ def setUp(self): available") def tearDown(self): - #Clean up, terminate the created volumes - if self.attached: - self.virtual_machine.get_ssh_client(reconnect = True) - - self.virtual_machine.detach_volume(self.apiClient, self.volume) - if self.virtual_machine.hypervisor == "KVM": self.virtual_machine.stop(self.apiClient) + if self.attached: + self.virtual_machine.detach_volume(self.apiClient, self.volume) self.virtual_machine.start(self.apiClient) - self.virtual_machine.get_ssh_client(reconnect = True) - + try: + self.virtual_machine.get_ssh_client(reconnect=True) + except Exception as err: + self.fail("SSH failed for Virtual machine: %s due to %s" % + (self.virtual_machine.ipaddress, err)) + elif self.attached: + self.virtual_machine.detach_volume(self.apiClient, self.volume) - cleanup_resources(self.apiClient, self.cleanup) - return + super(TestVolumes, self).tearDown() - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_02_attach_volume(self): """Attach a created Volume to a Running VM - """ # Validate the following # 1. shows list of volumes # 2. "Attach Disk" pop-up box will display with list of instances # 3. disk should be attached to instance successfully + """ self.debug( "Attaching volume (ID: %s) to VM (ID: %s)" % ( @@ -435,7 +419,7 @@ def test_02_attach_volume(self): "Check if volume state (attached) is reflected" ) try: - #Format the attached volume to a known fs + # Format the attached volume to a known fs format_volume_to_ext3(self.virtual_machine.get_ssh_client()) except Exception as e: @@ -444,14 +428,14 @@ def test_02_attach_volume(self): (self.virtual_machine.ipaddress, e)) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_03_download_attached_volume(self): """Download a Volume attached to a VM - """ # Validate the following # 1. download volume will fail with proper error message # "Failed - Invalid state of the volume with ID: # It should be either detached or the VM should be in stopped state + """ self.debug("Extract attached Volume ID: %s" % self.volume.id) @@ -466,84 +450,84 @@ def test_03_download_attached_volume(self): with self.assertRaises(Exception): self.apiClient.extractVolume(cmd) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_04_delete_attached_volume(self): """Delete a Volume attached to a VM - """ # Validate the following # 1. delete volume will fail with proper error message # "Failed - Invalid state of the volume with ID: # It should be either detached or the VM should be in stopped state + """ self.debug("Trying to delete attached Volume ID: %s" % - self.volume.id) + self.volume.id) self.virtual_machine.attach_volume(self.apiClient, self.volume) self.attached = True cmd = deleteVolume.deleteVolumeCmd() cmd.id = self.volume.id - #Proper exception should be raised; deleting attach VM is not allowed - #with self.assertRaises(Exception): + # Proper exception should be raised; deleting attach VM is not allowed + # with self.assertRaises(Exception): with self.assertRaises(Exception): self.apiClient.deleteVolume(cmd) + self._cleanup.remove(self.volume) # when succeeded - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_05_detach_volume(self): """Detach a Volume attached to a VM - """ # Validate the following # Data disk should be detached from instance and detached data disk # details should be updated properly + """ self.debug( - "Detaching volume (ID: %s) from VM (ID: %s)" % ( - self.volume.id, - self.virtual_machine.id - )) + "Detaching volume (ID: %s) from VM (ID: %s)" % ( + self.volume.id, + self.virtual_machine.id)) self.virtual_machine.attach_volume(self.apiClient, self.volume) self.virtual_machine.detach_volume(self.apiClient, self.volume) self.attached = False - #Sleep to ensure the current state will reflected in other calls + # Sleep to ensure the current state will reflected in other calls time.sleep(self.services["sleep"]) list_volume_response = Volume.list( - self.apiClient, - id=self.volume.id - ) + self.apiClient, + id=self.volume.id + ) self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list response returns a valid list" - ) + isinstance(list_volume_response, list), + True, + "Check list response returns a valid list" + ) self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) + list_volume_response, + None, + "Check if volume exists in ListVolumes" + ) volume = list_volume_response[0] self.assertEqual( - volume.virtualmachineid, - None, - "Check if volume state (detached) is reflected" - ) + volume.virtualmachineid, + None, + "Check if volume state (detached) is reflected" + ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_06_download_detached_volume(self): """Download a Volume unattached to an VM + Validate the following + 1. able to download the volume when its not attached to instance """ - # Validate the following - # 1. able to download the volume when its not attached to instance self.debug("Extract detached Volume ID: %s" % self.volume.id) self.virtual_machine.attach_volume(self.apiClient, self.volume) - #Sleep to ensure the current state will reflected in other calls + # Sleep to ensure the current state will reflected in other calls time.sleep(self.services["sleep"]) self.virtual_machine.detach_volume(self.apiClient, self.volume) self.attached = False - #Sleep to ensure the current state will reflected in other calls + # Sleep to ensure the current state will reflected in other calls time.sleep(self.services["sleep"]) cmd = extractVolume.extractVolumeCmd() @@ -552,90 +536,90 @@ def test_06_download_detached_volume(self): cmd.zoneid = self.services["zoneid"] extract_vol = self.apiClient.extractVolume(cmd) - #Attempt to download the volume and save contents locally + # Attempt to download the volume and save contents locally try: formatted_url = urllib.parse.unquote_plus(extract_vol.url) self.debug("Attempting to download volume at url %s" % formatted_url) response = urllib.request.urlopen(formatted_url) self.debug("response from volume url %s" % response.getcode()) fd, path = tempfile.mkstemp() - self.debug("Saving volume %s to path %s" %(self.volume.id, path)) + self.debug("Saving volume %s to path %s" % (self.volume.id, path)) os.close(fd) with open(path, 'wb') as fd: fd.write(response.read()) self.debug("Saved volume successfully") - except Exception: + except Exception as e: self.fail( - "Extract Volume Failed with invalid URL %s (vol id: %s)" \ - % (extract_vol.url, self.volume.id) + "Extract Volume Failed (URL: %s , vol id: %s) due to %s" + % (extract_vol.url, self.volume.id, e) ) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_07_resize_fail(self): """Test resize (negative) non-existent volume""" # Verify the size is the new size is what we wanted it to be. self.debug("Fail Resize Volume ID: %s" % self.volume.id) # first, an invalid id - cmd = resizeVolume.resizeVolumeCmd() - cmd.id = "invalid id" + cmd = resizeVolume.resizeVolumeCmd() + cmd.id = "invalid id" cmd.diskofferingid = self.services['customresizeddiskofferingid'] - success = False + success = False try: self.apiClient.resizeVolume(cmd) except Exception as ex: - #print str(ex) + # print str(ex) if "invalid" in str(ex): success = True self.assertEqual( - success, - True, - "ResizeVolume - verify invalid id is handled appropriately") + success, + True, + "ResizeVolume - verify invalid id is handled appropriately") # Next, we'll try an invalid disk offering id - cmd.id = self.volume.id + cmd.id = self.volume.id cmd.diskofferingid = "invalid id" - success = False + success = False try: self.apiClient.resizeVolume(cmd) except Exception as ex: if "invalid" in str(ex): success = True self.assertEqual( - success, - True, - "ResizeVolume - verify disk offering is handled appropriately") + success, + True, + "ResizeVolume - verify disk offering is handled appropriately") # try to resize a root disk with a disk offering, root can only be resized by size= # get root vol from created vm list_volume_response = Volume.list( - self.apiClient, - virtualmachineid=self.virtual_machine.id, - type='ROOT', - listall=True - ) + self.apiClient, + virtualmachineid=self.virtual_machine.id, + type='ROOT', + listall=True + ) rootvolume = list_volume_response[0] - cmd.id = rootvolume.id + cmd.id = rootvolume.id cmd.diskofferingid = self.services['diskofferingid'] with self.assertRaises(Exception): self.apiClient.resizeVolume(cmd) # Ok, now let's try and resize a volume that is not custom. - cmd.id = self.volume.id + cmd.id = self.volume.id cmd.diskofferingid = self.services['diskofferingid'] - cmd.size = 4 + cmd.size = 4 self.debug( - "Attaching volume (ID: %s) to VM (ID: %s)" % ( - self.volume.id, - self.virtual_machine.id) - ) - #attach the volume + "Attaching volume (ID: %s) to VM (ID: %s)" % ( + self.volume.id, + self.virtual_machine.id) + ) + # attach the volume self.virtual_machine.attach_volume(self.apiClient, self.volume) self.attached = True - #stop the vm if it is on xenserver + # stop the vm if it is on xenserver hosts = Host.list(self.apiClient, id=self.virtual_machine.hostid) self.assertTrue(isinstance(hosts, list)) self.assertTrue(len(hosts) > 0) @@ -656,16 +640,15 @@ def test_07_resize_fail(self): time.sleep(30) return - - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_08_resize_volume(self): """Test resize a volume""" # Verify the size is the new size is what we wanted it to be. self.debug( - "Attaching volume (ID: %s) to VM (ID: %s)" % ( - self.volume.id, - self.virtual_machine.id - )) + "Attaching volume (ID: %s) to VM (ID: %s)" % ( + self.volume.id, + self.virtual_machine.id + )) self.virtual_machine.attach_volume(self.apiClient, self.volume) self.attached = True @@ -684,13 +667,13 @@ def test_08_resize_volume(self): self.services["disk_offering"]["disksize"] = 20 disk_offering_20_GB = DiskOffering.create( - self.apiclient, - self.services["disk_offering"] - ) + self.apiclient, + self.services["disk_offering"] + ) self.cleanup.append(disk_offering_20_GB) - cmd = resizeVolume.resizeVolumeCmd() - cmd.id = self.volume.id + cmd = resizeVolume.resizeVolumeCmd() + cmd.id = self.volume.id cmd.diskofferingid = disk_offering_20_GB.id self.apiClient.resizeVolume(cmd) @@ -699,12 +682,12 @@ def test_08_resize_volume(self): success = False while count < 3: list_volume_response = Volume.list( - self.apiClient, - id=self.volume.id, - type='DATADISK' - ) + self.apiClient, + id=self.volume.id, + type='DATADISK' + ) for vol in list_volume_response: - if vol.id == self.volume.id and int(vol.size) == (int(disk_offering_20_GB.disksize) * (1024** 3)) and vol.state == 'Ready': + if vol.id == self.volume.id and int(vol.size) == (int(disk_offering_20_GB.disksize) * (1024 ** 3)) and vol.state == 'Ready': success = True if success: break @@ -713,18 +696,18 @@ def test_08_resize_volume(self): count += 1 self.assertEqual( - success, - True, - "Check if the data volume resized appropriately" - ) + success, + True, + "Check if the data volume resized appropriately" + ) can_shrink = False list_volume_response = Volume.list( - self.apiClient, - id=self.volume.id, - type='DATADISK' - ) + self.apiClient, + id=self.volume.id, + type='DATADISK' + ) storage_pool_id = [x.storageid for x in list_volume_response if x.id == self.volume.id][0] storage = StoragePool.list(self.apiclient, id=storage_pool_id)[0] # At present only CLVM supports shrinking volumes @@ -734,15 +717,15 @@ def test_08_resize_volume(self): if can_shrink: self.services["disk_offering"]["disksize"] = 10 disk_offering_10_GB = DiskOffering.create( - self.apiclient, - self.services["disk_offering"] - ) + self.apiclient, + self.services["disk_offering"] + ) self.cleanup.append(disk_offering_10_GB) - cmd = resizeVolume.resizeVolumeCmd() - cmd.id = self.volume.id + cmd = resizeVolume.resizeVolumeCmd() + cmd.id = self.volume.id cmd.diskofferingid = disk_offering_10_GB.id - cmd.shrinkok = "true" + cmd.shrinkok = "true" self.apiClient.resizeVolume(cmd) @@ -750,9 +733,9 @@ def test_08_resize_volume(self): success = False while count < 3: list_volume_response = Volume.list( - self.apiClient, - id=self.volume.id - ) + self.apiClient, + id=self.volume.id + ) for vol in list_volume_response: if vol.id == self.volume.id and int(vol.size) == (int(disk_offering_10_GB.disksize) * (1024 ** 3)) and vol.state == 'Ready': success = True @@ -763,37 +746,38 @@ def test_08_resize_volume(self): count += 1 self.assertEqual( - success, - True, - "Check if the root volume resized appropriately" - ) + success, + True, + "Check if the root volume resized appropriately" + ) - #start the vm if it is on xenserver + # start the vm if it is on xenserver if hosts[0].hypervisor == "XenServer": self.virtual_machine.start(self.apiClient) time.sleep(30) return - @attr(tags = ["advanced", "advancedns", "smoke","basic"], required_hardware="false") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="false") def test_09_delete_detached_volume(self): """Delete a Volume unattached to an VM - """ # Validate the following # 1. volume should be deleted successfully and listVolume should not # contain the deleted volume details. # 2. "Delete Volume" menu item not shown under "Actions" menu. # (UI should not allow to delete the volume when it is attached # to instance by hiding the menu Item) + """ self.debug("Delete Volume ID: %s" % self.volume.id) self.volume_1 = Volume.create( - self.apiclient, - self.services, - account=self.account.name, - domainid=self.account.domainid + self.apiclient, + self.services, + account=self.account.name, + domainid=self.account.domainid ) + self.cleanup.append(self.volume_1) self.virtual_machine.attach_volume(self.apiClient, self.volume_1) self.virtual_machine.detach_volume(self.apiClient, self.volume_1) @@ -801,28 +785,30 @@ def test_09_delete_detached_volume(self): cmd = deleteVolume.deleteVolumeCmd() cmd.id = self.volume_1.id self.apiClient.deleteVolume(cmd) + self.cleanup.remove(self.volume_1) list_volume_response = Volume.list( - self.apiClient, - id=self.volume_1.id, - type='DATADISK' - ) + self.apiClient, + id=self.volume_1.id, + type='DATADISK' + ) self.assertEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) + list_volume_response, + None, + "Check if volume exists in ListVolumes" + ) return - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_10_list_volumes(self): - + """ # Validate the following # # 1. List Root Volume and waits until it has the newly introduced attributes # # 2. Verifies return attributes has values different from none, when instance is running # + """ list_vm = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id)[0] @@ -871,15 +857,15 @@ def test_10_list_volumes(self): self.assertTrue(hasattr(root_volume, "podname")) self.assertEqual(root_volume.podname, list_pods.name) - @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="true") + @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_11_attach_volume_with_unstarted_vm(self): """Attach a created Volume to a unstarted VM + Validate the following + 1. Attach to a vm in startvm=false state works and vm can be started afterwards. + 2. shows list of volumes + 3. "Attach Disk" pop-up box will display with list of instances + 4. disk should be attached to instance successfully """ - # Validate the following - # 1. Attach to a vm in startvm=false state works and vm can be started afterwards. - # 2. shows list of volumes - # 3. "Attach Disk" pop-up box will display with list of instances - # 4. disk should be attached to instance successfully test_vm = VirtualMachine.create( self.apiclient, @@ -891,6 +877,7 @@ def test_11_attach_volume_with_unstarted_vm(self): mode=self.services["mode"], startvm=False ) + self.cleanup.append(test_vm) self.debug( "Attaching volume (ID: %s) to VM (ID: %s)" % ( @@ -920,11 +907,10 @@ def test_11_attach_volume_with_unstarted_vm(self): None, "Check if volume state (attached) is reflected" ) - #Sleep to ensure the current state will reflected in other calls + # Sleep to ensure the current state will reflected in other calls time.sleep(self.services["sleep"]) test_vm.detach_volume(self.apiClient, self.volume) - self.cleanup.append(test_vm) return @@ -947,34 +933,31 @@ def checkVolumeResponse(): self.fail("Failed to return root volume response") return response - @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true") def test_11_migrate_volume_and_change_offering(self): - - # Validates the following - # - # 1. Creates a new Volume with a small disk offering - # - # 2. Migrates the Volume to another primary storage and changes the offering - # - # 3. Verifies the Volume has new offering when migrated to the new storage. + """ + Validates the following + 1. Creates a new Volume with a small disk offering + 2. Migrates the Volume to another primary storage and changes the offering + 3. Verifies the Volume has new offering when migrated to the new storage. + """ small_offering = list_disk_offering( self.apiclient, - name = "Small" + name="Small" )[0] large_offering = list_disk_offering( self.apiclient, - name = "Large" + name="Large" )[0] volume = Volume.create( self.apiClient, self.services, - zoneid = self.zone.id, - account = self.account.name, - domainid = self.account.domainid, - diskofferingid = small_offering.id + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid, + diskofferingid=small_offering.id ) self.debug("Created a small volume: %s" % volume.id) @@ -986,7 +969,7 @@ def test_11_migrate_volume_and_change_offering(self): pools = StoragePool.listForMigration( self.apiclient, id=volume.id - ) + ) pool = None @@ -1005,17 +988,16 @@ def test_11_migrate_volume_and_change_offering(self): Volume.migrate( self.apiclient, - volumeid = volume.id, - storageid = pool.id, - newdiskofferingid = large_offering.id, - livemigrate = livemigrate + volumeid=volume.id, + storageid=pool.id, + newdiskofferingid=large_offering.id, + livemigrate=livemigrate ) if self.virtual_machine.hypervisor == "KVM": - self.virtual_machine.start(self.apiclient - ) + self.virtual_machine.start(self.apiclient) migrated_vol = Volume.list( self.apiclient, - id = volume.id + id=volume.id )[0] self.assertEqual( migrated_vol.diskofferingname, From 4645863b25acc8510a75aa1d26ed73bd99339f01 Mon Sep 17 00:00:00 2001 From: davidjumani Date: Thu, 1 Jul 2021 09:45:21 +0530 Subject: [PATCH 053/120] tests: Fix test failures for Local storage and Basic zones (#5106) tests: Fix test failures for Local storage and Basic (SG) zones * Skip migrate vm when localstorage enabled * Fix test_direct_download.py * Skip test_03_create_network_domain_network_offering in basic zones * Skip test_03_create_vpc_domain_vpc_offering in basic zones * Skip test_01_add_primary_storage_disabled_host if localstorageenabled --- .../integration/smoke/test_direct_download.py | 80 ++++++++++--------- .../smoke/test_domain_network_offerings.py | 1 - .../smoke/test_domain_vpc_offerings.py | 1 - .../integration/smoke/test_primary_storage.py | 3 + test/integration/smoke/test_vm_life_cycle.py | 3 + 5 files changed, 48 insertions(+), 40 deletions(-) diff --git a/test/integration/smoke/test_direct_download.py b/test/integration/smoke/test_direct_download.py index 324fb5972cb2..b894f08934b2 100644 --- a/test/integration/smoke/test_direct_download.py +++ b/test/integration/smoke/test_direct_download.py @@ -184,20 +184,28 @@ def setUpClass(cls): cls.services["service_offerings"]["tiny"] ) cls._cleanup.append(cls.service_offering) - cls.network_offering = NetworkOffering.create( - cls.apiclient, - cls.services["l2-network_offering"], - ) - cls.network_offering.update(cls.apiclient, state='Enabled') - cls.services["network"]["networkoffering"] = cls.network_offering.id - cls.l2_network = Network.create( - cls.apiclient, - cls.services["l2-network"], - zoneid=cls.zone.id, - networkofferingid=cls.network_offering.id - ) - cls._cleanup.append(cls.l2_network) - cls._cleanup.append(cls.network_offering) + + if cls.zone.networktype == 'Basic' : + networks = Network.list(cls.apiclient) + if len(networks) == 0 : + self.skipTest("Skipping test since no network found in basic zone") + else : + cls.network = networks[0] + else : + cls.network_offering = NetworkOffering.create( + cls.apiclient, + cls.services["l2-network_offering"], + ) + cls._cleanup.append(cls.network_offering) + cls.network_offering.update(cls.apiclient, state='Enabled') + cls.services["network"]["networkoffering"] = cls.network_offering.id + cls.network = Network.create( + cls.apiclient, + cls.services["l2-network"], + zoneid=cls.zone.id, + networkofferingid=cls.network_offering.id + ) + cls._cleanup.append(cls.network) storage_pools = StoragePool.list( cls.apiclient, @@ -221,11 +229,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - try: - cleanup_resources(cls.apiclient, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return + super(TestDirectDownloadTemplates, cls).tearDownClass() def setUp(self): self.apiclient = self.testClient.getApiClient() @@ -234,11 +238,7 @@ def setUp(self): return def tearDown(self): - try: - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return + super(TestDirectDownloadTemplates, self).tearDown() def getCurrentStoragePoolTags(self, poolId): local_pool = StoragePool.list( @@ -269,6 +269,22 @@ def createServiceOffering(self, name, type, tags): tags=tags ) + def deployVM(self, offering) : + if self.zone.networktype == 'Basic' : + vm = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + serviceofferingid=offering.id + ) + else : + vm = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + serviceofferingid=offering.id, + networkids=self.network.id + ) + self.cleanup.append(vm) + return vm @skipTestIf("nfsKvmNotAvailable") @attr(tags=["advanced", "basic", "eip", "advancedns", "sg"], required_hardware="false") @@ -282,12 +298,7 @@ def test_01_deploy_vm_from_direct_download_template_nfs_storage(self): self.updateStoragePoolTags(self.nfsPoolId, test_tag) nfs_storage_offering = self.createServiceOffering("TestNFSStorageDirectDownload", "shared", test_tag) - vm = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - serviceofferingid=nfs_storage_offering.id, - networkids=self.l2_network.id - ) + vm = self.deployVM(nfs_storage_offering) self.assertEqual( vm.state, "Running", @@ -296,7 +307,6 @@ def test_01_deploy_vm_from_direct_download_template_nfs_storage(self): # Revert storage tags for the storage pool used in this test self.updateStoragePoolTags(self.nfsPoolId, tags) - self.cleanup.append(vm) self.cleanup.append(nfs_storage_offering) return @@ -313,12 +323,7 @@ def test_02_deploy_vm_from_direct_download_template_local_storage(self): local_storage_offering = self.createServiceOffering("TestLocalStorageDirectDownload", "local", test_tag) # Deploy VM - vm = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - serviceofferingid=local_storage_offering.id, - networkids=self.l2_network.id, - ) + vm = self.deployVM(local_storage_offering) self.assertEqual( vm.state, "Running", @@ -327,7 +332,6 @@ def test_02_deploy_vm_from_direct_download_template_local_storage(self): # Revert storage tags for the storage pool used in this test self.updateStoragePoolTags(self.localPoolId, tags) - self.cleanup.append(vm) self.cleanup.append(local_storage_offering) return diff --git a/test/integration/smoke/test_domain_network_offerings.py b/test/integration/smoke/test_domain_network_offerings.py index 0bab9a12c1d6..d2d6120697f4 100644 --- a/test/integration/smoke/test_domain_network_offerings.py +++ b/test/integration/smoke/test_domain_network_offerings.py @@ -274,7 +274,6 @@ def test_02_edit_network_offering(self): @attr( tags=[ "advanced", - "basic", "eip", "sg", "advancedns", diff --git a/test/integration/smoke/test_domain_vpc_offerings.py b/test/integration/smoke/test_domain_vpc_offerings.py index 928c24accb73..f3d31b2bf7e9 100644 --- a/test/integration/smoke/test_domain_vpc_offerings.py +++ b/test/integration/smoke/test_domain_vpc_offerings.py @@ -319,7 +319,6 @@ def test_02_edit_vpc_offering(self): @attr( tags=[ "advanced", - "basic", "eip", "sg", "advancedns", diff --git a/test/integration/smoke/test_primary_storage.py b/test/integration/smoke/test_primary_storage.py index 7c0a9487af67..4e630b70a78d 100644 --- a/test/integration/smoke/test_primary_storage.py +++ b/test/integration/smoke/test_primary_storage.py @@ -256,6 +256,9 @@ def test_01_add_primary_storage_disabled_host(self): """Test add primary storage pool with disabled host """ + if self.zone.localstorageenabled : + self.skipTest("Skipping since localstorageenabled") + # Disable a host clusters = list_clusters( self.apiclient, diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index d6a78907ad5d..61b3a22a6c8e 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -613,6 +613,9 @@ def test_08_migrate_vm(self): # 2. DeployVM on suitable host (with another host in the cluster) # 3. Migrate the VM and assert migration successful + if self.zone.localstorageenabled : + self.skipTest("Migration is not supported on zones with local storage") + suitable_hosts = None hosts = Host.list( From 0d72886ee310271272f8d51f435131a5e7401b6d Mon Sep 17 00:00:00 2001 From: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com> Date: Thu, 1 Jul 2021 10:12:59 +0530 Subject: [PATCH 054/120] Replace the DB properties having master and slave(s), with source and replica(s) respectively, on Upgrade for inclusiveness (#5162) Updates the DB properties (with strict / full property string search) having master and slave(s), with source and replica(s) respectively on upgrade (for inclusiveness). Signed-off-by: Suresh Kumar Anaparti --- debian/cloudstack-management.postinst | 8 ++++++++ packaging/centos7/cloud.spec | 8 ++++++++ packaging/centos8/cloud.spec | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/debian/cloudstack-management.postinst b/debian/cloudstack-management.postinst index 2cc3b9b7b533..e3dd52821a59 100755 --- a/debian/cloudstack-management.postinst +++ b/debian/cloudstack-management.postinst @@ -63,6 +63,14 @@ if [ "$1" = configure ]; then grep -s -q "db.cloud.driver=jdbc:mysql" ${CONFDIR}/${DBPROPS} || sed -i -e "\$adb.cloud.driver=jdbc:mysql" ${CONFDIR}/${DBPROPS} grep -s -q "db.usage.driver=jdbc:mysql" ${CONFDIR}/${DBPROPS} || sed -i -e "\$adb.usage.driver=jdbc:mysql" ${CONFDIR}/${DBPROPS} grep -s -q "db.simulator.driver=jdbc:mysql" ${CONFDIR}/${DBPROPS} || sed -i -e "\$adb.simulator.driver=jdbc:mysql" ${CONFDIR}/${DBPROPS} + + # Update DB properties having master and slave(s), with source and replica(s) respectively (for inclusiveness) + grep -s -q "^db.cloud.slaves=" ${CONFDIR}/${DBPROPS} && sed -i "s/^db.cloud.slaves=/db.cloud.replicas=/g" ${CONFDIR}/${DBPROPS} + grep -s -q "^db.cloud.secondsBeforeRetryMaster=" ${CONFDIR}/${DBPROPS} && sed -i "s/^db.cloud.secondsBeforeRetryMaster=/db.cloud.secondsBeforeRetrySource=/g" ${CONFDIR}/${DBPROPS} + grep -s -q "^db.cloud.queriesBeforeRetryMaster=" ${CONFDIR}/${DBPROPS} && sed -i "s/^db.cloud.queriesBeforeRetryMaster=/db.cloud.queriesBeforeRetrySource=/g" ${CONFDIR}/${DBPROPS} + grep -s -q "^db.usage.slaves=" ${CONFDIR}/${DBPROPS} && sed -i "s/^db.usage.slaves=/db.usage.replicas=/g" ${CONFDIR}/${DBPROPS} + grep -s -q "^db.usage.secondsBeforeRetryMaster=" ${CONFDIR}/${DBPROPS} && sed -i "s/^db.usage.secondsBeforeRetryMaster=/db.usage.secondsBeforeRetrySource=/g" ${CONFDIR}/${DBPROPS} + grep -s -q "^db.usage.queriesBeforeRetryMaster=" ${CONFDIR}/${DBPROPS} && sed -i "s/^db.usage.queriesBeforeRetryMaster=/db.usage.queriesBeforeRetrySource=/g" ${CONFDIR}/${DBPROPS} fi #DEBHELPER# diff --git a/packaging/centos7/cloud.spec b/packaging/centos7/cloud.spec index 737ecd256d6b..b1b69b7549de 100644 --- a/packaging/centos7/cloud.spec +++ b/packaging/centos7/cloud.spec @@ -432,6 +432,14 @@ grep -s -q "db.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.pr grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" grep -s -q "db.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" +# Update DB properties having master and slave(s), with source and replica(s) respectively (for inclusiveness) +grep -s -q "^db.cloud.slaves=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.slaves=/db.cloud.replicas=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.cloud.secondsBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.secondsBeforeRetryMaster=/db.cloud.secondsBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.cloud.queriesBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.queriesBeforeRetryMaster=/db.cloud.queriesBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.usage.slaves=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.slaves=/db.usage.replicas=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.usage.secondsBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.secondsBeforeRetryMaster=/db.usage.secondsBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.usage.queriesBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.queriesBeforeRetryMaster=/db.usage.queriesBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties" + if [ ! -f %{_datadir}/cloudstack-common/scripts/vm/hypervisor/xenserver/vhd-util ] ; then echo Please download vhd-util from http://download.cloudstack.org/tools/vhd-util and put it in echo %{_datadir}/cloudstack-common/scripts/vm/hypervisor/xenserver/ diff --git a/packaging/centos8/cloud.spec b/packaging/centos8/cloud.spec index 350b9d83a60f..9e62691782f9 100644 --- a/packaging/centos8/cloud.spec +++ b/packaging/centos8/cloud.spec @@ -423,6 +423,14 @@ grep -s -q "db.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.pr grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" grep -s -q "db.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" +# Update DB properties having master and slave(s), with source and replica(s) respectively (for inclusiveness) +grep -s -q "^db.cloud.slaves=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.slaves=/db.cloud.replicas=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.cloud.secondsBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.secondsBeforeRetryMaster=/db.cloud.secondsBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.cloud.queriesBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.cloud.queriesBeforeRetryMaster=/db.cloud.queriesBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.usage.slaves=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.slaves=/db.usage.replicas=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.usage.secondsBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.secondsBeforeRetryMaster=/db.usage.secondsBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties" +grep -s -q "^db.usage.queriesBeforeRetryMaster=" "%{_sysconfdir}/%{name}/management/db.properties" && sed -i "s/^db.usage.queriesBeforeRetryMaster=/db.usage.queriesBeforeRetrySource=/g" "%{_sysconfdir}/%{name}/management/db.properties" + if [ ! -f %{_datadir}/cloudstack-common/scripts/vm/hypervisor/xenserver/vhd-util ] ; then echo Please download vhd-util from http://download.cloudstack.org/tools/vhd-util and put it in echo %{_datadir}/cloudstack-common/scripts/vm/hypervisor/xenserver/ From 9ee6a57311562c89ab90d524bb63d4769c655465 Mon Sep 17 00:00:00 2001 From: davidjumani Date: Thu, 1 Jul 2021 15:58:39 +0530 Subject: [PATCH 055/120] ui: deployvm - Add option to stay on page (#4843) * ui: deployvm - Add option to stay on page * Moving option to a dropdown --- ui/public/locales/en.json | 1 + ui/src/views/compute/DeployVM.vue | 31 ++++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index cd07ee2f25b5..bab3f4daac36 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -1218,6 +1218,7 @@ "label.latest.events": "Latest events", "label.launch": "Launch", "label.launch.vm": "Launch Virtual Machine", +"label.launch.vm.and.stay": "Launch VM & Stay On This Page", "label.launch.zone": "Launch Zone", "label.lb.algorithm.leastconn": "Least connections", "label.lb.algorithm.roundrobin": "Round-robin", diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index 16abfa80aa3a..a7a9ebbdbfd2 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -600,14 +600,27 @@ @@ -1362,6 +1375,15 @@ export default { getText (option) { return _.get(option, 'displaytext', _.get(option, 'name')) }, + handleSubmitAndStay (e) { + this.form.setFieldsValue({ + stayonpage: true + }) + this.handleSubmit(e.domEvent) + this.form.setFieldsValue({ + stayonpage: false + }) + }, handleSubmit (e) { console.log('wizard submit') e.preventDefault() @@ -1585,9 +1607,12 @@ export default { new Promise(resolve => setTimeout(resolve, 3000)).then(() => { eventBus.$emit('vm-refresh-data') }) - this.$router.back() + if (!values.stayonpage) { + this.$router.back() + } }).catch(error => { this.$notifyError(error) + }).finally(() => { this.loading.deploy = false }) }) From 5fd970d88f25a7b4be01b4f6eb8b0421088b83a3 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 1 Jul 2021 19:30:51 +0530 Subject: [PATCH 056/120] db, server: refactor host_view to prevent duplicate entries (#4796) Signed-off-by: Abhishek Kumar --- .../META-INF/db/schema-41510to41600.sql | 92 +++++++++++++++++++ .../main/java/com/cloud/api/ApiDBUtils.java | 8 -- .../cloud/api/query/ViewResponseHelper.java | 18 +--- .../com/cloud/api/query/dao/HostJoinDao.java | 4 - .../cloud/api/query/dao/HostJoinDaoImpl.java | 69 +++----------- 5 files changed, 109 insertions(+), 82 deletions(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql b/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql index 2e1a592ced5b..ad13853fc1f4 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql @@ -419,3 +419,95 @@ DROP TABLE IF EXISTS `cloud`.`swift`; ALTER TABLE `cloud`.`snapshots` DROP FOREIGN KEY `fk_snapshots__s3_id` ; ALTER TABLE `cloud`.`snapshots` DROP COLUMN `s3_id` ; DROP TABLE IF EXISTS `cloud`.`s3`; + +-- Re-create host view to prevent multiple entries for hosts with multiple tags +DROP VIEW IF EXISTS `cloud`.`host_view`; +CREATE VIEW `cloud`.`host_view` AS + SELECT + host.id, + host.uuid, + host.name, + host.status, + host.disconnected, + host.type, + host.private_ip_address, + host.version, + host.hypervisor_type, + host.hypervisor_version, + host.capabilities, + host.last_ping, + host.created, + host.removed, + host.resource_state, + host.mgmt_server_id, + host.cpu_sockets, + host.cpus, + host.speed, + host.ram, + cluster.id cluster_id, + cluster.uuid cluster_uuid, + cluster.name cluster_name, + cluster.cluster_type, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + data_center.networktype data_center_type, + host_pod_ref.id pod_id, + host_pod_ref.uuid pod_uuid, + host_pod_ref.name pod_name, + GROUP_CONCAT(DISTINCT(host_tags.tag)) AS tag, + guest_os_category.id guest_os_category_id, + guest_os_category.uuid guest_os_category_uuid, + guest_os_category.name guest_os_category_name, + mem_caps.used_capacity memory_used_capacity, + mem_caps.reserved_capacity memory_reserved_capacity, + cpu_caps.used_capacity cpu_used_capacity, + cpu_caps.reserved_capacity cpu_reserved_capacity, + async_job.id job_id, + async_job.uuid job_uuid, + async_job.job_status job_status, + async_job.account_id job_account_id, + oobm.enabled AS `oobm_enabled`, + oobm.power_state AS `oobm_power_state`, + ha_config.enabled AS `ha_enabled`, + ha_config.ha_state AS `ha_state`, + ha_config.provider AS `ha_provider`, + `last_annotation_view`.`annotation` AS `annotation`, + `last_annotation_view`.`created` AS `last_annotated`, + `user`.`username` AS `username` + FROM + `cloud`.`host` + LEFT JOIN + `cloud`.`cluster` ON host.cluster_id = cluster.id + LEFT JOIN + `cloud`.`data_center` ON host.data_center_id = data_center.id + LEFT JOIN + `cloud`.`host_pod_ref` ON host.pod_id = host_pod_ref.id + LEFT JOIN + `cloud`.`host_details` ON host.id = host_details.host_id + AND host_details.name = 'guest.os.category.id' + LEFT JOIN + `cloud`.`guest_os_category` ON guest_os_category.id = CONVERT ( host_details.value, UNSIGNED ) + LEFT JOIN + `cloud`.`host_tags` ON host_tags.host_id = host.id + LEFT JOIN + `cloud`.`op_host_capacity` mem_caps ON host.id = mem_caps.host_id + AND mem_caps.capacity_type = 0 + LEFT JOIN + `cloud`.`op_host_capacity` cpu_caps ON host.id = cpu_caps.host_id + AND cpu_caps.capacity_type = 1 + LEFT JOIN + `cloud`.`async_job` ON async_job.instance_id = host.id + AND async_job.instance_type = 'Host' + AND async_job.job_status = 0 + LEFT JOIN + `cloud`.`oobm` ON oobm.host_id = host.id + left join + `cloud`.`ha_config` ON ha_config.resource_id=host.id + and ha_config.resource_type='Host' + LEFT JOIN + `cloud`.`last_annotation_view` ON `last_annotation_view`.`entity_uuid` = `host`.`uuid` + LEFT JOIN + `cloud`.`user` ON `user`.`uuid` = `last_annotation_view`.`user_uuid` + GROUP BY + `host`.`id`; diff --git a/server/src/main/java/com/cloud/api/ApiDBUtils.java b/server/src/main/java/com/cloud/api/ApiDBUtils.java index 91af895870df..d688c276a338 100644 --- a/server/src/main/java/com/cloud/api/ApiDBUtils.java +++ b/server/src/main/java/com/cloud/api/ApiDBUtils.java @@ -1891,18 +1891,10 @@ public static HostResponse newHostResponse(HostJoinVO vr, EnumSet d return s_hostJoinDao.newHostResponse(vr, details); } - public static HostResponse fillHostDetails(HostResponse vrData, HostJoinVO vr) { - return s_hostJoinDao.setHostResponse(vrData, vr); - } - public static HostForMigrationResponse newHostForMigrationResponse(HostJoinVO vr, EnumSet details) { return s_hostJoinDao.newHostForMigrationResponse(vr, details); } - public static HostForMigrationResponse fillHostForMigrationDetails(HostForMigrationResponse vrData, HostJoinVO vr) { - return s_hostJoinDao.setHostForMigrationResponse(vrData, vr); - } - public static List newHostView(Host vr) { return s_hostJoinDao.newHostView(vr); } diff --git a/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java index 1067ff2ed472..ec3397407f20 100644 --- a/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java @@ -242,14 +242,7 @@ public static List createHostResponse(EnumSet details Hashtable vrDataList = new Hashtable(); // Initialise the vrdatalist with the input data for (HostJoinVO vr : hosts) { - HostResponse vrData = vrDataList.get(vr.getId()); - if (vrData == null) { - // first time encountering this vm - vrData = ApiDBUtils.newHostResponse(vr, details); - } else { - // update tags - vrData = ApiDBUtils.fillHostDetails(vrData, vr); - } + HostResponse vrData = ApiDBUtils.newHostResponse(vr, details); vrDataList.put(vr.getId(), vrData); } return new ArrayList(vrDataList.values()); @@ -259,14 +252,7 @@ public static List createHostForMigrationResponse(Enum Hashtable vrDataList = new Hashtable(); // Initialise the vrdatalist with the input data for (HostJoinVO vr : hosts) { - HostForMigrationResponse vrData = vrDataList.get(vr.getId()); - if (vrData == null) { - // first time encountering this vm - vrData = ApiDBUtils.newHostForMigrationResponse(vr, details); - } else { - // update tags - vrData = ApiDBUtils.fillHostForMigrationDetails(vrData, vr); - } + HostForMigrationResponse vrData = ApiDBUtils.newHostForMigrationResponse(vr, details); vrDataList.put(vr.getId(), vrData); } return new ArrayList(vrDataList.values()); diff --git a/server/src/main/java/com/cloud/api/query/dao/HostJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/HostJoinDao.java index e7dc5d5ff046..e7ad5e53862a 100644 --- a/server/src/main/java/com/cloud/api/query/dao/HostJoinDao.java +++ b/server/src/main/java/com/cloud/api/query/dao/HostJoinDao.java @@ -31,12 +31,8 @@ public interface HostJoinDao extends GenericDao { HostResponse newHostResponse(HostJoinVO host, EnumSet details); - HostResponse setHostResponse(HostResponse response, HostJoinVO host); - HostForMigrationResponse newHostForMigrationResponse(HostJoinVO host, EnumSet details); - HostForMigrationResponse setHostForMigrationResponse(HostForMigrationResponse response, HostJoinVO host); - List newHostView(Host group); List searchByIds(Long... ids); diff --git a/server/src/main/java/com/cloud/api/query/dao/HostJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/HostJoinDaoImpl.java index 32236093f03c..af392a254022 100644 --- a/server/src/main/java/com/cloud/api/query/dao/HostJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/HostJoinDaoImpl.java @@ -18,6 +18,7 @@ import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.EnumSet; import java.util.Iterator; @@ -93,6 +94,18 @@ protected HostJoinDaoImpl() { this._count = "select count(distinct id) from host_view WHERE "; } + private boolean containsHostHATag(final String tags) { + boolean result = false; + String haTag = ApiDBUtils.getHaTag(); + if (StringUtils.isNotEmpty(haTag) && StringUtils.isNotEmpty(tags)) { + List tagsList = Arrays.asList(tags.split(",")); + if (tagsList.contains(haTag)) { + result = true; + } + } + return result; + } + @Override public HostResponse newHostResponse(HostJoinVO host, EnumSet details) { HostResponse hostResponse = new HostResponse(); @@ -180,13 +193,7 @@ public HostResponse newHostResponse(HostJoinVO host, EnumSet detail String hostTags = host.getTag(); hostResponse.setHostTags(hostTags); - - hostResponse.setHaHost(false); - String haTag = ApiDBUtils.getHaTag(); - if (StringUtils.isNotEmpty(haTag) && StringUtils.isNotEmpty(hostTags) && - haTag.equalsIgnoreCase(hostTags)) { - hostResponse.setHaHost(true); - } + hostResponse.setHaHost(containsHostHATag(hostTags)); hostResponse.setHypervisorVersion(host.getHypervisorVersion()); @@ -268,26 +275,6 @@ public HostResponse newHostResponse(HostJoinVO host, EnumSet detail return hostResponse; } - @Override - public HostResponse setHostResponse(HostResponse response, HostJoinVO host) { - String tag = host.getTag(); - if (StringUtils.isNotEmpty(tag)) { - if (StringUtils.isNotEmpty(response.getHostTags())) { - response.setHostTags(response.getHostTags() + "," + tag); - } else { - response.setHostTags(tag); - } - - if (Boolean.FALSE.equals(response.getHaHost())) { - String haTag = ApiDBUtils.getHaTag(); - if (StringUtils.isNotEmpty(haTag) && haTag.equalsIgnoreCase(tag)) { - response.setHaHost(true); - } - } - } - return response; - } - @Override public HostForMigrationResponse newHostForMigrationResponse(HostJoinVO host, EnumSet details) { HostForMigrationResponse hostResponse = new HostForMigrationResponse(); @@ -339,13 +326,7 @@ public HostForMigrationResponse newHostForMigrationResponse(HostJoinVO host, Enu String hostTags = host.getTag(); hostResponse.setHostTags(hostTags); - - hostResponse.setHaHost(false); - String haTag = ApiDBUtils.getHaTag(); - if (StringUtils.isNotEmpty(haTag) && StringUtils.isNotEmpty(hostTags) && - haTag.equalsIgnoreCase(hostTags)) { - hostResponse.setHaHost(true); - } + hostResponse.setHaHost(containsHostHATag(hostTags)); hostResponse.setHypervisorVersion(host.getHypervisorVersion()); @@ -410,26 +391,6 @@ public HostForMigrationResponse newHostForMigrationResponse(HostJoinVO host, Enu return hostResponse; } - @Override - public HostForMigrationResponse setHostForMigrationResponse(HostForMigrationResponse response, HostJoinVO host) { - String tag = host.getTag(); - if (tag != null) { - if (response.getHostTags() != null && response.getHostTags().length() > 0) { - response.setHostTags(response.getHostTags() + "," + tag); - } else { - response.setHostTags(tag); - } - - if (Boolean.FALSE.equals(response.getHaHost())) { - String haTag = ApiDBUtils.getHaTag(); - if (StringUtils.isNotEmpty(haTag) && haTag.equalsIgnoreCase(tag)) { - response.setHaHost(true); - } - } - } - return response; - } - @Override public List newHostView(Host host) { SearchCriteria sc = hostIdSearch.create(); From 293dd4d8efd56d753e714af684469c69ee50c505 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Thu, 1 Jul 2021 19:49:41 +0530 Subject: [PATCH 057/120] volume: Fix deletion of Uploaded volumes (#5125) Fixes issue with deletion of Uploaded volumes --- .../java/com/cloud/storage/VolumeApiServiceImpl.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 0bd0861ec43e..b9fa40c4633b 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -23,9 +23,11 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -306,6 +308,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic private long _maxVolumeSizeInGb; private final StateMachine2 _volStateMachine; + private static final Set STATES_VOLUME_CANNOT_BE_DESTROYED = new HashSet<>(Arrays.asList(Volume.State.Destroy, Volume.State.Expunging, Volume.State.Expunged, Volume.State.Allocated)); + protected VolumeApiServiceImpl() { _volStateMachine = Volume.State.getStateMachine(); _gson = GsonHelper.getGsonLogger(); @@ -1451,13 +1455,14 @@ protected VolumeVO retrieveAndValidateVolume(long volumeId, Account caller) { *
    *
  • {@value Volume.State#Destroy}; *
  • {@value Volume.State#Expunging}; - *
  • {@value Volume.State#Expunged}. + *
  • {@value Volume.State#Expunged}; + *
  • {@value Volume.State#Allocated}. *
* * The volume is destroyed via {@link VolumeService#destroyVolume(long)} method. */ protected void destroyVolumeIfPossible(VolumeVO volume) { - if (volume.getState() != Volume.State.Destroy && volume.getState() != Volume.State.Expunging && volume.getState() != Volume.State.Expunged && volume.getState() != Volume.State.Allocated && volume.getState() != Volume.State.Uploaded) { + if (!STATES_VOLUME_CANNOT_BE_DESTROYED.contains(volume.getState())) { volService.destroyVolume(volume.getId()); } } From 7bef87f11dac1585b5d208801305e5494009416d Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 2 Jul 2021 02:22:53 -0400 Subject: [PATCH 058/120] template zone addition code --- .../java/com/cloud/template/TemplateManagerImpl.java | 9 ++++++--- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 6d7fc7b2ca23..639f8468aaaa 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1789,12 +1789,13 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template _accountMgr.checkAccess(caller, null, true, templateOwner); String name = cmd.getTemplateName(); if (name.length() > 32) { - name = name.substring(5) + "-QA"; + name = name.substring(5) + "-QA-Clone"; } - int bits = 64; // where to specify boolean featured = false; boolean isPublic = cmd.isPublic(); + UserVm curVm = cmd.getTargetVM(); + long zoneId = curVm.getDataCenterId(); Long volumeId = _volumeDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT).get(0).getId(); HypervisorType hyperType = null; VolumeVO volume = _volumeDao.findById(volumeId); @@ -1853,8 +1854,10 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template } privateTemplate.setSourceTemplateId(sourceTemplateId); - VMTemplateVO template = _tmpltDao.persist(privateTemplate); + // persist this to the template zone area and remember to remove the resource count in the execute phase once in failure or clean up phase + VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, template.getId(), new Date()); + _tmpltZoneDao.persist(templateZone); // Increment the number of templates if (template != null) { Map details = new HashMap(); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 224f9f6ed38e..037b8461f5a7 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5626,6 +5626,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio if (groupVo != null) { group = groupVo.getName(); } + UserVm vmResult = createBasicSecurityGroupVirtualMachine(dataCenter, serviceOffering, template, securityGroupIdList, curAccount, hostName, displayName, diskOfferingId, size , group , hypervisorType, cmd.getHttpMethod(), userData , sshKeyPair , ipToNetoworkMap, addr, isDisplayVM , keyboard , null, curVm.getDetails() == null ? new HashMap<>() : curVm.getDetails(), cmd.getCustomId(), new HashMap<>(), From d15f6207fa64d120a39b50b6c2d4e1b1c6d7eeb1 Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 2 Jul 2021 02:25:54 -0400 Subject: [PATCH 059/120] trail-issue-1 --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 037b8461f5a7..224f9f6ed38e 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5626,7 +5626,6 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio if (groupVo != null) { group = groupVo.getName(); } - UserVm vmResult = createBasicSecurityGroupVirtualMachine(dataCenter, serviceOffering, template, securityGroupIdList, curAccount, hostName, displayName, diskOfferingId, size , group , hypervisorType, cmd.getHttpMethod(), userData , sshKeyPair , ipToNetoworkMap, addr, isDisplayVM , keyboard , null, curVm.getDetails() == null ? new HashMap<>() : curVm.getDetails(), cmd.getCustomId(), new HashMap<>(), From fee4a95a016a1b3fe410f103afdc41405375e4fb Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 2 Jul 2021 03:08:22 -0400 Subject: [PATCH 060/120] change test ip address --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 224f9f6ed38e..06399bd130bd 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5599,7 +5599,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio String ipv6Address = null; String macAddress = null; // IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); - IpAddresses addr = new IpAddresses("127.20.0.183", ipv6Address, macAddress); + IpAddresses addr = new IpAddresses("60.147.41.98", ipv6Address, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); From f81d79da8e2c1bbd484e2a35c643b212f7694b9f Mon Sep 17 00:00:00 2001 From: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com> Date: Fri, 2 Jul 2021 16:48:33 +0530 Subject: [PATCH 061/120] Updated some offensive words in kubernetes plugin/service with inclusive words/terms. (#5171) --- ...esClusterResourceModifierActionWorker.java | 4 +- .../KubernetesClusterStartWorker.java | 92 +++++++++---------- .../response/KubernetesClusterResponse.java | 4 +- .../resources/conf/k8s-control-node-add.yml | 4 +- .../main/resources/conf/k8s-control-node.yml | 8 +- .../src/main/resources/conf/k8s-node.yml | 4 +- ui/src/config/section/compute.js | 2 +- 7 files changed, 59 insertions(+), 59 deletions(-) diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java index 28f925915c95..e60807ec56d7 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java @@ -142,8 +142,8 @@ protected void init() { private String getKubernetesNodeConfig(final String joinIp, final boolean ejectIso) throws IOException { String k8sNodeConfig = readResourceFile("/conf/k8s-node.yml"); final String sshPubKey = "{{ k8s.ssh.pub.key }}"; - final String joinIpKey = "{{ k8s_master.join_ip }}"; - final String clusterTokenKey = "{{ k8s_master.cluster.token }}"; + final String joinIpKey = "{{ k8s_control_node.join_ip }}"; + final String clusterTokenKey = "{{ k8s_control_node.cluster.token }}"; final String ejectIsoKey = "{{ k8s.eject.iso }}"; String pubKey = "- \"" + configurationDao.getValue("ssh.publickey") + "\""; String sshKeyPair = kubernetesCluster.getKeyPair(); diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java index c6f939cf4269..9a30fdd82357 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java +++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterStartWorker.java @@ -89,8 +89,8 @@ public KubernetesSupportedVersion getKubernetesClusterVersion() { return kubernetesClusterVersion; } - private Pair> getKubernetesControlIpAddresses(final DataCenter zone, final Network network, final Account account) throws InsufficientAddressCapacityException { - String controlIp = null; + private Pair> getKubernetesControlNodeIpAddresses(final DataCenter zone, final Network network, final Account account) throws InsufficientAddressCapacityException { + String controlNodeIp = null; Map requestedIps = null; if (Network.GuestType.Shared.equals(network.getGuestType())) { List vlanIds = new ArrayList<>(); @@ -100,16 +100,16 @@ private Pair> getKubernetesControlIpAddre } PublicIp ip = ipAddressManager.getAvailablePublicIpAddressFromVlans(zone.getId(), null, account, Vlan.VlanType.DirectAttached, vlanIds,network.getId(), null, false); if (ip != null) { - controlIp = ip.getAddress().toString(); + controlNodeIp = ip.getAddress().toString(); } requestedIps = new HashMap<>(); Ip ipAddress = ip.getAddress(); boolean isIp6 = ipAddress.isIp6(); requestedIps.put(network.getId(), new Network.IpAddresses(ipAddress.isIp4() ? ip.getAddress().addr() : null, null)); } else { - controlIp = ipAddressManager.acquireGuestIpAddress(networkDao.findById(kubernetesCluster.getNetworkId()), null); + controlNodeIp = ipAddressManager.acquireGuestIpAddress(networkDao.findById(kubernetesCluster.getNetworkId()), null); } - return new Pair<>(controlIp, requestedIps); + return new Pair<>(controlNodeIp, requestedIps); } private boolean isKubernetesVersionSupportsHA() { @@ -127,20 +127,20 @@ private boolean isKubernetesVersionSupportsHA() { return haSupported; } - private String getKubernetesControlConfig(final String controlIp, final String serverIp, - final String hostName, final boolean haSupported, - final boolean ejectIso) throws IOException { - String k8sControlConfig = readResourceFile("/conf/k8s-control-node.yml"); - final String apiServerCert = "{{ k8s_master.apiserver.crt }}"; - final String apiServerKey = "{{ k8s_master.apiserver.key }}"; - final String caCert = "{{ k8s_master.ca.crt }}"; + private String getKubernetesControlNodeConfig(final String controlNodeIp, final String serverIp, + final String hostName, final boolean haSupported, + final boolean ejectIso) throws IOException { + String k8sControlNodeConfig = readResourceFile("/conf/k8s-control-node.yml"); + final String apiServerCert = "{{ k8s_control_node.apiserver.crt }}"; + final String apiServerKey = "{{ k8s_control_node.apiserver.key }}"; + final String caCert = "{{ k8s_control_node.ca.crt }}"; final String sshPubKey = "{{ k8s.ssh.pub.key }}"; - final String clusterToken = "{{ k8s_master.cluster.token }}"; - final String clusterInitArgsKey = "{{ k8s_master.cluster.initargs }}"; + final String clusterToken = "{{ k8s_control_node.cluster.token }}"; + final String clusterInitArgsKey = "{{ k8s_control_node.cluster.initargs }}"; final String ejectIsoKey = "{{ k8s.eject.iso }}"; final List addresses = new ArrayList<>(); - addresses.add(controlIp); - if (!serverIp.equals(controlIp)) { + addresses.add(controlNodeIp); + if (!serverIp.equals(controlNodeIp)) { addresses.add(serverIp); } final Certificate certificate = caManager.issueCertificate(null, Arrays.asList(hostName, "kubernetes", @@ -149,9 +149,9 @@ private String getKubernetesControlConfig(final String controlIp, final String s final String tlsClientCert = CertUtils.x509CertificateToPem(certificate.getClientCertificate()); final String tlsPrivateKey = CertUtils.privateKeyToPem(certificate.getPrivateKey()); final String tlsCaCert = CertUtils.x509CertificatesToPem(certificate.getCaCertificates()); - k8sControlConfig = k8sControlConfig.replace(apiServerCert, tlsClientCert.replace("\n", "\n ")); - k8sControlConfig = k8sControlConfig.replace(apiServerKey, tlsPrivateKey.replace("\n", "\n ")); - k8sControlConfig = k8sControlConfig.replace(caCert, tlsCaCert.replace("\n", "\n ")); + k8sControlNodeConfig = k8sControlNodeConfig.replace(apiServerCert, tlsClientCert.replace("\n", "\n ")); + k8sControlNodeConfig = k8sControlNodeConfig.replace(apiServerKey, tlsPrivateKey.replace("\n", "\n ")); + k8sControlNodeConfig = k8sControlNodeConfig.replace(caCert, tlsCaCert.replace("\n", "\n ")); String pubKey = "- \"" + configurationDao.getValue("ssh.publickey") + "\""; String sshKeyPair = kubernetesCluster.getKeyPair(); if (!Strings.isNullOrEmpty(sshKeyPair)) { @@ -160,8 +160,8 @@ private String getKubernetesControlConfig(final String controlIp, final String s pubKey += "\n - \"" + sshkp.getPublicKey() + "\""; } } - k8sControlConfig = k8sControlConfig.replace(sshPubKey, pubKey); - k8sControlConfig = k8sControlConfig.replace(clusterToken, KubernetesClusterUtil.generateClusterToken(kubernetesCluster)); + k8sControlNodeConfig = k8sControlNodeConfig.replace(sshPubKey, pubKey); + k8sControlNodeConfig = k8sControlNodeConfig.replace(clusterToken, KubernetesClusterUtil.generateClusterToken(kubernetesCluster)); String initArgs = ""; if (haSupported) { initArgs = String.format("--control-plane-endpoint %s:%d --upload-certs --certificate-key %s ", @@ -171,9 +171,9 @@ private String getKubernetesControlConfig(final String controlIp, final String s } initArgs += String.format("--apiserver-cert-extra-sans=%s", serverIp); initArgs += String.format(" --kubernetes-version=%s", getKubernetesClusterVersion().getSemanticVersion()); - k8sControlConfig = k8sControlConfig.replace(clusterInitArgsKey, initArgs); - k8sControlConfig = k8sControlConfig.replace(ejectIsoKey, String.valueOf(ejectIso)); - return k8sControlConfig; + k8sControlNodeConfig = k8sControlNodeConfig.replace(clusterInitArgsKey, initArgs); + k8sControlNodeConfig = k8sControlNodeConfig.replace(ejectIsoKey, String.valueOf(ejectIso)); + return k8sControlNodeConfig; } private UserVm createKubernetesControlNode(final Network network, String serverIp) throws ManagementServerException, @@ -183,13 +183,13 @@ private UserVm createKubernetesControlNode(final Network network, String serverI ServiceOffering serviceOffering = serviceOfferingDao.findById(kubernetesCluster.getServiceOfferingId()); List networkIds = new ArrayList(); networkIds.add(kubernetesCluster.getNetworkId()); - Pair> ipAddresses = getKubernetesControlIpAddresses(zone, network, owner); - String controlIp = ipAddresses.first(); + Pair> ipAddresses = getKubernetesControlNodeIpAddresses(zone, network, owner); + String controlNodeIp = ipAddresses.first(); Map requestedIps = ipAddresses.second(); if (Network.GuestType.Shared.equals(network.getGuestType()) && Strings.isNullOrEmpty(serverIp)) { - serverIp = controlIp; + serverIp = controlNodeIp; } - Network.IpAddresses addrs = new Network.IpAddresses(controlIp, null); + Network.IpAddresses addrs = new Network.IpAddresses(controlNodeIp, null); long rootDiskSize = kubernetesCluster.getNodeRootDiskSize(); Map customParameterMap = new HashMap(); if (rootDiskSize > 0) { @@ -201,13 +201,13 @@ private UserVm createKubernetesControlNode(final Network network, String serverI } hostName = getKubernetesClusterNodeAvailableName(hostName); boolean haSupported = isKubernetesVersionSupportsHA(); - String k8sControlConfig = null; + String k8sControlNodeConfig = null; try { - k8sControlConfig = getKubernetesControlConfig(controlIp, serverIp, hostName, haSupported, Hypervisor.HypervisorType.VMware.equals(clusterTemplate.getHypervisorType())); + k8sControlNodeConfig = getKubernetesControlNodeConfig(controlNodeIp, serverIp, hostName, haSupported, Hypervisor.HypervisorType.VMware.equals(clusterTemplate.getHypervisorType())); } catch (IOException e) { - logAndThrow(Level.ERROR, "Failed to read Kubernetes control configuration file", e); + logAndThrow(Level.ERROR, "Failed to read Kubernetes control node configuration file", e); } - String base64UserData = Base64.encodeBase64String(k8sControlConfig.getBytes(StringUtils.getPreferredCharset())); + String base64UserData = Base64.encodeBase64String(k8sControlNodeConfig.getBytes(StringUtils.getPreferredCharset())); controlVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner, hostName, hostName, null, null, null, Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(), @@ -218,12 +218,12 @@ private UserVm createKubernetesControlNode(final Network network, String serverI return controlVm; } - private String getKubernetesAdditionalControlConfig(final String joinIp, final boolean ejectIso) throws IOException { - String k8sControlConfig = readResourceFile("/conf/k8s-control-node-add.yml"); - final String joinIpKey = "{{ k8s_master.join_ip }}"; - final String clusterTokenKey = "{{ k8s_master.cluster.token }}"; + private String getKubernetesAdditionalControlNodeConfig(final String joinIp, final boolean ejectIso) throws IOException { + String k8sControlNodeConfig = readResourceFile("/conf/k8s-control-node-add.yml"); + final String joinIpKey = "{{ k8s_control_node.join_ip }}"; + final String clusterTokenKey = "{{ k8s_control_node.cluster.token }}"; final String sshPubKey = "{{ k8s.ssh.pub.key }}"; - final String clusterHACertificateKey = "{{ k8s_master.cluster.ha.certificate.key }}"; + final String clusterHACertificateKey = "{{ k8s_control_node.cluster.ha.certificate.key }}"; final String ejectIsoKey = "{{ k8s.eject.iso }}"; String pubKey = "- \"" + configurationDao.getValue("ssh.publickey") + "\""; String sshKeyPair = kubernetesCluster.getKeyPair(); @@ -233,12 +233,12 @@ private String getKubernetesAdditionalControlConfig(final String joinIp, final b pubKey += "\n - \"" + sshkp.getPublicKey() + "\""; } } - k8sControlConfig = k8sControlConfig.replace(sshPubKey, pubKey); - k8sControlConfig = k8sControlConfig.replace(joinIpKey, joinIp); - k8sControlConfig = k8sControlConfig.replace(clusterTokenKey, KubernetesClusterUtil.generateClusterToken(kubernetesCluster)); - k8sControlConfig = k8sControlConfig.replace(clusterHACertificateKey, KubernetesClusterUtil.generateClusterHACertificateKey(kubernetesCluster)); - k8sControlConfig = k8sControlConfig.replace(ejectIsoKey, String.valueOf(ejectIso)); - return k8sControlConfig; + k8sControlNodeConfig = k8sControlNodeConfig.replace(sshPubKey, pubKey); + k8sControlNodeConfig = k8sControlNodeConfig.replace(joinIpKey, joinIp); + k8sControlNodeConfig = k8sControlNodeConfig.replace(clusterTokenKey, KubernetesClusterUtil.generateClusterToken(kubernetesCluster)); + k8sControlNodeConfig = k8sControlNodeConfig.replace(clusterHACertificateKey, KubernetesClusterUtil.generateClusterHACertificateKey(kubernetesCluster)); + k8sControlNodeConfig = k8sControlNodeConfig.replace(ejectIsoKey, String.valueOf(ejectIso)); + return k8sControlNodeConfig; } private UserVm createKubernetesAdditionalControlNode(final String joinIp, final int additionalControlNodeInstance) throws ManagementServerException, @@ -255,13 +255,13 @@ private UserVm createKubernetesAdditionalControlNode(final String joinIp, final customParameterMap.put("rootdisksize", String.valueOf(rootDiskSize)); } String hostName = getKubernetesClusterNodeAvailableName(String.format("%s-control-%d", kubernetesClusterNodeNamePrefix, additionalControlNodeInstance + 1)); - String k8sControlConfig = null; + String k8sControlNodeConfig = null; try { - k8sControlConfig = getKubernetesAdditionalControlConfig(joinIp, Hypervisor.HypervisorType.VMware.equals(clusterTemplate.getHypervisorType())); + k8sControlNodeConfig = getKubernetesAdditionalControlNodeConfig(joinIp, Hypervisor.HypervisorType.VMware.equals(clusterTemplate.getHypervisorType())); } catch (IOException e) { logAndThrow(Level.ERROR, "Failed to read Kubernetes control configuration file", e); } - String base64UserData = Base64.encodeBase64String(k8sControlConfig.getBytes(StringUtils.getPreferredCharset())); + String base64UserData = Base64.encodeBase64String(k8sControlNodeConfig.getBytes(StringUtils.getPreferredCharset())); additionalControlVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner, hostName, hostName, null, null, null, Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(), diff --git a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesClusterResponse.java b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesClusterResponse.java index 682aaaca8126..cbfa6accff5b 100644 --- a/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesClusterResponse.java +++ b/plugins/integrations/kubernetes-service/src/main/java/org/apache/cloudstack/api/response/KubernetesClusterResponse.java @@ -101,9 +101,9 @@ public class KubernetesClusterResponse extends BaseResponse implements Controlle @Param(description = "keypair details") private String keypair; - @Deprecated + @Deprecated(since = "4.16") @SerializedName(ApiConstants.MASTER_NODES) - @Param(description = "the master nodes count for the Kubernetes cluster") + @Param(description = "the master nodes count for the Kubernetes cluster. This parameter is deprecated, please use 'controlnodes' parameter.") private Long masterNodes; @SerializedName(ApiConstants.CONTROL_NODES) diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml index 787ea97491ce..a8650ac957b3 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node-add.yml @@ -196,7 +196,7 @@ write-files: if [[ "$PATH" != *:/opt/bin && "$PATH" != *:/opt/bin:* ]]; then export PATH=$PATH:/opt/bin fi - kubeadm join {{ k8s_master.join_ip }}:6443 --token {{ k8s_master.cluster.token }} --control-plane --certificate-key {{ k8s_master.cluster.ha.certificate.key }} --discovery-token-unsafe-skip-ca-verification + kubeadm join {{ k8s_control_node.join_ip }}:6443 --token {{ k8s_control_node.cluster.token }} --control-plane --certificate-key {{ k8s_control_node.cluster.ha.certificate.key }} --discovery-token-unsafe-skip-ca-verification sudo touch /home/core/success echo "true" > /home/core/success @@ -229,7 +229,7 @@ coreos: Type=simple StartLimitInterval=0 Restart=on-failure - ExecStartPre=/usr/bin/curl -k https://{{ k8s_master.join_ip }}:6443/version + ExecStartPre=/usr/bin/curl -k https://{{ k8s_control_node.join_ip }}:6443/version ExecStart=/opt/bin/deploy-kube-system update: diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml index db7d7530ed88..c2cecc4a0994 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-control-node.yml @@ -29,17 +29,17 @@ write-files: - path: /etc/kubernetes/pki/cloudstack/ca.crt permissions: '0644' content: | - {{ k8s_master.ca.crt }} + {{ k8s_control_node.ca.crt }} - path: /etc/kubernetes/pki/cloudstack/apiserver.crt permissions: '0644' content: | - {{ k8s_master.apiserver.crt }} + {{ k8s_control_node.apiserver.crt }} - path: /etc/kubernetes/pki/cloudstack/apiserver.key permissions: '0600' content: | - {{ k8s_master.apiserver.key }} + {{ k8s_control_node.apiserver.key }} - path: /opt/bin/setup-kube-system permissions: 0700 @@ -204,7 +204,7 @@ write-files: fi retval=0 set +e - kubeadm init --token {{ k8s_master.cluster.token }} --token-ttl 0 {{ k8s_master.cluster.initargs }} + kubeadm init --token {{ k8s_control_node.cluster.token }} --token-ttl 0 {{ k8s_control_node.cluster.initargs }} retval=$? set -e if [ $retval -eq 0 ]; then diff --git a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml index d2f5454a669d..f65cc9c82963 100644 --- a/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml +++ b/plugins/integrations/kubernetes-service/src/main/resources/conf/k8s-node.yml @@ -196,7 +196,7 @@ write-files: if [[ "$PATH" != *:/opt/bin && "$PATH" != *:/opt/bin:* ]]; then export PATH=$PATH:/opt/bin fi - kubeadm join {{ k8s_master.join_ip }}:6443 --token {{ k8s_master.cluster.token }} --discovery-token-unsafe-skip-ca-verification + kubeadm join {{ k8s_control_node.join_ip }}:6443 --token {{ k8s_control_node.cluster.token }} --discovery-token-unsafe-skip-ca-verification sudo touch /home/core/success echo "true" > /home/core/success @@ -229,7 +229,7 @@ coreos: Type=simple StartLimitInterval=0 Restart=on-failure - ExecStartPre=/usr/bin/curl -k https://{{ k8s_master.join_ip }}:6443/version + ExecStartPre=/usr/bin/curl -k https://{{ k8s_control_node.join_ip }}:6443/version ExecStart=/opt/bin/deploy-kube-system update: diff --git a/ui/src/config/section/compute.js b/ui/src/config/section/compute.js index ffd32a2014fb..d6ecbf53b96a 100644 --- a/ui/src/config/section/compute.js +++ b/ui/src/config/section/compute.js @@ -430,7 +430,7 @@ export default { fields.push('zonename') return fields }, - details: ['name', 'description', 'zonename', 'kubernetesversionname', 'size', 'masternodes', 'cpunumber', 'memory', 'keypair', 'associatednetworkname', 'account', 'domain', 'zonename'], + details: ['name', 'description', 'zonename', 'kubernetesversionname', 'size', 'controlnodes', 'cpunumber', 'memory', 'keypair', 'associatednetworkname', 'account', 'domain', 'zonename'], tabs: [{ name: 'k8s', component: () => import('@/views/compute/KubernetesServiceTab.vue') From eecacc08c6883ef7591a8701c1ee2d16f7c9aea2 Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 2 Jul 2021 10:18:20 -0400 Subject: [PATCH 062/120] add template download record --- .../src/main/java/com/cloud/template/TemplateManagerImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 639f8468aaaa..8ad16a024b19 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1858,6 +1858,8 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template // persist this to the template zone area and remember to remove the resource count in the execute phase once in failure or clean up phase VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, template.getId(), new Date()); _tmpltZoneDao.persist(templateZone); + TemplateDataStoreVO voRecord = _tmplStoreDao.createTemplateDirectDownloadEntry(template.getId(), template.getSize()); + _tmplStoreDao.persist(voRecord); // Increment the number of templates if (template != null) { Map details = new HashMap(); From d916e416ecf7688e6e757361c0ebd91c0120e48c Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Fri, 2 Jul 2021 22:56:35 +0530 Subject: [PATCH 063/120] Updating pom.xml version numbers for release 4.15.2.0-SNAPSHOT Signed-off-by: Rohit Yadav --- agent/pom.xml | 2 +- api/pom.xml | 2 +- client/pom.xml | 2 +- core/pom.xml | 2 +- debian/changelog | 6 ++++++ developer/pom.xml | 2 +- engine/api/pom.xml | 2 +- engine/components-api/pom.xml | 2 +- engine/network/pom.xml | 2 +- engine/orchestration/pom.xml | 2 +- engine/pom.xml | 2 +- engine/schema/pom.xml | 2 +- engine/service/pom.xml | 2 +- engine/storage/cache/pom.xml | 2 +- engine/storage/configdrive/pom.xml | 2 +- engine/storage/datamotion/pom.xml | 2 +- engine/storage/image/pom.xml | 2 +- engine/storage/integration-test/pom.xml | 2 +- engine/storage/pom.xml | 2 +- engine/storage/snapshot/pom.xml | 2 +- engine/storage/volume/pom.xml | 2 +- framework/agent-lb/pom.xml | 2 +- framework/ca/pom.xml | 2 +- framework/cluster/pom.xml | 2 +- framework/config/pom.xml | 2 +- framework/db/pom.xml | 2 +- framework/direct-download/pom.xml | 2 +- framework/events/pom.xml | 2 +- framework/ipc/pom.xml | 2 +- framework/jobs/pom.xml | 2 +- framework/managed-context/pom.xml | 2 +- framework/pom.xml | 2 +- framework/quota/pom.xml | 2 +- framework/rest/pom.xml | 2 +- framework/security/pom.xml | 2 +- framework/spring/lifecycle/pom.xml | 2 +- framework/spring/module/pom.xml | 2 +- plugins/acl/dynamic-role-based/pom.xml | 2 +- plugins/acl/project-role-based/pom.xml | 2 +- plugins/acl/static-role-based/pom.xml | 2 +- .../affinity-group-processors/explicit-dedication/pom.xml | 2 +- plugins/affinity-group-processors/host-affinity/pom.xml | 2 +- .../affinity-group-processors/host-anti-affinity/pom.xml | 2 +- plugins/alert-handlers/snmp-alerts/pom.xml | 2 +- plugins/alert-handlers/syslog-alerts/pom.xml | 2 +- plugins/api/discovery/pom.xml | 2 +- plugins/api/rate-limit/pom.xml | 2 +- plugins/api/solidfire-intg-test/pom.xml | 2 +- plugins/api/vmware-sioc/pom.xml | 2 +- plugins/backup/dummy/pom.xml | 2 +- plugins/backup/veeam/pom.xml | 2 +- plugins/ca/root-ca/pom.xml | 2 +- plugins/database/mysql-ha/pom.xml | 2 +- plugins/database/quota/pom.xml | 2 +- plugins/dedicated-resources/pom.xml | 2 +- plugins/deployment-planners/implicit-dedication/pom.xml | 2 +- plugins/deployment-planners/user-concentrated-pod/pom.xml | 2 +- plugins/deployment-planners/user-dispersing/pom.xml | 2 +- plugins/event-bus/inmemory/pom.xml | 2 +- plugins/event-bus/kafka/pom.xml | 2 +- plugins/event-bus/rabbitmq/pom.xml | 2 +- plugins/ha-planners/skip-heurestics/pom.xml | 2 +- plugins/host-allocators/random/pom.xml | 2 +- plugins/hypervisors/baremetal/pom.xml | 2 +- plugins/hypervisors/hyperv/pom.xml | 2 +- plugins/hypervisors/kvm/pom.xml | 2 +- plugins/hypervisors/ovm/pom.xml | 2 +- plugins/hypervisors/ovm3/pom.xml | 2 +- plugins/hypervisors/simulator/pom.xml | 2 +- plugins/hypervisors/ucs/pom.xml | 2 +- plugins/hypervisors/vmware/pom.xml | 2 +- plugins/hypervisors/xenserver/pom.xml | 2 +- plugins/integrations/cloudian/pom.xml | 2 +- plugins/integrations/kubernetes-service/pom.xml | 2 +- plugins/integrations/prometheus/pom.xml | 2 +- plugins/metrics/pom.xml | 2 +- plugins/network-elements/bigswitch/pom.xml | 2 +- plugins/network-elements/brocade-vcs/pom.xml | 2 +- plugins/network-elements/cisco-vnmc/pom.xml | 2 +- plugins/network-elements/dns-notifier/pom.xml | 2 +- plugins/network-elements/elastic-loadbalancer/pom.xml | 2 +- plugins/network-elements/f5/pom.xml | 2 +- plugins/network-elements/globodns/pom.xml | 2 +- plugins/network-elements/internal-loadbalancer/pom.xml | 2 +- plugins/network-elements/juniper-contrail/pom.xml | 2 +- plugins/network-elements/juniper-srx/pom.xml | 2 +- plugins/network-elements/netscaler/pom.xml | 2 +- plugins/network-elements/nicira-nvp/pom.xml | 2 +- plugins/network-elements/opendaylight/pom.xml | 2 +- plugins/network-elements/ovs/pom.xml | 2 +- plugins/network-elements/palo-alto/pom.xml | 2 +- plugins/network-elements/stratosphere-ssp/pom.xml | 2 +- plugins/network-elements/vxlan/pom.xml | 2 +- plugins/outofbandmanagement-drivers/ipmitool/pom.xml | 2 +- .../outofbandmanagement-drivers/nested-cloudstack/pom.xml | 2 +- plugins/outofbandmanagement-drivers/redfish/pom.xml | 2 +- plugins/pom.xml | 2 +- plugins/storage-allocators/random/pom.xml | 2 +- plugins/storage/image/default/pom.xml | 2 +- plugins/storage/image/s3/pom.xml | 2 +- plugins/storage/image/sample/pom.xml | 2 +- plugins/storage/image/swift/pom.xml | 2 +- plugins/storage/volume/cloudbyte/pom.xml | 2 +- plugins/storage/volume/datera/pom.xml | 2 +- plugins/storage/volume/default/pom.xml | 2 +- plugins/storage/volume/nexenta/pom.xml | 2 +- plugins/storage/volume/sample/pom.xml | 2 +- plugins/storage/volume/solidfire/pom.xml | 2 +- plugins/user-authenticators/ldap/pom.xml | 2 +- plugins/user-authenticators/md5/pom.xml | 2 +- plugins/user-authenticators/pbkdf2/pom.xml | 2 +- plugins/user-authenticators/plain-text/pom.xml | 2 +- plugins/user-authenticators/saml2/pom.xml | 2 +- plugins/user-authenticators/sha256salted/pom.xml | 2 +- pom.xml | 2 +- quickcloud/pom.xml | 2 +- server/pom.xml | 2 +- services/console-proxy/pom.xml | 2 +- services/console-proxy/rdpconsole/pom.xml | 2 +- services/console-proxy/server/pom.xml | 2 +- services/pom.xml | 2 +- services/secondary-storage/controller/pom.xml | 2 +- services/secondary-storage/pom.xml | 2 +- services/secondary-storage/server/pom.xml | 2 +- systemvm/pom.xml | 2 +- test/pom.xml | 2 +- tools/apidoc/pom.xml | 2 +- tools/checkstyle/pom.xml | 2 +- tools/devcloud-kvm/pom.xml | 2 +- tools/devcloud4/pom.xml | 2 +- tools/docker/Dockerfile | 2 +- tools/docker/Dockerfile.marvin | 4 ++-- tools/marvin/pom.xml | 2 +- tools/marvin/setup.py | 2 +- tools/pom.xml | 2 +- usage/pom.xml | 2 +- utils/pom.xml | 2 +- vmware-base/pom.xml | 2 +- 138 files changed, 144 insertions(+), 138 deletions(-) diff --git a/agent/pom.xml b/agent/pom.xml index 42655b17e7c3..58b94d2ff52b 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/api/pom.xml b/api/pom.xml index 8fb03ca2875d..f49d1caf4531 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/client/pom.xml b/client/pom.xml index 169d0a6c982c..b54255344e12 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index db467500be4c..1b48de8826f5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/debian/changelog b/debian/changelog index df7bc1e7103b..adca7c5fe0a2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cloudstack (4.15.2.0-SNAPSHOT) unstable; urgency=low + + * Update the version to 4.15.2.0-SNAPSHOT + + -- the Apache CloudStack project Fri, 02 Jul 2021 22:58:02 +0000 + cloudstack (4.15.1.0) unstable; urgency=low * Update the version to 4.15.1.0 diff --git a/developer/pom.xml b/developer/pom.xml index b5dfabe0841d..664141d94f36 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/engine/api/pom.xml b/engine/api/pom.xml index 7d0355a5d574..99712dd72c63 100644 --- a/engine/api/pom.xml +++ b/engine/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml index 649f1308c3b9..8dc03c21e27e 100644 --- a/engine/components-api/pom.xml +++ b/engine/components-api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/engine/network/pom.xml b/engine/network/pom.xml index 0929fe961ab6..2ab888867593 100644 --- a/engine/network/pom.xml +++ b/engine/network/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml index 90e2995294cb..d1b3f8a9ecbf 100755 --- a/engine/orchestration/pom.xml +++ b/engine/orchestration/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/engine/pom.xml b/engine/pom.xml index 893fc11198dc..d6d039cfaecf 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml index efcc9bad10a1..3a8321f80409 100644 --- a/engine/schema/pom.xml +++ b/engine/schema/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/engine/service/pom.xml b/engine/service/pom.xml index 67fe5bab7f02..cee4f237e558 100644 --- a/engine/service/pom.xml +++ b/engine/service/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT cloud-engine-service war diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml index d78a2ffb44bc..a4c933c3fd78 100644 --- a/engine/storage/cache/pom.xml +++ b/engine/storage/cache/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/configdrive/pom.xml b/engine/storage/configdrive/pom.xml index 05eff5fe62be..928353304be0 100644 --- a/engine/storage/configdrive/pom.xml +++ b/engine/storage/configdrive/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml index bc37fcaa5714..89de38c6ddc4 100644 --- a/engine/storage/datamotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml index fe86d1ab9a1b..19e567f9bbd0 100644 --- a/engine/storage/image/pom.xml +++ b/engine/storage/image/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index a835074ffe2b..4760e87ae7b3 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index f1cb2e20022c..0dce38f8de50 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index 3b0f0517567e..d4a558dbc21a 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml index 127c02faea5b..be87f8cc097f 100644 --- a/engine/storage/volume/pom.xml +++ b/engine/storage/volume/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/framework/agent-lb/pom.xml b/framework/agent-lb/pom.xml index abba5ccce9fe..e510346058d4 100644 --- a/framework/agent-lb/pom.xml +++ b/framework/agent-lb/pom.xml @@ -24,7 +24,7 @@ cloudstack-framework org.apache.cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/ca/pom.xml b/framework/ca/pom.xml index 73af795ae54d..935560daaca0 100644 --- a/framework/ca/pom.xml +++ b/framework/ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml index 1b15106d29da..896a28340bef 100644 --- a/framework/cluster/pom.xml +++ b/framework/cluster/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/config/pom.xml b/framework/config/pom.xml index 218410ba31bd..d8b1bf7f3652 100644 --- a/framework/config/pom.xml +++ b/framework/config/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/db/pom.xml b/framework/db/pom.xml index 28ce27c96448..26b2cdd81624 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/direct-download/pom.xml b/framework/direct-download/pom.xml index 14f7ccc6086d..584000efc1c2 100644 --- a/framework/direct-download/pom.xml +++ b/framework/direct-download/pom.xml @@ -24,7 +24,7 @@ cloudstack-framework org.apache.cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml \ No newline at end of file diff --git a/framework/events/pom.xml b/framework/events/pom.xml index 92b46b68de33..fceeefd8ac29 100644 --- a/framework/events/pom.xml +++ b/framework/events/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index 3bfbaabf2359..53e26895c4b5 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index 53bfd748fbe6..dff71dad9dda 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml index 5114af8727fc..4e1c2a24d04e 100644 --- a/framework/managed-context/pom.xml +++ b/framework/managed-context/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/framework/pom.xml b/framework/pom.xml index 0b7656798ca5..cf60412a6b78 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml index abfeb4731b6a..347df2c6c82a 100644 --- a/framework/quota/pom.xml +++ b/framework/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml index 954cd9bb518d..6a0babecc6a1 100644 --- a/framework/rest/pom.xml +++ b/framework/rest/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml cloud-framework-rest diff --git a/framework/security/pom.xml b/framework/security/pom.xml index 726a3e3adbc7..15ee4f1fbd13 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml index 255c5228411d..a2dda1e5eeb0 100644 --- a/framework/spring/lifecycle/pom.xml +++ b/framework/spring/lifecycle/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml index a4983cd6ef02..cc517d9f7e71 100644 --- a/framework/spring/module/pom.xml +++ b/framework/spring/module/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/acl/dynamic-role-based/pom.xml b/plugins/acl/dynamic-role-based/pom.xml index cad38280a0f0..e4629f51e274 100644 --- a/plugins/acl/dynamic-role-based/pom.xml +++ b/plugins/acl/dynamic-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/acl/project-role-based/pom.xml b/plugins/acl/project-role-based/pom.xml index cc0561052929..1aa9dae37a3f 100644 --- a/plugins/acl/project-role-based/pom.xml +++ b/plugins/acl/project-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml index d9d2be2adaa5..77844c6347eb 100644 --- a/plugins/acl/static-role-based/pom.xml +++ b/plugins/acl/static-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml index 561474137a0b..3d4cff537632 100644 --- a/plugins/affinity-group-processors/explicit-dedication/pom.xml +++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/host-affinity/pom.xml b/plugins/affinity-group-processors/host-affinity/pom.xml index d4656ed12bc3..50e1df62c813 100644 --- a/plugins/affinity-group-processors/host-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml index 97b01a7a60b3..8ed0f26a14be 100644 --- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml index 690a9cf3dce8..57333b9fba87 100644 --- a/plugins/alert-handlers/snmp-alerts/pom.xml +++ b/plugins/alert-handlers/snmp-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml index 9ba0758ecbf0..1065d407a70a 100644 --- a/plugins/alert-handlers/syslog-alerts/pom.xml +++ b/plugins/alert-handlers/syslog-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml index 46d8453b445c..da485d699fbc 100644 --- a/plugins/api/discovery/pom.xml +++ b/plugins/api/discovery/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml index c30383165eef..03f4fdc3e1e4 100644 --- a/plugins/api/rate-limit/pom.xml +++ b/plugins/api/rate-limit/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml index db66187b24f0..42a5ae20e36f 100644 --- a/plugins/api/solidfire-intg-test/pom.xml +++ b/plugins/api/solidfire-intg-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/vmware-sioc/pom.xml b/plugins/api/vmware-sioc/pom.xml index e6be8bf59fc5..cda5deadd7bf 100644 --- a/plugins/api/vmware-sioc/pom.xml +++ b/plugins/api/vmware-sioc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/backup/dummy/pom.xml b/plugins/backup/dummy/pom.xml index f20231d4dee7..96c02628dbce 100644 --- a/plugins/backup/dummy/pom.xml +++ b/plugins/backup/dummy/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/backup/veeam/pom.xml b/plugins/backup/veeam/pom.xml index cf64399dfe59..69e273ffcc2e 100644 --- a/plugins/backup/veeam/pom.xml +++ b/plugins/backup/veeam/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/ca/root-ca/pom.xml b/plugins/ca/root-ca/pom.xml index 38d115938f15..9464b0f9db2d 100644 --- a/plugins/ca/root-ca/pom.xml +++ b/plugins/ca/root-ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml index 657449a567e1..c7ccbf7541c1 100644 --- a/plugins/database/mysql-ha/pom.xml +++ b/plugins/database/mysql-ha/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml index 1807b09514a1..a9f64b52f499 100644 --- a/plugins/database/quota/pom.xml +++ b/plugins/database/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml index 8176d522c860..5ac5bc6265d2 100644 --- a/plugins/dedicated-resources/pom.xml +++ b/plugins/dedicated-resources/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml index 334e1c2f61ff..81b3168cb1ea 100644 --- a/plugins/deployment-planners/implicit-dedication/pom.xml +++ b/plugins/deployment-planners/implicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml index ad1f85629f6f..95d7f286ac32 100644 --- a/plugins/deployment-planners/user-concentrated-pod/pom.xml +++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml index aff6ca5aeffd..2de121c27b58 100644 --- a/plugins/deployment-planners/user-dispersing/pom.xml +++ b/plugins/deployment-planners/user-dispersing/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml index 329bbcd414ac..161c142c8c87 100644 --- a/plugins/event-bus/inmemory/pom.xml +++ b/plugins/event-bus/inmemory/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml index fbe14ded76e3..2921383d33f4 100644 --- a/plugins/event-bus/kafka/pom.xml +++ b/plugins/event-bus/kafka/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml index 29b858f83cec..724e88c9ea69 100644 --- a/plugins/event-bus/rabbitmq/pom.xml +++ b/plugins/event-bus/rabbitmq/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml index 3611d8bd2e24..bba9b9145b11 100644 --- a/plugins/ha-planners/skip-heurestics/pom.xml +++ b/plugins/ha-planners/skip-heurestics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml index 55e42f432af8..001ef2873abb 100644 --- a/plugins/host-allocators/random/pom.xml +++ b/plugins/host-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index 044b7381a1bd..e564d8021347 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-baremetal diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index cda66be4eb0b..301bbd25a693 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index 28a172b28603..20287f8af15f 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml index 001ee2ba136a..55ba72856bd6 100644 --- a/plugins/hypervisors/ovm/pom.xml +++ b/plugins/hypervisors/ovm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml index 46304de4858b..0073e919540f 100644 --- a/plugins/hypervisors/ovm3/pom.xml +++ b/plugins/hypervisors/ovm3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml index 93e7d508d0a3..9c6a9f26ea30 100644 --- a/plugins/hypervisors/simulator/pom.xml +++ b/plugins/hypervisors/simulator/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-simulator diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml index 8d822deacc73..260e23eea204 100644 --- a/plugins/hypervisors/ucs/pom.xml +++ b/plugins/hypervisors/ucs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-ucs diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index 18fd3cc0b03d..bf0207942713 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml index 28f1f2ee03a6..694ebfbaaea4 100644 --- a/plugins/hypervisors/xenserver/pom.xml +++ b/plugins/hypervisors/xenserver/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/integrations/cloudian/pom.xml b/plugins/integrations/cloudian/pom.xml index 505ddf93fa3a..cecf68b3125a 100644 --- a/plugins/integrations/cloudian/pom.xml +++ b/plugins/integrations/cloudian/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/integrations/kubernetes-service/pom.xml b/plugins/integrations/kubernetes-service/pom.xml index ab81c5bbc66b..988bc59bacff 100644 --- a/plugins/integrations/kubernetes-service/pom.xml +++ b/plugins/integrations/kubernetes-service/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/integrations/prometheus/pom.xml b/plugins/integrations/prometheus/pom.xml index f1abbaa0b05f..91797ad61be8 100644 --- a/plugins/integrations/prometheus/pom.xml +++ b/plugins/integrations/prometheus/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/metrics/pom.xml b/plugins/metrics/pom.xml index 0627ce4a9f36..0a90bec1bc2f 100644 --- a/plugins/metrics/pom.xml +++ b/plugins/metrics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/plugins/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml index 1f397655f0a6..45958a636bb1 100644 --- a/plugins/network-elements/bigswitch/pom.xml +++ b/plugins/network-elements/bigswitch/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml index fef1294aa79a..c5a6e43c8df7 100644 --- a/plugins/network-elements/brocade-vcs/pom.xml +++ b/plugins/network-elements/brocade-vcs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml index 2f32d856191f..7d66b079498e 100644 --- a/plugins/network-elements/cisco-vnmc/pom.xml +++ b/plugins/network-elements/cisco-vnmc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml index c8a6447619c2..cec6d292b726 100644 --- a/plugins/network-elements/dns-notifier/pom.xml +++ b/plugins/network-elements/dns-notifier/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml cloud-plugin-example-dns-notifier diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml index b6f0d1714a32..67143d2e9855 100644 --- a/plugins/network-elements/elastic-loadbalancer/pom.xml +++ b/plugins/network-elements/elastic-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/f5/pom.xml b/plugins/network-elements/f5/pom.xml index ea90410b9e0f..4651fecaac29 100644 --- a/plugins/network-elements/f5/pom.xml +++ b/plugins/network-elements/f5/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml index 56719ebcd728..b0e0bc373849 100644 --- a/plugins/network-elements/globodns/pom.xml +++ b/plugins/network-elements/globodns/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml index 5daf5cb575ee..ca065bb4fb85 100644 --- a/plugins/network-elements/internal-loadbalancer/pom.xml +++ b/plugins/network-elements/internal-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index d66ae56e213b..47bce2d6892f 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/juniper-srx/pom.xml b/plugins/network-elements/juniper-srx/pom.xml index 1723ea2f7e56..ac5314bd48f4 100644 --- a/plugins/network-elements/juniper-srx/pom.xml +++ b/plugins/network-elements/juniper-srx/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml index c91e91f09e64..75f07c34146c 100644 --- a/plugins/network-elements/netscaler/pom.xml +++ b/plugins/network-elements/netscaler/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 88ace033b975..860ba0ab7e36 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml index 6c982cc0b6fc..b27ed96104f1 100644 --- a/plugins/network-elements/opendaylight/pom.xml +++ b/plugins/network-elements/opendaylight/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml index 78213eb062c3..fc28f52e1038 100644 --- a/plugins/network-elements/ovs/pom.xml +++ b/plugins/network-elements/ovs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml index 30e59af7fdcc..e82e3df1a507 100644 --- a/plugins/network-elements/palo-alto/pom.xml +++ b/plugins/network-elements/palo-alto/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml index 1de47b870313..504d45e395dc 100644 --- a/plugins/network-elements/stratosphere-ssp/pom.xml +++ b/plugins/network-elements/stratosphere-ssp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml index 0d6100b0ae0f..5de688988094 100644 --- a/plugins/network-elements/vxlan/pom.xml +++ b/plugins/network-elements/vxlan/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml index bf41e865752a..89e4548747f6 100644 --- a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml +++ b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml index 6c9f96484a49..1f11f81df80e 100644 --- a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml +++ b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/redfish/pom.xml b/plugins/outofbandmanagement-drivers/redfish/pom.xml index 2c3292b05357..7b9954c1d53f 100644 --- a/plugins/outofbandmanagement-drivers/redfish/pom.xml +++ b/plugins/outofbandmanagement-drivers/redfish/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/pom.xml b/plugins/pom.xml index 686ad4d79308..0427e7847c4d 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml index ee5c2047e55b..bbe5ed3ed757 100644 --- a/plugins/storage-allocators/random/pom.xml +++ b/plugins/storage-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index 3228910bce05..85d4a1ec2d6f 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index 32488110eab6..5c7ec1cc79ee 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index 3176740d55da..a46319e344fe 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index 4b4da9807aa7..e016598e6131 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml index 6b054c43ce10..dd7bfba060da 100644 --- a/plugins/storage/volume/cloudbyte/pom.xml +++ b/plugins/storage/volume/cloudbyte/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/datera/pom.xml b/plugins/storage/volume/datera/pom.xml index daa52330939d..59f7c81292bc 100644 --- a/plugins/storage/volume/datera/pom.xml +++ b/plugins/storage/volume/datera/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml index 31148796eb3c..1e5114f899bc 100644 --- a/plugins/storage/volume/default/pom.xml +++ b/plugins/storage/volume/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml index 43ac0cd1e31d..340aa7954783 100644 --- a/plugins/storage/volume/nexenta/pom.xml +++ b/plugins/storage/volume/nexenta/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml index 9dbeeb1ad34f..e750f1c1cd83 100644 --- a/plugins/storage/volume/sample/pom.xml +++ b/plugins/storage/volume/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml index 21a9ae63dbc1..d69fbd1228ca 100644 --- a/plugins/storage/volume/solidfire/pom.xml +++ b/plugins/storage/volume/solidfire/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml index a5ba9b4d1d6e..60d7ed642425 100644 --- a/plugins/user-authenticators/ldap/pom.xml +++ b/plugins/user-authenticators/ldap/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml index bb2b0bd501cc..69db8d99cdff 100644 --- a/plugins/user-authenticators/md5/pom.xml +++ b/plugins/user-authenticators/md5/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml index 475e4c01d1b0..f25a108dd535 100644 --- a/plugins/user-authenticators/pbkdf2/pom.xml +++ b/plugins/user-authenticators/pbkdf2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml index 3496e290684d..d8fd842391d6 100644 --- a/plugins/user-authenticators/plain-text/pom.xml +++ b/plugins/user-authenticators/plain-text/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml index 5e873878f547..5746fc8e397f 100644 --- a/plugins/user-authenticators/saml2/pom.xml +++ b/plugins/user-authenticators/saml2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml index 4040745542f7..f61220f82c26 100644 --- a/plugins/user-authenticators/sha256salted/pom.xml +++ b/plugins/user-authenticators/sha256salted/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index ff19c9ff8347..3818c033e4c0 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT pom Apache CloudStack Apache CloudStack is an IaaS ("Infrastructure as a Service") cloud orchestration platform. diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml index 898d4acfad27..f743995408e4 100644 --- a/quickcloud/pom.xml +++ b/quickcloud/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/server/pom.xml b/server/pom.xml index 3f0f75669373..c29ca5b73ea7 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index ce9922446729..b0e51fae41ce 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/rdpconsole/pom.xml b/services/console-proxy/rdpconsole/pom.xml index 5f7610828af3..2568213207a1 100644 --- a/services/console-proxy/rdpconsole/pom.xml +++ b/services/console-proxy/rdpconsole/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index 02f47cd0b222..cb01052d5428 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/services/pom.xml b/services/pom.xml index d3f331524a40..24e74c36b6f0 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml index f9cb8f351001..a75259d13b3b 100644 --- a/services/secondary-storage/controller/pom.xml +++ b/services/secondary-storage/controller/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index d7d7dd652fee..282fa69291da 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml index 751ebc3b6914..b6e7a0b4b5c0 100644 --- a/services/secondary-storage/server/pom.xml +++ b/services/secondary-storage/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/systemvm/pom.xml b/systemvm/pom.xml index bceae9721ee6..d7d55a889be5 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/test/pom.xml b/test/pom.xml index db396e7d8012..ba41ec717f9a 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml index b5f54dc92c61..41b191c8b9ec 100644 --- a/tools/apidoc/pom.xml +++ b/tools/apidoc/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml index 0790c89b2c39..ee9e9e4afabb 100644 --- a/tools/checkstyle/pom.xml +++ b/tools/checkstyle/pom.xml @@ -22,7 +22,7 @@ Apache CloudStack Developer Tools - Checkstyle Configuration org.apache.cloudstack checkstyle - 4.15.1.0 + 4.15.2.0-SNAPSHOT UTF-8 diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml index 79b988ac1f4d..4d98c5b0a84b 100644 --- a/tools/devcloud-kvm/pom.xml +++ b/tools/devcloud-kvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml index b678eacfe4ad..577f5bdc5353 100644 --- a/tools/devcloud4/pom.xml +++ b/tools/devcloud4/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 451184bf18bf..af652f2a3eaa 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:18.04 MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.15.1.0" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.15.2.0-SNAPSHOT" ARG DEBIAN_FRONTEND=noninteractive diff --git a/tools/docker/Dockerfile.marvin b/tools/docker/Dockerfile.marvin index d1a2eeb19005..022f643a3a87 100644 --- a/tools/docker/Dockerfile.marvin +++ b/tools/docker/Dockerfile.marvin @@ -20,11 +20,11 @@ FROM python:2 MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.15.1.0" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.15.2.0-SNAPSHOT" ENV WORK_DIR=/marvin -ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.15.1.0.tar.gz +ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.15.2.0-SNAPSHOT.tar.gz RUN apt-get update && apt-get install -y vim RUN pip install --upgrade paramiko nose requests diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 12c2a5d7f5dc..28c16cbd5ebb 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index 93467f898842..391ec544f844 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -27,7 +27,7 @@ raise RuntimeError("python setuptools is required to build Marvin") -VERSION = "4.15.1.0" +VERSION = "4.15.2.0-SNAPSHOT" setup(name="Marvin", version=VERSION, diff --git a/tools/pom.xml b/tools/pom.xml index 7df173d32830..6fa3cc2cace1 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/usage/pom.xml b/usage/pom.xml index 51efb1841f12..b8148e3bab18 100644 --- a/usage/pom.xml +++ b/usage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT diff --git a/utils/pom.xml b/utils/pom.xml index 4934d26152d3..fe2e64072bf3 100755 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT ../pom.xml diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index 6c778b9c3c39..82363c27cc57 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.15.1.0 + 4.15.2.0-SNAPSHOT From 31824f2b6a8abb43423a93ecaef2c5191bb472bb Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 15:46:18 -0400 Subject: [PATCH 064/120] get the template created and prepare for the vm start --- .../java/com/cloud/network/NetworkModel.java | 4 + .../cloud/template/TemplateApiService.java | 2 +- .../api/command/user/vm/CloneVMCmd.java | 5 +- .../com/cloud/network/NetworkModelImpl.java | 10 +++ .../cloud/template/TemplateManagerImpl.java | 84 +++++++++++++++++-- .../java/com/cloud/vm/UserVmManagerImpl.java | 32 +++++-- 6 files changed, 123 insertions(+), 14 deletions(-) diff --git a/api/src/main/java/com/cloud/network/NetworkModel.java b/api/src/main/java/com/cloud/network/NetworkModel.java index e933a1cc7bd3..0f05b1afa13f 100644 --- a/api/src/main/java/com/cloud/network/NetworkModel.java +++ b/api/src/main/java/com/cloud/network/NetworkModel.java @@ -107,6 +107,10 @@ public interface NetworkModel { List listNetworksUsedByVm(long vmId, boolean isSystem); + default List listNetworksUsedByVm(long vmId) { + throw new UnsupportedOperationException(); + } + Nic getNicInNetwork(long vmId, long networkId); List getNicsForTraffic(long vmId, TrafficType type); diff --git a/api/src/main/java/com/cloud/template/TemplateApiService.java b/api/src/main/java/com/cloud/template/TemplateApiService.java index f0e6f0b264a4..0e647d67f986 100644 --- a/api/src/main/java/com/cloud/template/TemplateApiService.java +++ b/api/src/main/java/com/cloud/template/TemplateApiService.java @@ -105,7 +105,7 @@ public interface TemplateApiService { * */ VirtualMachineTemplate createPrivateTemplateRecord(CloneVMCmd cmd, Account templateOwner) throws ResourceAllocationException; - VirtualMachineTemplate createPrivateTemplateRecord(CloneVMCmd cmd) throws CloudRuntimeException; + VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws CloudRuntimeException; VirtualMachineTemplate createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 074e47b1671a..e92cf27bc10f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.UserVmResponse; //import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import java.util.Optional; @@ -131,8 +132,8 @@ public String getTemplateName() { public void execute() { Optional result; try { -// CallContext.current().setEventDetails("Vm Id for full clone: " + getId()); -// VirtualMachineTemplate template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId())); + CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); +// _templateService.createPrivateTemplate(this); result = _userVmService.cloneVirtualMachine(this); } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); diff --git a/server/src/main/java/com/cloud/network/NetworkModelImpl.java b/server/src/main/java/com/cloud/network/NetworkModelImpl.java index 4322478d93e1..32643ca2a48f 100644 --- a/server/src/main/java/com/cloud/network/NetworkModelImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkModelImpl.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -831,6 +832,15 @@ public List listNetworksUsedByVm(long vmId, boolean isSystem) { return networks; } + @Override + public List listNetworksUsedByVm(long vmId) { + return listNetworksUsedByVm(vmId, false). + stream(). + mapToLong(NetworkVO::getId). + boxed(). + collect(Collectors.toList()); + } + @Override public Nic getNicInNetwork(long vmId, long networkId) { return _nicDao.findByNtwkIdAndInstanceId(networkId, vmId); diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 8ad16a024b19..19e6b25ba3f0 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1782,6 +1782,85 @@ public void doInTransactionWithoutResult(TransactionStatus status) { } } + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating actual private template", create = true) + public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws CloudRuntimeException { + UserVm curVm = cmd.getTargetVM(); + long templateId = cmd.getTemporaryTemlateId(); + final Long accountId = curVm.getAccountId(); + Account caller = CallContext.current().getCallingAccount(); + List volumes = _volumeDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); + VolumeVO targetVolume = volumes.get(0); + long volumeId = targetVolume.getId(); + VMTemplateVO finalTmpProduct = null; + try { + TemplateInfo cloneTempalateInfp = _tmplFactory.getTemplate(templateId, DataStoreRole.Image); + long zoneId = curVm.getDataCenterId(); + AsyncCallFuture future = null; + VolumeInfo vInfo = _volFactory.getVolume(volumeId); + DataStore store = _dataStoreMgr.getImageStoreWithFreeCapacity(zoneId); + future = _tmpltSvr.createTemplateFromVolumeAsync(vInfo, cloneTempalateInfp, store); + CommandResult result = null; + try { + result = future.get(); + + if (result.isFailed()) { + finalTmpProduct = null; + s_logger.debug("Failed to create template: " + result.getResult()); + throw new CloudRuntimeException("Failed to create template: " + result.getResult()); + } + if (_dataStoreMgr.isRegionStore(store)) { + _tmpltSvr.associateTemplateToZone(templateId, null); + } else { + // Already done in the record to db step + } + finalTmpProduct = _tmpltDao.findById(templateId); + TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId); + UsageEventVO usageEvent = + new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, finalTmpProduct.getAccountId(), zoneId, finalTmpProduct.getId(), privateTemplate.getName(), null, + finalTmpProduct.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), finalTmpProduct.getSize()); + _usageEventDao.persist(usageEvent); + } catch (InterruptedException e) { + s_logger.debug("Failed to create template for id: " + templateId, e); + throw new CloudRuntimeException("Failed to create template" , e); + } catch (ExecutionException e) { + s_logger.debug("Failed to create template for id: " + templateId, e); + throw new CloudRuntimeException("Failed to create template ", e); + } + + } finally { + if (finalTmpProduct == null) { + final VolumeVO volumeFinal = targetVolume; + final SnapshotVO snapshotFinal = null; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + // template_store_ref entries should have been removed using our + // DataObject.processEvent command in case of failure, but clean + // it up here to avoid + // some leftovers which will cause removing template from + // vm_template table fail. + _tmplStoreDao.deletePrimaryRecordsForTemplate(templateId); + // Remove the template_zone_ref record + _tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId); + // Remove the template record + _tmpltDao.expunge(templateId); + + // decrement resource count + if (accountId != null) { + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volumeFinal != null ? volumeFinal.getSize() + : snapshotFinal.getSize())); + } + } + }); + + } + } + return null; + } + @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template from clone", create = true) public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account templateOwner) throws ResourceAllocationException { @@ -1904,11 +1983,6 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template } } - @Override - public VirtualMachineTemplate createPrivateTemplateRecord(CloneVMCmd cmd) throws CloudRuntimeException { - return null; - } - @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", create = true) public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 06399bd130bd..78d229988799 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5599,7 +5599,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio String ipv6Address = null; String macAddress = null; // IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); - IpAddresses addr = new IpAddresses("60.147.41.98", ipv6Address, macAddress); + IpAddresses addr = new IpAddresses("60.147.41.99", ipv6Address, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); @@ -5620,16 +5620,36 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio if (template == null) { throw new CloudRuntimeException("the temporary template is not created, server error, contact your sys admin"); } - List networkIds = null; + List networkIds = _networkModel.listNetworksUsedByVm(curVm.getId()); String group = null; InstanceGroupVO groupVo = getGroupForVm(cmd.getId()); if (groupVo != null) { group = groupVo.getName(); } - UserVm vmResult = createBasicSecurityGroupVirtualMachine(dataCenter, serviceOffering, template, securityGroupIdList, curAccount, hostName, displayName, diskOfferingId, - size , group , hypervisorType, cmd.getHttpMethod(), userData , sshKeyPair , ipToNetoworkMap, addr, isDisplayVM , keyboard , null, - curVm.getDetails() == null ? new HashMap<>() : curVm.getDetails(), cmd.getCustomId(), new HashMap<>(), - null, new HashMap<>(), dynamicScalingEnabled); + UserVm vmResult = null; + List affinityGroupIdList = _affinityGroupDao.findByAccountAndNames(curAccount.getId(), curAccount.getAccountName()) + .stream(). + mapToLong(AffinityGroupVO::getId). + boxed(). + collect(Collectors.toList()); + if (dataCenter.getNetworkType() == NetworkType.Basic) { + vmResult = createBasicSecurityGroupVirtualMachine(dataCenter, serviceOffering, template, securityGroupIdList, curAccount, hostName, displayName, diskOfferingId, + size, group, hypervisorType, cmd.getHttpMethod(), userData, sshKeyPair, ipToNetoworkMap, addr, isDisplayVM, keyboard, affinityGroupIdList, + curVm.getDetails() == null ? new HashMap<>() : curVm.getDetails(), cmd.getCustomId(), new HashMap<>(), + null, new HashMap<>(), dynamicScalingEnabled); + } else { + if (dataCenter.isSecurityGroupEnabled()) { + vmResult = createAdvancedSecurityGroupVirtualMachine(dataCenter, serviceOffering, template, networkIds, securityGroupIdList, curAccount, hostName, + displayName, diskOfferingId, size, group, hypervisorType, cmd.getHttpMethod(), userData, sshKeyPair, ipToNetoworkMap, addr, isDisplayVM, keyboard, + affinityGroupIdList, curVm.getDetails() == null ? new HashMap<>() : curVm.getDetails(), cmd.getCustomId(), new HashMap<>(), + null, new HashMap<>(), dynamicScalingEnabled); + } else { + vmResult = createAdvancedVirtualMachine(dataCenter, serviceOffering, template, networkIds, curAccount, hostName, displayName, diskOfferingId, size, group, + hypervisorType, cmd.getHttpMethod(), userData, sshKeyPair, ipToNetoworkMap, addr, isDisplayVM, keyboard, affinityGroupIdList, curVm.getDetails() == null ? new HashMap<>() : curVm.getDetails(), + cmd.getCustomId(), new HashMap<>(), null, new HashMap<>(), dynamicScalingEnabled); + } + } + return vmResult; } From e3bf89459584e511ca05c806d0f59300d4102089 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 16:51:46 -0400 Subject: [PATCH 065/120] fix unknown symbol --- .../src/main/java/com/cloud/template/TemplateManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 19e6b25ba3f0..a1ac73bb4998 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1818,7 +1818,7 @@ public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws Cloud finalTmpProduct = _tmpltDao.findById(templateId); TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId); UsageEventVO usageEvent = - new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, finalTmpProduct.getAccountId(), zoneId, finalTmpProduct.getId(), privateTemplate.getName(), null, + new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, finalTmpProduct.getAccountId(), zoneId, finalTmpProduct.getId(), finalTmpProduct.getName(), null, finalTmpProduct.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), finalTmpProduct.getSize()); _usageEventDao.persist(usageEvent); } catch (InterruptedException e) { From 99e50434144102c27f2387a23dde0ee46e3035e3 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 17:27:32 -0400 Subject: [PATCH 066/120] finish the final private creation --- .../org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index e92cf27bc10f..9cf9007a6943 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -133,7 +133,7 @@ public void execute() { Optional result; try { CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); -// _templateService.createPrivateTemplate(this); + _templateService.createPrivateTemplate(this); result = _userVmService.cloneVirtualMachine(this); } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); From 40abfac2c349e19ea9f58c0c156003cd49474f64 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 17:49:26 -0400 Subject: [PATCH 067/120] add logger information --- .../org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 9cf9007a6943..f71c8a18d2ae 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -101,7 +101,6 @@ public void create() throws ResourceAllocationException { } setEntityId(vmRecord.getId()); setEntityUuid(vmRecord.getUuid()); -// _userVmService.createBasicSecurityGroupVirtualMachine(); // disabled since it crashes } catch (ResourceUnavailableException | InsufficientCapacityException e) { s_logger.warn("Exception: ", e); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, e.getMessage()); @@ -133,6 +132,8 @@ public void execute() { Optional result; try { CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); + s_logger.info("creating actual template id: " + getTemporaryTemlateId()); + s_logger.info("starting actual VM id: " + getEntityId()); _templateService.createPrivateTemplate(this); result = _userVmService.cloneVirtualMachine(this); } catch (ResourceUnavailableException ex) { From d235477b349d7682c3e5e9d563bcdb81fb4aae31 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 18:04:40 -0400 Subject: [PATCH 068/120] add autobox statement --- .../org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index f71c8a18d2ae..270699c6ae08 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -82,7 +82,7 @@ public Long getTemporaryTemlateId() { return this.temporaryTemlateId; } - public void setTemporaryTemlateId(Long tempId) { + public void setTemporaryTemlateId(long tempId) { this.temporaryTemlateId = tempId; } @@ -94,6 +94,7 @@ public void create() throws ResourceAllocationException { if (template == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "failed to create a template to db"); } + s_logger.info("The template id recorded is: " + template.getId()); setTemporaryTemlateId(template.getId()); UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); if (vmRecord == null) { From a48d7fa367fe8ae16091bf6a348cda59d300f9fa Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 21:46:45 -0400 Subject: [PATCH 069/120] add template Id setting --- .../org/apache/cloudstack/api/BaseAsyncCreateCmd.java | 9 +++++++++ .../cloudstack/api/command/user/vm/CloneVMCmd.java | 3 ++- .../java/com/cloud/template/TemplateManagerImpl.java | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java index 60c2a183ad33..869431b8b03a 100644 --- a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java @@ -23,6 +23,8 @@ public abstract class BaseAsyncCreateCmd extends BaseAsyncCmd { private String uuid; + private Long templateId; + public abstract void create() throws ResourceAllocationException; public Long getEntityId() { @@ -49,4 +51,11 @@ public String getCreateEventDescription() { return null; } + public Long getTemplateId() { + return templateId; + } + + public void setTemplateId(Long id) { + this.templateId = id; + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 270699c6ae08..0cadbbba1dc8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -95,6 +95,7 @@ public void create() throws ResourceAllocationException { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "failed to create a template to db"); } s_logger.info("The template id recorded is: " + template.getId()); + setTemplateId(template.getId()); setTemporaryTemlateId(template.getId()); UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); if (vmRecord == null) { @@ -133,7 +134,7 @@ public void execute() { Optional result; try { CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); - s_logger.info("creating actual template id: " + getTemporaryTemlateId()); + s_logger.info("creating actual template id: " + getTemplateId()); s_logger.info("starting actual VM id: " + getEntityId()); _templateService.createPrivateTemplate(this); result = _userVmService.cloneVirtualMachine(this); diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index a1ac73bb4998..5546a6a07e23 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1787,7 +1787,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating actual private template", create = true) public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws CloudRuntimeException { UserVm curVm = cmd.getTargetVM(); - long templateId = cmd.getTemporaryTemlateId(); + long templateId = cmd.getTemplateId(); final Long accountId = curVm.getAccountId(); Account caller = CallContext.current().getCallingAccount(); List volumes = _volumeDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); From 7fb099482d1415bd6758920c2cda86319ca5319c Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 22:19:39 -0400 Subject: [PATCH 070/120] use uuid as replacement of template --- .../org/apache/cloudstack/api/BaseAsyncCreateCmd.java | 10 ---------- .../cloudstack/api/command/user/vm/CloneVMCmd.java | 7 +++---- .../java/com/cloud/template/TemplateManagerImpl.java | 2 +- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java index 869431b8b03a..10fee857dfcf 100644 --- a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java @@ -23,8 +23,6 @@ public abstract class BaseAsyncCreateCmd extends BaseAsyncCmd { private String uuid; - private Long templateId; - public abstract void create() throws ResourceAllocationException; public Long getEntityId() { @@ -50,12 +48,4 @@ public String getCreateEventType() { public String getCreateEventDescription() { return null; } - - public Long getTemplateId() { - return templateId; - } - - public void setTemplateId(Long id) { - this.templateId = id; - } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 0cadbbba1dc8..83ae60a6c3ef 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -95,14 +95,13 @@ public void create() throws ResourceAllocationException { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "failed to create a template to db"); } s_logger.info("The template id recorded is: " + template.getId()); - setTemplateId(template.getId()); - setTemporaryTemlateId(template.getId()); UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); if (vmRecord == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "unable to record a new VM to db!"); } + setTemporaryTemlateId(template.getId()); setEntityId(vmRecord.getId()); - setEntityUuid(vmRecord.getUuid()); + setEntityUuid(String.valueOf(template.getId())); } catch (ResourceUnavailableException | InsufficientCapacityException e) { s_logger.warn("Exception: ", e); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, e.getMessage()); @@ -134,7 +133,7 @@ public void execute() { Optional result; try { CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); - s_logger.info("creating actual template id: " + getTemplateId()); + s_logger.info("creating actual template id: " + getEntityUuid()); s_logger.info("starting actual VM id: " + getEntityId()); _templateService.createPrivateTemplate(this); result = _userVmService.cloneVirtualMachine(this); diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 5546a6a07e23..f5494b7c8444 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1787,7 +1787,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating actual private template", create = true) public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws CloudRuntimeException { UserVm curVm = cmd.getTargetVM(); - long templateId = cmd.getTemplateId(); + long templateId = Long.parseLong(cmd.getEntityUuid()); final Long accountId = curVm.getAccountId(); Account caller = CallContext.current().getCallingAccount(); List volumes = _volumeDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); From ed9ac4e2fc02ff171497ca3b750452cc518badb9 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 22:27:23 -0400 Subject: [PATCH 071/120] fix the template recording bug --- .../org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 83ae60a6c3ef..179d5efd32f1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -95,11 +95,11 @@ public void create() throws ResourceAllocationException { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "failed to create a template to db"); } s_logger.info("The template id recorded is: " + template.getId()); + setTemporaryTemlateId(template.getId()); UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); if (vmRecord == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "unable to record a new VM to db!"); } - setTemporaryTemlateId(template.getId()); setEntityId(vmRecord.getId()); setEntityUuid(String.valueOf(template.getId())); } catch (ResourceUnavailableException | InsufficientCapacityException e) { From 23a53cb22ecbdeaf3e67c6295fbb8c696b1442e0 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 22:53:31 -0400 Subject: [PATCH 072/120] fix instance creation null --- .../org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 2 +- .../src/main/java/com/cloud/template/TemplateManagerImpl.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 179d5efd32f1..b724dc21f000 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -133,7 +133,7 @@ public void execute() { Optional result; try { CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); - s_logger.info("creating actual template id: " + getEntityUuid()); + s_logger.info("creating actual template id: " + Long.parseLong(getEntityUuid())); s_logger.info("starting actual VM id: " + getEntityId()); _templateService.createPrivateTemplate(this); result = _userVmService.cloneVirtualMachine(this); diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index f5494b7c8444..0b0309f9187e 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1807,7 +1807,7 @@ public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws Cloud if (result.isFailed()) { finalTmpProduct = null; - s_logger.debug("Failed to create template: " + result.getResult()); + s_logger.warn("Failed to create template: " + result.getResult()); throw new CloudRuntimeException("Failed to create template: " + result.getResult()); } if (_dataStoreMgr.isRegionStore(store)) { @@ -1815,6 +1815,7 @@ public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws Cloud } else { // Already done in the record to db step } + s_logger.info("successfully created the template with Id: " + templateId); finalTmpProduct = _tmpltDao.findById(templateId); TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId); UsageEventVO usageEvent = @@ -1830,6 +1831,7 @@ public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws Cloud } } finally { + finalTmpProduct = _tmpltDao.findById(templateId); if (finalTmpProduct == null) { final VolumeVO volumeFinal = targetVolume; final SnapshotVO snapshotFinal = null; From 53785ed1c657e74eb0ebd312a97f9469a92e46e0 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 4 Jul 2021 23:52:35 -0400 Subject: [PATCH 073/120] fix the template creation sequence --- .../cloudstack/api/command/user/vm/CloneVMCmd.java | 5 ++--- .../com/cloud/template/TemplateManagerImpl.java | 13 ++++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index b724dc21f000..91144ab72651 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -96,12 +96,13 @@ public void create() throws ResourceAllocationException { } s_logger.info("The template id recorded is: " + template.getId()); setTemporaryTemlateId(template.getId()); + _templateService.createPrivateTemplate(this); UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); if (vmRecord == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "unable to record a new VM to db!"); } setEntityId(vmRecord.getId()); - setEntityUuid(String.valueOf(template.getId())); + setEntityUuid(vmRecord.getUuid()); } catch (ResourceUnavailableException | InsufficientCapacityException e) { s_logger.warn("Exception: ", e); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, e.getMessage()); @@ -133,9 +134,7 @@ public void execute() { Optional result; try { CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); - s_logger.info("creating actual template id: " + Long.parseLong(getEntityUuid())); s_logger.info("starting actual VM id: " + getEntityId()); - _templateService.createPrivateTemplate(this); result = _userVmService.cloneVirtualMachine(this); } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 0b0309f9187e..1955aa96f625 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1787,7 +1787,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating actual private template", create = true) public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws CloudRuntimeException { UserVm curVm = cmd.getTargetVM(); - long templateId = Long.parseLong(cmd.getEntityUuid()); + long templateId = cmd.getTemporaryTemlateId(); final Long accountId = curVm.getAccountId(); Account caller = CallContext.current().getCallingAccount(); List volumes = _volumeDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); @@ -1814,6 +1814,8 @@ public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws Cloud _tmpltSvr.associateTemplateToZone(templateId, null); } else { // Already done in the record to db step + VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date()); + _tmpltZoneDao.persist(templateZone); } s_logger.info("successfully created the template with Id: " + templateId); finalTmpProduct = _tmpltDao.findById(templateId); @@ -1937,10 +1939,11 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template privateTemplate.setSourceTemplateId(sourceTemplateId); VMTemplateVO template = _tmpltDao.persist(privateTemplate); // persist this to the template zone area and remember to remove the resource count in the execute phase once in failure or clean up phase - VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, template.getId(), new Date()); - _tmpltZoneDao.persist(templateZone); - TemplateDataStoreVO voRecord = _tmplStoreDao.createTemplateDirectDownloadEntry(template.getId(), template.getSize()); - _tmplStoreDao.persist(voRecord); +// VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, template.getId(), new Date()); +// _tmpltZoneDao.persist(templateZone); +// TemplateDataStoreVO voRecord = _tmplStoreDao.createTemplateDirectDownloadEntry(template.getId(), template.getSize()); +// voRecord.setDataStoreId(2); +// _tmplStoreDao.persist(voRecord); // Increment the number of templates if (template != null) { Map details = new HashMap(); From 50bf2861c01a5dccb27b8c053d681f76f17ade83 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 5 Jul 2021 11:48:43 +0530 Subject: [PATCH 074/120] server: Fix NPE during destroy VM (#5142) --- .../java/com/cloud/hypervisor/HypervisorGuruBase.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java index 2a8b13e96ca1..5965e89773ad 100644 --- a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java @@ -179,9 +179,13 @@ protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) { ServiceOffering offering = _serviceOfferingDao.findById(vmProfile.getId(), vmProfile.getServiceOfferingId()); VirtualMachine vm = vmProfile.getVirtualMachine(); HostVO host = hostDao.findById(vm.getHostId()); + boolean divideMemoryByOverprovisioning = true; + boolean divideCpuByOverprovisioning = true; - boolean divideMemoryByOverprovisioning = VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(host.getClusterId()); - boolean divideCpuByOverprovisioning = VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(host.getClusterId()); + if (host != null) { + divideMemoryByOverprovisioning = VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(host.getClusterId()); + divideCpuByOverprovisioning = VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(host.getClusterId()); + } Long minMemory = (long)(offering.getRamSize() / (divideMemoryByOverprovisioning ? vmProfile.getMemoryOvercommitRatio() : 1)); int minspeed = (int)(offering.getSpeed() / (divideCpuByOverprovisioning ? vmProfile.getCpuOvercommitRatio() : 1)); From 665142701d5532e42dfcabbbccdc55c24495463a Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 5 Jul 2021 11:50:10 +0530 Subject: [PATCH 075/120] server: Fix NPE when no recipients configured for sending alerts (#5154) * Fix NPE when no recipients configured for sending alerts * Adding logs * Address comments --- server/src/main/java/com/cloud/alert/AlertManagerImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java index 99200f41c2ad..f6e4360b9816 100644 --- a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java @@ -712,6 +712,11 @@ public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long c return; } + if (recipients == null) { + s_logger.warn(String.format("No recipients set in 'alert.email.addresses', skipping sending alert with subject: %s and content: %s", subject, content)); + return; + } + SMTPMailProperties mailProps = new SMTPMailProperties(); mailProps.setSender(new MailAddress(senderAddress)); mailProps.setSubject(subject); From f286f0151697ed6b05b65b8c95a89be525d38073 Mon Sep 17 00:00:00 2001 From: Wei Zhou <57355700+weizhouapache@users.noreply.github.com> Date: Mon, 5 Jul 2021 08:21:07 +0200 Subject: [PATCH 076/120] kvm: fix VM HA on zone-wide storage pools (#5164) --- .../kvm/src/main/java/com/cloud/ha/KVMInvestigator.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/ha/KVMInvestigator.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/ha/KVMInvestigator.java index a6cddc7dfabb..a76b56a1a4de 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/ha/KVMInvestigator.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/ha/KVMInvestigator.java @@ -85,6 +85,15 @@ public Status isAgentAlive(Host agent) { break; } } + if (!hasNfs) { + List zonePools = _storagePoolDao.findZoneWideStoragePoolsByHypervisor(agent.getDataCenterId(), agent.getHypervisorType()); + for (StoragePoolVO pool : zonePools) { + if (pool.getPoolType() == StoragePoolType.NetworkFilesystem) { + hasNfs = true; + break; + } + } + } if (!hasNfs) { s_logger.warn( "Agent investigation was requested on host " + agent + ", but host does not support investigation because it has no NFS storage. Skipping investigation."); From 306a7f42d3aac05ac17ae0ac5d422ca0420c1cbf Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 5 Jul 2021 02:22:23 -0400 Subject: [PATCH 077/120] finish the start vm coding --- .../main/java/com/cloud/vm/UserVmService.java | 2 +- .../api/command/user/vm/CloneVMCmd.java | 10 +++++----- .../java/com/cloud/vm/UserVmManagerImpl.java | 19 +++++++++++++++++-- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index a7fe2824763c..90f41d860ffa 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -94,7 +94,7 @@ public interface UserVmService { * - the command specifying vmId to be cloned * @return the VM if cloneVM operation is successful * */ - Optional cloneVirtualMachine(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException; + Optional cloneVirtualMachine(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; void checkCloneCondition(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ResourceAllocationException; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 91144ab72651..438f31854e79 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -143,12 +143,12 @@ public void execute() { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); } -// catch (ResourceAllocationException ex) { -// s_logger.warn("Exception: ", ex); -// throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage()); -// } + catch (ResourceAllocationException | InsufficientCapacityException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage()); + } result.ifPresentOrElse((userVm)-> { - UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), "virtualmachine", userVm).get(0); + UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), "virtualmachine", result.get()).get(0); response.setResponseName("test_clone"); setResponseObject(response); }, ()-> { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 78d229988799..6c423beba7b9 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4589,10 +4589,25 @@ public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueExce } _resourceLimitMgr.checkResourceLimit(activeOwner, ResourceType.primary_storage, totalSize); } + @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CLONE, eventDescription = "clone vm", async = true) - public Optional cloneVirtualMachine(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, CloudRuntimeException { - return Optional.ofNullable(null); + public Optional cloneVirtualMachine(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, CloudRuntimeException, InsufficientCapacityException, ResourceAllocationException { + long vmId = cmd.getEntityId(); + UserVmVO curVm = _vmDao.findById(vmId); + Long podId = curVm.getPodIdToDeployIn(); + Long clusterId = null; + Long hostId = curVm.getHostId(); + Map additonalParams = new HashMap<>(); + Map diskOfferingMap = null; + if (MapUtils.isNotEmpty(curVm.getDetails()) && curVm.getDetails().containsKey(ApiConstants.BootType.UEFI.toString())) { + Map map = curVm.getDetails(); + additonalParams.put(VirtualMachineProfile.Param.UefiFlag, "Yes"); + additonalParams.put(VirtualMachineProfile.Param.BootType, ApiConstants.BootType.UEFI.toString()); + additonalParams.put(VirtualMachineProfile.Param.BootMode, map.get(ApiConstants.BootType.UEFI.toString())); + } + + return Optional.of(startVirtualMachine(vmId, podId, clusterId, hostId, diskOfferingMap, additonalParams, null)); } @Override From 9533054599764534af00c3204c3490325ea550a7 Mon Sep 17 00:00:00 2001 From: j-porsche Date: Mon, 5 Jul 2021 08:23:06 +0200 Subject: [PATCH 078/120] ui: Changes of the german translation (#5173) --- ui/public/locales/de_DE.json | 50 ++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/ui/public/locales/de_DE.json b/ui/public/locales/de_DE.json index f30e9abbf4c2..b1e29fc64b11 100644 --- a/ui/public/locales/de_DE.json +++ b/ui/public/locales/de_DE.json @@ -111,7 +111,7 @@ "label.action.delete.physical.network": "Physikalisches Netzwerk löschen", "label.action.delete.pod": "Pod löschen", "label.action.delete.pod.processing": "Pod wird gelöscht....", -"label.action.delete.primary.storage": "Hauptspeicher löschen", +"label.action.delete.primary.storage": "Primärspeicher löschen", "label.action.delete.primary.storage.processing": "Primary Storage wird gelöscht....", "label.action.delete.secondary.storage": "Sekundärspeicher löschen", "label.action.delete.secondary.storage.processing": "Secondary Storage wird gelöscht....", @@ -168,7 +168,7 @@ "label.action.edit.network.offering": "Netzwerkangebot bearbeiten", "label.action.edit.network.processing": "Netzwerk wird bearbeitet....", "label.action.edit.pod": "Bearbeiten des Pods", -"label.action.edit.primary.storage": "Hauptspeicher bearbeiten", +"label.action.edit.primary.storage": "Primärspeicher bearbeiten", "label.action.edit.resource.limits": "Resourcenlimit bearbeiten", "label.action.edit.service.offering": "Dienstangebot bearbeiten", "label.action.edit.template": "Vorlage bearbeiten", @@ -335,7 +335,7 @@ "label.add.pod": "Pod hinzufügen", "label.add.port.forwarding.rule": "Portweiterleitungsregel hinzufügen", "label.add.portable.ip.range": "Portablen IP-Bereich hinzufügen", -"label.add.primary.storage": "Hauptspeicher hinzufügen", +"label.add.primary.storage": "Primärspeicher hinzufügen", "label.add.private.gateway": "Privaten Gateway hinzufügen", "label.add.region": "Region hinzufügen", "label.add.resources": "Ressourcen hinzufügen", @@ -467,7 +467,7 @@ "label.baremetalcpu": "CPU (in MHz)", "label.baremetalcpucores": "Anzahl an CPU-Kernen", "label.baremetalmac": "Host-MAC", -"label.baremetalmemory": "Speicher (in MB)", +"label.baremetalmemory": "Arbeitsspeicher", "label.based.on": "Basierend auf", "label.basic": "Basis", "label.basic.mode": "Grundmodus", @@ -1271,8 +1271,8 @@ "label.may.continue": "Sie können jetzt fortfahren", "label.mb.memory": "MB Speicher", "label.memallocated": "Speicher Belegung", -"label.memory": "Speicher (in MB)", -"label.memory.maximum.mb": "Max. Speicher (in MB)", +"label.memory": "Arbeitsspeicher", +"label.memory.maximum.mb": "Max. Arbeitsspeicher", "label.memory.total": "Speicher insgesamt", "label.memory.used": "Genutzter Speicher", "label.memoryallocated": "zugeordneter Speicher", @@ -1331,7 +1331,7 @@ "label.migrate.to.storage": "Zu Speicher migrieren", "label.migrate.volume": "Volumen migrieren", "label.migrate.volume.newdiskoffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.", -"label.migrate.volume.to.primary.storage": "Migriere ein Speichervolumen zu einem anderen Hauptspeicher", +"label.migrate.volume.to.primary.storage": "Migriere ein Speichervolumen zu einem anderen Primärspeicher", "label.migrating": "Migriere", "label.min.balance": "Min Abrechnung", "label.min.past.hour": "min seit Std. vergangen", @@ -1341,7 +1341,7 @@ "label.mininstance": "Min Instanzen", "label.miniops": "Min IOPS", "label.minmaxiops": "Min. IOPS / Max IOPS", -"label.minmemory": "Min. Speicher (in MB)", +"label.minmemory": "Min. Arbeitsspeicher", "label.minute.past.hour": "Minute(n) seit der Stunde vergangen", "label.minutes.past.hour": "Minute(n) seit der Stunde vergangen", "label.monday": "Montag", @@ -1561,12 +1561,12 @@ "label.previous": "Vorherige", "label.primary": "Primär", "label.primary.network": "Hauptnetzwerk", -"label.primary.storage": "Hauptspeicher", -"label.primary.storage.allocated": "Zugewiesener Hauptspeicher", -"label.primary.storage.count": "Hauptspeicher-Pools", -"label.primary.storage.used": "Genutzter Hauptspeicher", -"label.primarystoragelimit": "Hauptspeicher-Limits (GiB)", -"label.primarystoragetotal": "Hauptspeicher", +"label.primary.storage": "Primärspeicher", +"label.primary.storage.allocated": "Zugewiesener Primärspeicher", +"label.primary.storage.count": "Primärspeicher-Pools", +"label.primary.storage.used": "Genutzter Primärspeicher", +"label.primarystoragelimit": "Primärspeicher-Limits (GiB)", +"label.primarystoragetotal": "Primärspeicher", "label.private.gateway": "Privater Gateway", "label.private.interface": "Privates Interface", "label.private.ip.range": "Privater IP-Bereich", @@ -1978,7 +1978,7 @@ "label.storage": "Speicher", "label.storage.tags": "Datenspeicher-Markierung", "label.storage.traffic": "Datenspeicherverkehr", -"label.storageid": "Hauptspeicher", +"label.storageid": "Primärspeicher", "label.storagemotionenabled": "Speicherbewegung aktiviert", "label.storagepolicy": "Speicherkonzept", "label.storagepool": "Speicher-Pool", @@ -2316,7 +2316,7 @@ "message.action.delete.nexusvswitch": "Bitte bestätigen Sie, dass Sie diesen nexus 1000v löschen möchten.", "message.action.delete.physical.network": "Bitte bestätigen Sie, dass Sie dieses physikalische Netzwerk löschen möchten", "message.action.delete.pod": "Bitte bestätigen Sie, dass Sie dieses pod löschen möchten.", -"message.action.delete.primary.storage": "Bitte bestätigen Sie, dass Sie diese Hauptspeicher löschen möchten.", +"message.action.delete.primary.storage": "Bitte bestätigen Sie, dass Sie diese Primärspeicher löschen möchten.", "message.action.delete.secondary.storage": "Bitte bestätigen Sie, dass Sie diesen Sekundärspeicher löschen möchten.", "message.action.delete.security.group": "Bitte bestätigen Sie, dass Sie diese Sicherheitsgruppe löschen möchten.", "message.action.delete.service.offering": "Bitte bestätigen Sie, dass Sie dieses Dienstangebot löschen möchten.", @@ -2350,7 +2350,7 @@ "message.action.host.enable.maintenance.mode": "Die Aktivierung des Wartungsmodus verursacht eine Livemigration aller laufenden Instanzen auf diesem Host zu einem anderen verfügbaren Host.", "message.action.instance.reset.password": "Bitte bestätigen Sie, dass Sie das ROOT Passwort für diese virtuelle Maschine ändern möchten.", "message.action.manage.cluster": "Bitte bestätigen Sie, dass das Cluster bearbeitet werden soll.", -"message.action.primarystorage.enable.maintenance.mode": "Warnung: den Hauptspeicher in den Wartungsmodus zu stellen, wird alle VMs stoppen, welche noch Volumen auf demjenigen haben. Möchten Sie fortfahren?", +"message.action.primarystorage.enable.maintenance.mode": "Warnung: den Primärspeicher in den Wartungsmodus zu stellen, wird alle VMs stoppen, welche noch Volumen auf demjenigen haben. Möchten Sie fortfahren?", "message.action.reboot.instance": "Bitte bestätigen Sie, dass Sie diese Instanz neu starten möchten.", "message.action.reboot.router": "Alle angebotenen Dienste dieses Routers werden unterbrochen. Bitte bestätigen Sie, dass Sie den Router neu starten möchten.", "message.action.reboot.systemvm": "Bitte bestätigen Sie, dass Sie diese System-VM neu starten möchten.", @@ -2406,7 +2406,7 @@ "message.add.pod.during.zone.creation": "Jede Zone muss mindestens einen Pod enthalten, welchen wir nun konfigurieren und hinzufügen. Ein Pod enthält Hosts und primären Storage, welche in einem späteren Schritt hinzugefügt werden. Zuerst konfigurieren Sie den Bereich der reservierten IP-Adressen für CloudStacks internen Verwaltungsdatenverkehr. Der reservierte IP-Bereich muss für jede Zone in der Cloud eindeutig sein.", "message.add.port.forward.failed": "Hinzufügen einer neuen Port-Weiterleitungsregel ist fehlgeschlagen", "message.add.port.forward.processing": "Hinzufügen einer neuen Port-Weiterleitungsregel...", -"message.add.primary": "Bitte spezifizieren Sie die folgenden Parameter, um einen neuen Hauptspeicher hinzuzufügen", +"message.add.primary": "Bitte spezifizieren Sie die folgenden Parameter, um einen neuen Primärspeicher hinzuzufügen", "message.add.primary.storage": "Bitte fügen Sie einen neuen primären Speicher für Zone , und Pod hinzu.", "message.add.private.gateway.failed": "Hinzufügen eines privaten Gateways ist fehlgeschlagen", "message.add.private.gateway.processing": "Hinzufügen eines privaten Gateways...", @@ -2562,7 +2562,7 @@ "message.creating.guest.network": "Gastnetzwerk wird erstellt", "message.creating.physical.networks": "Physikalische Netzwerke werden erstellt", "message.creating.pod": "Erstelle einen Pod", -"message.creating.primary.storage": "Hauptspeicher wird erstellt", +"message.creating.primary.storage": "Primärspeicher wird erstellt", "message.creating.secondary.storage": "Sekundärspeicher wird erstellt", "message.creating.systemvm": "Erstellung von System VMs (das kann eine Weile dauern)", "message.creating.zone": "Zone wird erstellt", @@ -2596,14 +2596,14 @@ "message.desc.add.new.lb.sticky.rule": "Neue Lastverteiler Sticky Regel hinzufügen", "message.desc.advanced.zone": "Für anspruchvollere Netzwerk-Topologien. Dieses Netzwerkmodell bietet die höchste Flexibilität beim Definieren der Gast-Netzwerke und beim Anbieten von maßgeschneiderten Nerzwerk-Angeboten wie Firewall-, VPN- oder Lastverteilungsunterstützung.", "message.desc.basic.zone": "Biete ein einzelnes Netzwerk an, in dem alle VM-Instanzen direkt mit IP vom Netzwerk verbunden sind. Gästeisolation kann durch Layer-3 wie Sicherheitsgruppen angeboten werden (IP-Adressen Source Filtering)", -"message.desc.cluster": "Jeder Pod muss einen oder mehrere Clusters enthalten, und wir werden jetzt den ersten Cluster hinzufügen. Ein Cluster bietet die Möglichkeit Hosts zu gruppieren. Die Hosts in einem Cluster haben alle identische Hardware, betreiben den selben Hypervisor, sind im selben Subnetz und greiffen auf den selben geteilten Speicher zu. Jeder Cluster besteht aus einem oder mehreren Hosts und einem oder mehreren Hauptspeicher-Server.", +"message.desc.cluster": "Jeder Pod muss einen oder mehrere Clusters enthalten, und wir werden jetzt den ersten Cluster hinzufügen. Ein Cluster bietet die Möglichkeit Hosts zu gruppieren. Die Hosts in einem Cluster haben alle identische Hardware, betreiben den selben Hypervisor, sind im selben Subnetz und greiffen auf den selben geteilten Speicher zu. Jeder Cluster besteht aus einem oder mehreren Hosts und einem oder mehreren Primärspeicher-Server.", "message.desc.create.ssh.key.pair": "Bitte die folgenden Daten eintragen um einen SSH-Schlüsselpaar zu registrieren oder erstellen.

(1) Wenn öffentlicher Schlüssel ausgewählt, registriert CloudStack einen öffentlichen Schlüssel. Dieser kann über den privaten Schlüssel verwendet werden.

(2) Wenn öffentlicher Schlüssel nicht ausgewählt ist, erstellt CloudStack einen neuen SSH-Schlüssel. In diesem Fall bitte den privaten Schlüssel kopieren und speichern. CloudStack wird ihn nicht speichern.
", "message.desc.created.ssh.key.pair": "Erstellte ein SSH-Schlüsselpaar.", "message.desc.host": "Jeder Cluster muss mindestens ein Host (Computer) beinhalten damit Gast-VMs darauf laufen können und wir werden nun den ersten Host erstellen. Damit ein Host in CloudStack funktioniert, muss eine Hypervisor-Software darauf installiert, eine IP-Adressse zugewiesen sowie sichergestellt sein, dass sich der Host mit dem CloudStack Verwaltungs-Server verbinden kann .

Geben Sie bitte den DNS-Namen oder IP-Adresse, den Benutzernamen (für gewöhnlich root) und das Passwort sowie jegliche Labels ein, mit denen Sie den Host kategorisieren möchten.", -"message.desc.primary.storage": "Jeder Cluster muss einen oder mehrere Hauptspeicher-Server enthalten, und wir werden nun den ersten erfassen. Hauptspeicher enthält die Festplatten-Volumen aller VMs, welche auf den Hosts in dem Cluster befinden. Benutzen Sie irgend ein standardkonformes Protokoll, welches vom darunterliegenden Hypervisor unterstützt wird.", +"message.desc.primary.storage": "Jeder Cluster muss einen oder mehrere Primärspeicher-Server enthalten, und wir werden nun den ersten erfassen. Primärspeicher enthält die Festplatten-Volumen aller VMs, welche auf den Hosts in dem Cluster befinden. Benutzen Sie irgend ein standardkonformes Protokoll, welches vom darunterliegenden Hypervisor unterstützt wird.", "message.desc.reset.ssh.key.pair": "Bitte definieren Sie ein SSH-Schlüsselpaar welches Sie zu dieser VM hinzufügen möchten. Bitte beachten Sie, dass das Root-Passwort dabei geändert wird falls es aktiviert ist.", "message.desc.secondary.storage": "Jede Zone muss mindestens ein NFS oder Sekundärspeicher-Server haben und wir werden nun den ersten hinzufügen. Sekundärspeicher speichert VM-Vorlagen, ISO-Abbilder und VM-Festplatten-Schnappschüsse. Dieser Server muss für alle Host in der Zone erreichbar sein.

Geben Sie die IP und den exportierten Pfad an.", -"message.desc.zone": "Eine Zone ist die größte organisatorische Einheit in CloudStack und entspricht typischerweise eines einzelnen Rechenzentrum. Zonen bieten physikalische Isolation und Redundanz. Eine Zone beinhaltet einen oder mehrere Pods (jeder von Ihnen beinhaltet Hosts und Hauptspeicher-Server) und ein Sekundärspeicher-Server, welcher von allen Pods in der Zone geteilt wird.", +"message.desc.zone": "Eine Zone ist die größte organisatorische Einheit in CloudStack und entspricht typischerweise eines einzelnen Rechenzentrum. Zonen bieten physikalische Isolation und Redundanz. Eine Zone beinhaltet einen oder mehrere Pods (jeder von Ihnen beinhaltet Hosts und Primärspeicher-Server) und ein Sekundärspeicher-Server, welcher von allen Pods in der Zone geteilt wird.", "message.detach.disk": "Sind Sie sicher, dass Sie diese Festplatte loslösen möchten?", "message.detach.iso.confirm": "Bitte bestätigen Sie, dass Sie die ISO von der virtuellen Instanz trennen möchten.", "message.diagnostics.exitcode": "exitcode: var", @@ -2785,7 +2785,7 @@ "message.installwizard.copy.whatisapod": "Ein Pod steht häufig für ein einzelnes Rack. Host im selben Pod sind im selben Subnetz.

Ein Pod ist die zweitgrößte Einheit innerhalb einer CloudStack™ Installation. Pods sind geschlossen innerhalb der Zonen. Jede Zone kann eine oder mehrere Pods enthalten; in der Basisinstallation werden Sie nur ein Pod in Ihrer Zone haben.", "message.installwizard.copy.whatisazone": "Eine Zone ist die größte organisatorische Einheit innerhalb einer CloudStack™ Installation. Eine Zone steht typischerweise für ein einzelnes Rechenzentrum, obwohl es natürlich erlaubt ist, mehrere Zonen in einem Rechenzentrum zu haben. Der Vorteil einer Unterteilung der Infrastruktur in Zonen besteht im Anbieten einer physikalischen Isolierung und Redundanz. Zum Beispiel kann jede Zone ihre eigene Stromversorgung und ihr eigener Netzwerk-Uplink haben und geographisch weit auseinanderliegen (obschon dies nicht zwingend ist).", "message.installwizard.copy.whatiscloudstack": "CloudStack™ ist eine Software-Plattform welche Rechenressourcen zusammenfasst, um öffentliche, private oder hybride \"Infrastructure as a Service\" (IaaS) Clouds zu bauen. CloudStack™ verwaltet das Netzwerk-, Speicher- und Computingknoten was eine Cloud-Infrastruktur ausmacht. Benutzen Sie CloudStack™ um Computing-Umgebungen zu erstellen, verwalten und zu konfigurieren.

Neben dem Erweitern von individuellen virtuellen Maschinenabbilder auf auf Standardhardware bietet CloudStack™ einen schlüsselfertigen Cloud Infrastruktur-Software-Stack für die Bereitstellung von virtueller Rechenzentren as a Service – Liefert alle wesentlichen Komponenten für das Bauen, Bereitstellen und Verwalten von multi-tier- und mandantenfähigen Cloud-Anwendungen. Open-Source sowie Premium-Versionen sind verfügbar, mit nahezu identischen Features.", -"message.installwizard.copy.whatisprimarystorage": "Eine CloudStack™ Cloud-Infrastruktur verwendet zwei Arten von Speicher: Hauptspeicher und Sekundärspeicher. Beide können iSCSI- oder NFS-Server, oder auch lokale Festplatten sein.

Hauptspeicher ist mit einem Cluster verbunden und speichert Festplattenvolumen aller diejenigen Gast-VMs, welche auf Hosts in diesem Cluster laufen. Der Hauptspeicher-Server ist typischerweise nahe am Host gelegen.", +"message.installwizard.copy.whatisprimarystorage": "Eine CloudStack™ Cloud-Infrastruktur verwendet zwei Arten von Speicher: Primärspeicher und Sekundärspeicher. Beide können iSCSI- oder NFS-Server, oder auch lokale Festplatten sein.

Primärspeicher ist mit einem Cluster verbunden und speichert Festplattenvolumen aller diejenigen Gast-VMs, welche auf Hosts in diesem Cluster laufen. Der Primärspeicher-Server ist typischerweise nahe am Host gelegen.", "message.installwizard.copy.whatissecondarystorage": "Sekundärspeicher wird mit einer Zone verbunden und speichert alles folgende:
  • Vorlagen - Betriebssystemabbilder welche für das Booten der VMs verwendet werden und zusätzliche Konfigurationsinformationen wie installierte Applikationen beinhalten kann
  • ISO-Abbilder - Betriebssystemabbilder welche bootbar oder nicht bootbar sein können
  • Festplattenvolumen-Schnappschüsse - gesicherte Kopien von VM-Daten, welche für die Datenwiederherstellung oder für neue Vorlagen verwenden werden können
", "message.installwizard.now.building": "Ihre Cloud wird erstellt...", "message.installwizard.tooltip.addcluster.name": "Der Name des Clusters. Der Name kann frei gewählt werden und wird von Cloudstack nicht genutzt.", @@ -2870,7 +2870,7 @@ "message.number.clusters": "

# of Cluster

", "message.number.hosts": "

# of Hosts

", "message.number.pods": "

Anzahl derPods

", -"message.number.storage": "

# von Hauptspeichervolumina

", +"message.number.storage": "

# von Primärspeicherdatenträgern

", "message.number.zones": "

# of Zonen

", "message.outofbandmanagement.action.maintenance": "Warnung Host ist im Wartungsmodus", "message.ovf.properties.available": "Die folgenden OVF-Eigenschaften stehen für die Bearbeitung zur Verfügung. Bitte passen Sie die Werte dementsprechend an", @@ -3150,7 +3150,7 @@ "message.zone.step.1.desc": "Bitte wählen Sie ein Netzwerk-Modell für Ihre Zone.", "message.zone.step.2.desc": "Bitte geben Sie die folgende Information ein, um eine neue Zone hinzuzufügen", "message.zone.step.3.desc": "Bitte geben Sie die folgende Information ein, um einen neuen pod hinzuzufügen", -"message.zonewizard.enable.local.storage": "WARNUNG: Wenn Sie den lokalen Speicher für diese Zone aktivieren möchten, müssen Sie, abhängig davon wo Sie Ihre System-VMs starten möchten, wie folgt vorgehen:

1. Wenn die System-VMs im geteilten Hauptspeicher gestartet werden sollen, muss der geteilte Hauptspeicher nach dem Erstellen zur Zone hinzugefügt werden. Zudem muss die Zone im deaktivierten Zustand gestartet werden.

2. Wenn die System-VMs im lokalen Hauptspeicher gestartet werden sollen, muss, \"system.vm.use.local.storage\" auf \"true\" gesetzt werden bevor Sie die Zone aktivieren.


Möchten Sie weiterfahren?", +"message.zonewizard.enable.local.storage": "WARNUNG: Wenn Sie den lokalen Speicher für diese Zone aktivieren möchten, müssen Sie, abhängig davon wo Sie Ihre System-VMs starten möchten, wie folgt vorgehen:

1. Wenn die System-VMs im geteilten Primärspeicher gestartet werden sollen, muss der geteilte Primärspeicher nach dem Erstellen zur Zone hinzugefügt werden. Zudem muss die Zone im deaktivierten Zustand gestartet werden.

2. Wenn die System-VMs im lokalen Primärspeicher gestartet werden sollen, muss, \"system.vm.use.local.storage\" auf \"true\" gesetzt werden bevor Sie die Zone aktivieren.


Möchten Sie weiterfahren?", "messgae.validate.min": "Bitte geben sie einen Wert größer oder gleich {0} ein.", "network.rate": "Netzwerk-Rate", "router.health.checks": "Gesundheitsüberprüfung", From 584c1cfbe0211347d94972ffdc142fca5007b42b Mon Sep 17 00:00:00 2001 From: Hoang Nguyen Date: Mon, 5 Jul 2021 13:23:38 +0700 Subject: [PATCH 079/120] ui: secondary storage - Display text and change the badge color of the Read-only column (#5176) * change badge color and display text of read-only secondary storage * change readonly label to access Fixes #5169 --- ui/public/locales/en.json | 2 ++ ui/src/components/view/ListView.vue | 2 +- ui/src/components/widgets/Status.vue | 8 +++++++- ui/src/config/section/infra/secondaryStorages.js | 5 ++++- ui/src/views/AutogenView.vue | 16 ++++++++++++---- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 2f51944d1f0a..870686b5f387 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -3324,6 +3324,8 @@ "state.expunging": "Expunging", "state.migrating": "Migrating", "state.pending": "Pending", +"state.readonly": "Read-Only", +"state.readwrite": "Read-Write", "state.running": "Running", "state.starting": "Starting", "state.stopped": "Stopped", diff --git a/ui/src/components/view/ListView.vue b/ui/src/components/view/ListView.vue index 85f49b3f8460..06b9fe384e42 100644 --- a/ui/src/components/view/ListView.vue +++ b/ui/src/components/view/ListView.vue @@ -231,7 +231,7 @@ {{ text }} - + {{ $toLocaleDate(text) }} diff --git a/ui/src/components/widgets/Status.vue b/ui/src/components/widgets/Status.vue index fa8fe1a3b20b..d380271aba05 100644 --- a/ui/src/components/widgets/Status.vue +++ b/ui/src/components/widgets/Status.vue @@ -72,6 +72,12 @@ export default { case 'Error': state = this.$t('state.error') break + case 'ReadOnly': + state = this.$t('state.readonly') + break + case 'ReadWrite': + state = this.$t('state.readwrite') + break } return state.charAt(0).toUpperCase() + state.slice(1) } @@ -106,7 +112,6 @@ export default { case 'Error': case 'False': case 'Stopped': - case 'ReadOnly': status = 'error' break case 'Migrating': @@ -126,6 +131,7 @@ export default { case 'Created': case 'Maintenance': case 'Pending': + case 'ReadOnly': status = 'warning' break } diff --git a/ui/src/config/section/infra/secondaryStorages.js b/ui/src/config/section/infra/secondaryStorages.js index 17600aaa17bc..d22564d7221b 100644 --- a/ui/src/config/section/infra/secondaryStorages.js +++ b/ui/src/config/section/infra/secondaryStorages.js @@ -25,7 +25,10 @@ export default { columns: () => { var fields = ['name', 'url', 'protocol', 'scope', 'zonename'] if (store.getters.apis.listImageStores.params.filter(x => x.name === 'readonly').length > 0) { - fields.push('readonly') + fields.push({ + field: 'readonly', + customTitle: 'access' + }) } return fields }, diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index ebeca6e4ab0c..ecd8547466e2 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -583,13 +583,21 @@ export default { const customRender = {} for (var columnKey of this.columnKeys) { - var key = columnKey + let key = columnKey + let title = columnKey if (typeof columnKey === 'object') { - key = Object.keys(columnKey)[0] - customRender[key] = columnKey[key] + if ('customTitle' in columnKey && 'field' in columnKey) { + key = columnKey.field + title = columnKey.customTitle + customRender[key] = columnKey[key] + } else { + key = Object.keys(columnKey)[0] + title = Object.keys(columnKey)[0] + customRender[key] = columnKey[key] + } } this.columns.push({ - title: this.$t('label.' + String(key).toLowerCase()), + title: this.$t('label.' + String(title).toLowerCase()), dataIndex: key, scopedSlots: { customRender: key }, sorter: function (a, b) { return genericCompare(a[this.dataIndex] || '', b[this.dataIndex] || '') } From 8ecb6a587b933b08e514ad67cad8e7bc9c0165b6 Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 5 Jul 2021 02:36:48 -0400 Subject: [PATCH 080/120] fix start virtual machine null pointer bug --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 6c423beba7b9..e94225b3e4c1 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4599,7 +4599,7 @@ public Optional cloneVirtualMachine(CloneVMCmd cmd) throws ResourceUnava Long clusterId = null; Long hostId = curVm.getHostId(); Map additonalParams = new HashMap<>(); - Map diskOfferingMap = null; + Map diskOfferingMap = new HashMap<>(); if (MapUtils.isNotEmpty(curVm.getDetails()) && curVm.getDetails().containsKey(ApiConstants.BootType.UEFI.toString())) { Map map = curVm.getDetails(); additonalParams.put(VirtualMachineProfile.Param.UefiFlag, "Yes"); From a1bf574b8e8b28a1cfbc7ed842174bb801b97f30 Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 5 Jul 2021 02:49:21 -0400 Subject: [PATCH 081/120] add public ip address for kvm host test --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index e94225b3e4c1..483f58991bba 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5614,7 +5614,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio String ipv6Address = null; String macAddress = null; // IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); - IpAddresses addr = new IpAddresses("60.147.41.99", ipv6Address, macAddress); + IpAddresses addr = new IpAddresses("172.20.0.97", ipv6Address, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); From 96393890f03fd6c27f9319774947b22f7fcad3fd Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 5 Jul 2021 12:20:28 -0400 Subject: [PATCH 082/120] new clone ip added --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 483f58991bba..c269e2fd71c9 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5614,7 +5614,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio String ipv6Address = null; String macAddress = null; // IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); - IpAddresses addr = new IpAddresses("172.20.0.97", ipv6Address, macAddress); + IpAddresses addr = new IpAddresses("172.20.0.100", ipv6Address, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); From 0871f74a4e0c6c0eb5c5693affb1f446cb9d070a Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 5 Jul 2021 12:55:53 -0400 Subject: [PATCH 083/120] change test ip to 98 --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index c269e2fd71c9..1ffb479c22ff 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5614,7 +5614,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio String ipv6Address = null; String macAddress = null; // IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); - IpAddresses addr = new IpAddresses("172.20.0.100", ipv6Address, macAddress); + IpAddresses addr = new IpAddresses("172.20.0.98", ipv6Address, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); From f5b896e5a8291a73bffdf6e715cac2b1fba3a74a Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 02:22:04 -0400 Subject: [PATCH 084/120] fixing the first password issue --- .../cloud/template/TemplateApiService.java | 3 +- .../api/command/user/vm/CloneVMCmd.java | 14 ++- .../cloud/template/TemplateManagerImpl.java | 93 ++++++++++++------- .../java/com/cloud/vm/UserVmManagerImpl.java | 6 +- 4 files changed, 79 insertions(+), 37 deletions(-) diff --git a/api/src/main/java/com/cloud/template/TemplateApiService.java b/api/src/main/java/com/cloud/template/TemplateApiService.java index 0e647d67f986..fd45499ef6b4 100644 --- a/api/src/main/java/com/cloud/template/TemplateApiService.java +++ b/api/src/main/java/com/cloud/template/TemplateApiService.java @@ -20,6 +20,7 @@ import java.net.URISyntaxException; import java.util.List; +import com.cloud.storage.VolumeApiService; import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; @@ -103,7 +104,7 @@ public interface TemplateApiService { /** * create a template record for later usage of creating a real template by createPrivateTemplate * */ - VirtualMachineTemplate createPrivateTemplateRecord(CloneVMCmd cmd, Account templateOwner) throws ResourceAllocationException; + VirtualMachineTemplate createPrivateTemplateRecord(CloneVMCmd cmd, Account templateOwner, VolumeApiService serviceObj) throws ResourceAllocationException; VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws CloudRuntimeException; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 438f31854e79..41837c93ac72 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -6,6 +6,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.storage.Snapshot; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; @@ -52,6 +53,8 @@ public class CloneVMCmd extends BaseAsyncCreateCustomIdCmd implements UserCmd { private Long temporaryTemlateId; + private Long temporarySnapShotId; + public String getAccountName() { return accountName; } @@ -82,6 +85,15 @@ public Long getTemporaryTemlateId() { return this.temporaryTemlateId; } + public void setTemporarySnapShotId(Long snapshotId) { + this.temporarySnapShotId = snapshotId; + } + + public Long getTemporarySnapShotId() { + return temporarySnapShotId; + } + + public void setTemporaryTemlateId(long tempId) { this.temporaryTemlateId = tempId; } @@ -90,7 +102,7 @@ public void setTemporaryTemlateId(long tempId) { public void create() throws ResourceAllocationException { try { _userVmService.checkCloneCondition(this); - VirtualMachineTemplate template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId())); + VirtualMachineTemplate template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId()), _volumeService); if (template == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "failed to create a template to db"); } diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 1955aa96f625..3e68ef0f9605 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -33,6 +33,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.storage.*; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; @@ -143,29 +144,9 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.projects.Project; import com.cloud.projects.ProjectManager; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.GuestOSVO; -import com.cloud.storage.ImageStoreUploadMonitorImpl; -import com.cloud.storage.LaunchPermissionVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolHostVO; -import com.cloud.storage.StoragePoolStatus; -import com.cloud.storage.TemplateProfile; -import com.cloud.storage.Upload; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.Volume; -import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.LaunchPermissionDao; import com.cloud.storage.dao.SnapshotDao; @@ -1788,19 +1769,50 @@ public void doInTransactionWithoutResult(TransactionStatus status) { public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws CloudRuntimeException { UserVm curVm = cmd.getTargetVM(); long templateId = cmd.getTemporaryTemlateId(); + long snapshotId = cmd.getTemporarySnapShotId(); final Long accountId = curVm.getAccountId(); Account caller = CallContext.current().getCallingAccount(); List volumes = _volumeDao.findByInstanceAndType(cmd.getId(), Volume.Type.ROOT); VolumeVO targetVolume = volumes.get(0); long volumeId = targetVolume.getId(); VMTemplateVO finalTmpProduct = null; + SnapshotVO snapshot = null; try { TemplateInfo cloneTempalateInfp = _tmplFactory.getTemplate(templateId, DataStoreRole.Image); long zoneId = curVm.getDataCenterId(); AsyncCallFuture future = null; VolumeInfo vInfo = _volFactory.getVolume(volumeId); DataStore store = _dataStoreMgr.getImageStoreWithFreeCapacity(zoneId); - future = _tmpltSvr.createTemplateFromVolumeAsync(vInfo, cloneTempalateInfp, store); + snapshot = _snapshotDao.findById(snapshotId); +// future = _tmpltSvr.createTemplateFromVolumeAsync(vInfo, cloneTempalateInfp, store); + // create template from snapshot + DataStoreRole dataStoreRole = ApiResponseHelper.getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr); + SnapshotInfo snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole); + if (dataStoreRole == DataStoreRole.Image) { + if (snapInfo == null) { + snapInfo = _snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary); + if(snapInfo == null) { + throw new CloudRuntimeException("Cannot find snapshot "+snapshotId); + } + // We need to copy the snapshot onto secondary. + SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP); + snapshotStrategy.backupSnapshot(snapInfo); + + // Attempt to grab it again. + snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole); + if(snapInfo == null) { + throw new CloudRuntimeException("Cannot find snapshot " + snapshotId + " on secondary and could not create backup"); + } + } + _accountMgr.checkAccess(caller, null, true, snapInfo); + DataStore snapStore = snapInfo.getDataStore(); + + if (snapStore != null) { + store = snapStore; // pick snapshot image store to create template + } + } + future = _tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, cloneTempalateInfp, store); + // wait for the result to converge CommandResult result = null; try { result = future.get(); @@ -1836,7 +1848,7 @@ public VirtualMachineTemplate createPrivateTemplate(CloneVMCmd cmd) throws Cloud finalTmpProduct = _tmpltDao.findById(templateId); if (finalTmpProduct == null) { final VolumeVO volumeFinal = targetVolume; - final SnapshotVO snapshotFinal = null; + final SnapshotVO snapshotFinal = snapshot; Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { @@ -1867,7 +1879,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template from clone", create = true) - public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account templateOwner) throws ResourceAllocationException { + public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account templateOwner, VolumeApiService volumeService) throws ResourceAllocationException { Account caller = CallContext.current().getCallingAccount(); _accountMgr.checkAccess(caller, null, true, templateOwner); String name = cmd.getTemplateName(); @@ -1883,21 +1895,22 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template HypervisorType hyperType = null; VolumeVO volume = _volumeDao.findById(volumeId); if (volume == null) { - throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId); + throw new InvalidParameterValueException("Failed to create private template record, unable to find root volume " + volumeId); } + // check permissions _accountMgr.checkAccess(caller, null, true, volume); // If private template is created from Volume, check that the volume // will not be active when the private template is // created - if (!_volumeMgr.volumeInactive(volume)) { - String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM, please stop the VM first"; - if (s_logger.isInfoEnabled()) { - s_logger.info(msg); - } - throw new CloudRuntimeException(msg); - } +// if (!_volumeMgr.volumeInactive(volume)) { +// String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM, please stop the VM first"; +// if (s_logger.isInfoEnabled()) { +// s_logger.info(msg); +// } +// throw new CloudRuntimeException(msg); +// } hyperType = _volumeDao.getHypervisorType(volumeId); if (HypervisorType.LXC.equals(hyperType)) { @@ -1913,7 +1926,23 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist."); } + // get snapshot from this step + + Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id"); + s_logger.info("Creating snapshot for the tempalte creation"); + SnapshotVO snapshot = (SnapshotVO) volumeService.allocSnapshot(volumeId, null, curVm.getDisplayName() + "-Clone-" + nextTemplateId, Snapshot.LocationType.PRIMARY); + if (snapshot == null) { + throw new CloudRuntimeException("Unable to create a snapshot during the template creation recording"); + } + Snapshot snapshotEntity = volumeService.takeSnapshot(volumeId, null, snapshot.getId(), caller, false, Snapshot.LocationType.PRIMARY, false, new HashMap<>()); + if (snapshotEntity == null) { + throw new CloudRuntimeException("Error when creating the snapshot entity"); + } + if (snapshotEntity.getState() != Snapshot.State.BackedUp) { + throw new CloudRuntimeException("Async backup of snapshot happens during the clone for snapshot id: " + snapshot.getId()); + } + cmd.setTemporarySnapShotId(snapshot.getId()); String description = ""; // TODO: add this to clone parameter in the future boolean isExtractable = false; Long sourceTemplateId = null; @@ -1978,7 +2007,7 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template); _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage, - volume.getSize()); + snapshot.getSize()); } if (template != null) { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 1ffb479c22ff..a2955491d742 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4524,9 +4524,9 @@ public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueExce throw new CloudRuntimeException("the VM doesn't exist or not registered in management server!"); } UserVmVO vmStatus = _vmDao.findById(cmd.getId()); - if (vmStatus.state != State.Shutdown && vmStatus.state != State.Stopped) { - throw new CloudRuntimeException("You should clone an instance that's shutdown!"); - } +// if (vmStatus.state != State.Shutdown && vmStatus.state != State.Stopped) { +// throw new CloudRuntimeException("You should clone an instance that's shutdown!"); +// } if (vmStatus.getHypervisorType() != HypervisorType.KVM && vmStatus.getHypervisorType() != HypervisorType.Simulator) { throw new CloudRuntimeException("The clone operation is only supported on KVM and Simulator!"); } From 8bebd3b6dd781dfa3d1aa50eeccd4fa61bdbdc86 Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 02:23:40 -0400 Subject: [PATCH 085/120] fix the style code --- .../org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 41837c93ac72..cdd5cb342c4d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -6,7 +6,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.storage.Snapshot; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; From 21ac7a77aa1ccaa92af6eb98ca62dd5afd7355e5 Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 02:26:07 -0400 Subject: [PATCH 086/120] audit the star --- .../cloud/template/TemplateManagerImpl.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 3e68ef0f9605..e00c5b8650ab 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -33,7 +33,27 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; -import com.cloud.storage.*; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.GuestOSVO; +import com.cloud.storage.ImageStoreUploadMonitorImpl; +import com.cloud.storage.LaunchPermissionVO; +import com.cloud.storage.Snapshot; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.Storage; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolHostVO; +import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.TemplateProfile; +import com.cloud.storage.Upload; +import com.cloud.storage.VMTemplateHostVO; +import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VMTemplateZoneVO; +import com.cloud.storage.Volume; +import com.cloud.storage.VolumeApiService; +import com.cloud.storage.VolumeVO; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; From 385df67c0d69535c119b525c2b402bec7dfcc9dc Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 02:57:36 -0400 Subject: [PATCH 087/120] location type changed --- .../src/main/java/com/cloud/template/TemplateManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index e00c5b8650ab..15f982f5e430 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1951,11 +1951,11 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id"); s_logger.info("Creating snapshot for the tempalte creation"); - SnapshotVO snapshot = (SnapshotVO) volumeService.allocSnapshot(volumeId, null, curVm.getDisplayName() + "-Clone-" + nextTemplateId, Snapshot.LocationType.PRIMARY); + SnapshotVO snapshot = (SnapshotVO) volumeService.allocSnapshot(volumeId, null, curVm.getDisplayName() + "-Clone-" + nextTemplateId, null); if (snapshot == null) { throw new CloudRuntimeException("Unable to create a snapshot during the template creation recording"); } - Snapshot snapshotEntity = volumeService.takeSnapshot(volumeId, null, snapshot.getId(), caller, false, Snapshot.LocationType.PRIMARY, false, new HashMap<>()); + Snapshot snapshotEntity = volumeService.takeSnapshot(volumeId, null, snapshot.getId(), caller, false, null, false, new HashMap<>()); if (snapshotEntity == null) { throw new CloudRuntimeException("Error when creating the snapshot entity"); } From cec1ee9cfd6d7b027e5f52021e451804fce96fd5 Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 03:09:30 -0400 Subject: [PATCH 088/120] fix the snapshot policy --- .../src/main/java/com/cloud/template/TemplateManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 15f982f5e430..48f5407f6398 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1951,11 +1951,11 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id"); s_logger.info("Creating snapshot for the tempalte creation"); - SnapshotVO snapshot = (SnapshotVO) volumeService.allocSnapshot(volumeId, null, curVm.getDisplayName() + "-Clone-" + nextTemplateId, null); + SnapshotVO snapshot = (SnapshotVO) volumeService.allocSnapshot(volumeId, Snapshot.MANUAL_POLICY_ID, curVm.getDisplayName() + "-Clone-" + nextTemplateId, null); if (snapshot == null) { throw new CloudRuntimeException("Unable to create a snapshot during the template creation recording"); } - Snapshot snapshotEntity = volumeService.takeSnapshot(volumeId, null, snapshot.getId(), caller, false, null, false, new HashMap<>()); + Snapshot snapshotEntity = volumeService.takeSnapshot(volumeId, Snapshot.MANUAL_POLICY_ID, snapshot.getId(), caller, false, null, false, new HashMap<>()); if (snapshotEntity == null) { throw new CloudRuntimeException("Error when creating the snapshot entity"); } From d4d7570ad46b24669f7c542c3dc2f2872d8a6552 Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 20:54:26 -0400 Subject: [PATCH 089/120] add automatic ip assignment- --- .../main/java/com/cloud/vm/UserVmManagerImpl.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index a2955491d742..1e07f2fbf8d3 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -52,10 +52,7 @@ import javax.xml.parsers.ParserConfigurationException; //import com.cloud.network.IpAddress; -import com.cloud.network.IpAddressManager; -import com.cloud.network.Network; -import com.cloud.network.NetworkModel; -import com.cloud.network.PhysicalNetwork; +import com.cloud.network.*; import com.cloud.network.security.SecurityGroupVO; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -5610,11 +5607,12 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio Account curAccount = _accountDao.findById(curVm.getAccountId()); long callingUserId = CallContext.current().getCallingUserId(); Account callerAccount = CallContext.current().getCallingAccount(); -// IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, curAccount.getId() == Account.ACCOUNT_ID_SYSTEM, callerAccount, callingUserId, dataCenter, null, null); +// IpAddress ipAddress = _ipAddrMgr.assignPublicIpAddress(zoneId, curVm.getPodIdToDeployIn(), callerAccount, VlanType.DirectAttached, ) + IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, false, callerAccount, callingUserId, dataCenter, null, null); String ipv6Address = null; String macAddress = null; -// IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), null, macAddress); - IpAddresses addr = new IpAddresses("172.20.0.98", ipv6Address, macAddress); + IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), ipv6Address, macAddress); +// IpAddresses addr = new IpAddresses("172.20.0.98", ipv6Address, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); List securityGroupList = _securityGroupMgr.getSecurityGroupsForVm(curVm.getId()); From 52f281035c13a311dc91692dda66c9a6055b0148 Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 21:01:17 -0400 Subject: [PATCH 090/120] add ip allocation --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 1e07f2fbf8d3..9ff1814ef36e 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5608,7 +5608,7 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio long callingUserId = CallContext.current().getCallingUserId(); Account callerAccount = CallContext.current().getCallingAccount(); // IpAddress ipAddress = _ipAddrMgr.assignPublicIpAddress(zoneId, curVm.getPodIdToDeployIn(), callerAccount, VlanType.DirectAttached, ) - IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, false, callerAccount, callingUserId, dataCenter, null, null); + IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, false, callerAccount, callingUserId, dataCenter, true, null); String ipv6Address = null; String macAddress = null; IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), ipv6Address, macAddress); From 1a475b3916d8549352f48be954957ace63feb113 Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 21:02:49 -0400 Subject: [PATCH 091/120] fix the check-style typo --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 9ff1814ef36e..8ecd7c1ca91e 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -52,7 +52,11 @@ import javax.xml.parsers.ParserConfigurationException; //import com.cloud.network.IpAddress; -import com.cloud.network.*; +import com.cloud.network.IpAddress; +import com.cloud.network.IpAddressManager; +import com.cloud.network.Network; +import com.cloud.network.NetworkModel; +import com.cloud.network.PhysicalNetwork; import com.cloud.network.security.SecurityGroupVO; import com.cloud.user.Account; import com.cloud.user.AccountManager; From b64c48bf3a8e7ab0e9c7ada9a72024a6ff8fb1ce Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 23:28:31 -0400 Subject: [PATCH 092/120] try null address for vm creation --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 8ecd7c1ca91e..636c9ddbf905 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5612,10 +5612,10 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio long callingUserId = CallContext.current().getCallingUserId(); Account callerAccount = CallContext.current().getCallingAccount(); // IpAddress ipAddress = _ipAddrMgr.assignPublicIpAddress(zoneId, curVm.getPodIdToDeployIn(), callerAccount, VlanType.DirectAttached, ) - IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, false, callerAccount, callingUserId, dataCenter, true, null); +// IpAddress ipAddress = _ipAddrMgr.allocateIp(curAccount, false, callerAccount, callingUserId, dataCenter, true, null); String ipv6Address = null; String macAddress = null; - IpAddresses addr = new IpAddresses(ipAddress.getVmIp(), ipv6Address, macAddress); + IpAddresses addr = new IpAddresses(null, ipv6Address, macAddress); // IpAddresses addr = new IpAddresses("172.20.0.98", ipv6Address, macAddress); long serviceOfferingId = curVm.getServiceOfferingId(); ServiceOffering serviceOffering = _serviceOfferingDao.findById(curVm.getId(), serviceOfferingId); From 6b145d17494d6467c71d7caab7db56195fbec832 Mon Sep 17 00:00:00 2001 From: junxuan Date: Wed, 7 Jul 2021 23:31:19 -0400 Subject: [PATCH 093/120] ignore unused ip --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 636c9ddbf905..4d23854009f6 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -50,9 +50,8 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; - //import com.cloud.network.IpAddress; -import com.cloud.network.IpAddress; +//import com.cloud.network.IpAddress; import com.cloud.network.IpAddressManager; import com.cloud.network.Network; import com.cloud.network.NetworkModel; From fbf37531d0312af3ed9d94f76330f0514625d351 Mon Sep 17 00:00:00 2001 From: junxuan Date: Thu, 8 Jul 2021 00:37:27 -0400 Subject: [PATCH 094/120] finish the network allocation --- .../src/main/java/com/cloud/template/TemplateManagerImpl.java | 2 +- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java index 48f5407f6398..79a7646b813e 100755 --- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java @@ -1979,7 +1979,7 @@ public VMTemplateVO createPrivateTemplateRecord(CloneVMCmd cmd, Account template VMTemplateVO privateTemplate = null; privateTemplate = new VMTemplateVO(nextTemplateId, name, ImageFormat.RAW, isPublic, featured, isExtractable, TemplateType.USER, null, true, 64, templateOwner.getId(), null, description, - true, guestOS.getId(), true, hyperType, null, new HashMap<>(){{put("template to be cleared", "yes");}}, false, false, false, false); + false, guestOS.getId(), true, hyperType, null, new HashMap<>(){{put("template to be cleared", "yes");}}, false, false, false, false); List stores = _imgStoreDao.findRegionImageStores(); if (!CollectionUtils.isEmpty(stores)) { privateTemplate.setCrossZones(true); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 4d23854009f6..46863728851c 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5665,7 +5665,6 @@ public UserVm recordVirtualMachineToDB(CloneVMCmd cmd) throws ConcurrentOperatio cmd.getCustomId(), new HashMap<>(), null, new HashMap<>(), dynamicScalingEnabled); } } - return vmResult; } From 63c7c5e9b61a0ce39013439e23117d2949018ae7 Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 9 Jul 2021 00:50:27 -0400 Subject: [PATCH 095/120] datadisk code added --- .../com/cloud/storage/VolumeApiService.java | 4 + .../main/java/com/cloud/vm/UserVmService.java | 3 +- .../api/command/user/vm/CloneVMCmd.java | 2 +- .../cloud/storage/VolumeApiServiceImpl.java | 7 + .../java/com/cloud/vm/UserVmManagerImpl.java | 140 ++++++++++++------ 5 files changed, 110 insertions(+), 46 deletions(-) diff --git a/api/src/main/java/com/cloud/storage/VolumeApiService.java b/api/src/main/java/com/cloud/storage/VolumeApiService.java index 5c4130158cd8..5ea49650ae37 100644 --- a/api/src/main/java/com/cloud/storage/VolumeApiService.java +++ b/api/src/main/java/com/cloud/storage/VolumeApiService.java @@ -21,6 +21,8 @@ import java.net.MalformedURLException; import java.util.Map; +import com.cloud.exception.StorageUnavailableException; +import org.apache.cloudstack.api.command.user.vm.CloneVMCmd; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; @@ -92,6 +94,8 @@ public interface VolumeApiService { Volume detachVolumeViaDestroyVM(long vmId, long volumeId); + Volume cloneDataVolume(CloneVMCmd cmd, long snapshotId, Volume volume) throws StorageUnavailableException; + Volume detachVolumeFromVM(DetachVolumeCmd cmd); Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup, Map tags) diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index 90f41d860ffa..74c090eb5f32 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -20,6 +20,7 @@ import java.util.Map; import java.util.Optional; +import com.cloud.storage.VolumeApiService; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; @@ -94,7 +95,7 @@ public interface UserVmService { * - the command specifying vmId to be cloned * @return the VM if cloneVM operation is successful * */ - Optional cloneVirtualMachine(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; + Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService volumeService) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; void checkCloneCondition(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ResourceAllocationException; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index cdd5cb342c4d..66414dc28969 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -146,7 +146,7 @@ public void execute() { try { CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); s_logger.info("starting actual VM id: " + getEntityId()); - result = _userVmService.cloneVirtualMachine(this); + result = _userVmService.cloneVirtualMachine(this, _volumeService); } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index a2b2a4978c0d..732ece2345db 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -31,6 +31,7 @@ import javax.inject.Inject; +import org.apache.cloudstack.api.command.user.vm.CloneVMCmd; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; @@ -900,6 +901,12 @@ public VolumeVO createVolume(CreateVolumeCmd cmd) { } } + @Override + public Volume cloneDataVolume(CloneVMCmd cmd, long snapshotId, Volume volume) throws StorageUnavailableException { + long vmId = cmd.getEntityId(); + return createVolumeFromSnapshot((VolumeVO) volume, snapshotId, vmId); + } + protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId, Long vmId) throws StorageUnavailableException { VolumeInfo createdVolume = null; SnapshotVO snapshot = _snapshotDao.findById(snapshotId); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 46863728851c..4be22defc2f6 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -22,19 +22,8 @@ import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -57,6 +46,7 @@ import com.cloud.network.NetworkModel; import com.cloud.network.PhysicalNetwork; import com.cloud.network.security.SecurityGroupVO; +import com.cloud.storage.*; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountService; @@ -68,6 +58,7 @@ import com.cloud.user.UserStatisticsVO; import com.cloud.user.UserVO; import com.cloud.user.VmDiskStatisticsVO; +import com.cloud.utils.db.*; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; @@ -125,15 +116,13 @@ import org.apache.cloudstack.query.QueryService; import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DettachCommand; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.*; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; +import org.owasp.esapi.util.CollectionsUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -273,26 +262,9 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.service.dao.ServiceOfferingDetailsDao; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.GuestOSVO; -import com.cloud.storage.ScopeType; -import com.cloud.storage.Snapshot; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolStatus; -import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.Volume; -import com.cloud.storage.VolumeApiService; -import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; import com.cloud.storage.dao.GuestOSDao; @@ -319,16 +291,6 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.crypt.RSAHelper; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.EntityManager; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.db.TransactionCallbackNoReturn; -import com.cloud.utils.db.TransactionCallbackWithException; -import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; -import com.cloud.utils.db.TransactionStatus; -import com.cloud.utils.db.UUIDManager; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; @@ -4590,11 +4552,101 @@ public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueExce _resourceLimitMgr.checkResourceLimit(activeOwner, ResourceType.primary_storage, totalSize); } + private VolumeVO saveDataDiskVolumeFromSnapShot(final Account owner, final Boolean displayVolume, final Long zoneId, final Long diskOfferingId, + final Storage.ProvisioningType provisioningType, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, final String volumeName, final String uuid, final Map details) { + return Transaction.execute((TransactionCallback) status -> { + VolumeVO volume = new VolumeVO(volumeName, -1, -1, -1, -1, new Long(-1), null, null, provisioningType, 0, Volume.Type.DATADISK); + volume.setPoolId(null); + volume.setUuid(uuid); + volume.setDataCenterId(zoneId); + volume.setPodId(null); + volume.setAccountId(owner.getId()); + volume.setDomainId(owner.getDomainId()); + volume.setDiskOfferingId(diskOfferingId); + volume.setSize(size); + volume.setMinIops(minIops); + volume.setMaxIops(maxIops); + volume.setInstanceId(null); + volume.setUpdated(new Date()); + volume.setDisplayVolume(displayVolume); + if (parentVolume != null) { + volume.setTemplateId(parentVolume.getTemplateId()); + volume.setFormat(parentVolume.getFormat()); + } else { + volume.setTemplateId(null); + } + + volume = _volsDao.persist(volume); + CallContext.current().setEventDetails("Volume Id: " + volume.getUuid()); + + // Increment resource count during allocation; if actual creation fails, + // decrement it + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume); + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize())); + return volume; + }); + } + @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CLONE, eventDescription = "clone vm", async = true) - public Optional cloneVirtualMachine(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, CloudRuntimeException, InsufficientCapacityException, ResourceAllocationException { + public Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService volumeService) throws ResourceUnavailableException, ConcurrentOperationException, CloudRuntimeException, InsufficientCapacityException, ResourceAllocationException { long vmId = cmd.getEntityId(); UserVmVO curVm = _vmDao.findById(vmId); + // create and attach data disk + long targetClonedVmId = cmd.getId(); + Account caller = CallContext.current().getCallingAccount(); + List dataDisks = _volsDao.findByInstanceAndType(targetClonedVmId, Volume.Type.DATADISK); + List createdSnapshots = new ArrayList<>(); + List createdVolumes = new ArrayList<>(); + long zoneId = cmd.getTargetVM().getDataCenterId(); + s_logger.info("Trying to attach data disk before starting the VM..."); + if (dataDisks.size() > 0) { + VolumeVO newDatadisk = null; + try { + for (VolumeVO dataDisk : dataDisks) { + long diskId = dataDisk.getId(); + SnapshotVO dataSnapShot = (SnapshotVO) volumeService.allocSnapshot(diskId, Snapshot.MANUAL_POLICY_ID, "DataDisk-Clone" + dataDisk.getName(), null); + if (dataSnapShot == null) { + throw new CloudRuntimeException("Unable to allocate snapshot of data disk: " + dataDisk.getId() + " name: " + dataDisk.getName()); + } + createdSnapshots.add(dataSnapShot); + SnapshotVO snapshotEntity = (SnapshotVO) volumeService.takeSnapshot(diskId, Snapshot.MANUAL_POLICY_ID, dataSnapShot.getId(), caller, false, null, false, new HashMap<>()); + if (snapshotEntity == null) { + throw new CloudRuntimeException("Error when creating the snapshot entity"); + } + if (snapshotEntity.getState() != Snapshot.State.BackedUp) { + throw new CloudRuntimeException("Async backup of snapshot happens during the clone for snapshot id: " + dataSnapShot.getId()); + } + long diskOfferingId = snapshotEntity.getDiskOfferingId(); + DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId); + Long minIops = snapshotEntity.getMinIops(); + Long maxIops = snapshotEntity.getMaxIops(); + Long size = snapshotEntity.getSize(); + Storage.ProvisioningType provisioningType = diskOffering.getProvisioningType(); + DataCenterVO dataCenter = _dcDao.findById(zoneId); + String volumeName = snapshotEntity.getName() + "-DataDisk-Volume"; + VolumeVO parentVolume = _volsDao.findByIdIncludingRemoved(snapshotEntity.getVolumeId()); + newDatadisk = saveDataDiskVolumeFromSnapShot(caller, false, zoneId, + diskOfferingId, provisioningType, size, minIops, maxIops, parentVolume, volumeName, _uuidMgr.generateUuid(Volume.class, null), new HashMap<>()); + VolumeVO volumeEntity = (VolumeVO) volumeService.cloneDataVolume(cmd, snapshotEntity.getId(), newDatadisk); + createdVolumes.add(volumeEntity); + } + for (VolumeVO createdVol : createdVolumes) { + ((VolumeApiServiceImpl) volumeService).attachVolumeToVM(vmId, createdVol.getId(), createdVol.getDeviceId()); + } + } catch (CloudRuntimeException e){ + // clear the created disks + s_logger.warn("data disk process failed during clone, clearing the temporary resources..."); + if (newDatadisk != null) { + _resourceLimitMgr.decrementResourceCount(caller.getId(), ResourceType.volume, false); + _resourceLimitMgr.decrementResourceCount(caller.getId(), ResourceType.primary_storage, false, new Long(newDatadisk.getSize())); + } + throw new CloudRuntimeException(e.getMessage()); + } finally { + // clear the temporary data snapshots + } + } + // start the VM if successfull Long podId = curVm.getPodIdToDeployIn(); Long clusterId = null; Long hostId = curVm.getHostId(); From f7cc3c93160afad5e4e198a147f23190420408c9 Mon Sep 17 00:00:00 2001 From: Hoang Nguyen Date: Fri, 9 Jul 2021 16:34:18 +0700 Subject: [PATCH 096/120] UI - zone wizard - fix undefined property when setting RBD primary storage (#5167) * zone wizard launch: fix undefined property RBD primary storage * simplycode by #4956 --- .../views/infra/zone/ZoneWizardLaunchZone.vue | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue index 7191f1935fdd..b51e976ff079 100644 --- a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue +++ b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue @@ -1271,8 +1271,8 @@ export default { params.zoneid = this.stepData.zoneReturned.id params.podId = this.stepData.podReturned.id params.clusterid = this.stepData.clusterReturned.id - params.name = this.prefillContent.primaryStorageName ? this.prefillContent.primaryStorageName.value : null - params.scope = this.prefillContent.primaryStorageScope ? this.prefillContent.primaryStorageScope.value : null + params.name = this.prefillContent.primaryStorageName?.value || null + params.scope = this.prefillContent.primaryStorageScope?.value || null if (params.scope === 'zone') { const hypervisor = this.prefillContent.hypervisor.value @@ -1283,79 +1283,79 @@ export default { } } - var server = this.prefillContent.primaryStorageServer ? this.prefillContent.primaryStorageServer.value : null + var server = this.prefillContent.primaryStorageServer?.value || null let url = '' const protocol = this.prefillContent.primaryStorageProtocol.value if (protocol === 'nfs') { - let path = this.prefillContent.primaryStoragePath.value + let path = this.prefillContent.primaryStoragePath?.value || '' if (path.substring(0, 1) !== '/') { path = '/' + path } url = this.nfsURL(server, path) } else if (protocol === 'SMB') { - let path = this.prefillContent.primaryStoragePath.value + let path = this.prefillContent.primaryStoragePath?.value || '' if (path.substring(0, 1) !== '/') { path = '/' + path } url = this.smbURL(server, path) - params['details[0].user'] = this.prefillContent.primaryStorageSMBUsername.value - params['details[0].password'] = this.prefillContent.primaryStorageSMBPassword.value - params['details[0].domain'] = this.prefillContent.primaryStorageSMBDomain.value + params['details[0].user'] = this.prefillContent.primaryStorageSMBUsername?.value || null + params['details[0].password'] = this.prefillContent.primaryStorageSMBPassword?.value || null + params['details[0].domain'] = this.prefillContent.primaryStorageSMBDomain?.value || null } else if (protocol === 'PreSetup') { let path = '' if (this.stepData.clusterReturned.hypervisortype === 'XenServer') { - path = this.prefillContent.primaryStorageSRLabel.value + path = this.prefillContent.primaryStorageSRLabel?.value || '' server = 'localhost' } else { - path = this.prefillContent.primaryStoragePath.value + path = this.prefillContent.primaryStoragePath?.value || '' } if (path.substring(0, 1) !== '/') { path = '/' + path } url = this.presetupURL(server, path) } else if (protocol === 'ocfs2') { - let path = this.prefillContent.primaryStoragePath.value + let path = this.prefillContent.primaryStoragePath?.value || '' if (path.substring(0, 1) !== '/') { path = '/' + path } url = this.ocfs2URL(server, path) } else if (protocol === 'SharedMountPoint') { - let path = this.prefillContent.primaryStoragePath.value + let path = this.prefillContent.primaryStoragePath?.value || '' if (path.substring(0, 1) !== '/') { path = '/' + path } url = this.sharedMountPointURL(server, path) } else if (protocol === 'clvm') { - let vg = this.prefillContent.primaryStorageVolumeGroup.value + let vg = this.prefillContent.primaryStorageVolumeGroup?.value || '' if (vg.substring(0, 1) !== '/') { vg = '/' + vg } url = this.clvmURL(vg) } else if (protocol === 'rbd') { - const rbdmonitor = this.prefillContent.primaryStorageRADOSMonitor.value - const rbdpool = this.prefillContent.primaryStorageRADOSPool.value - const rbdid = this.prefillContent.primaryStorageRADOSUser.value - const rbdsecret = this.prefillContent.primaryStorage.value + const rbdmonitor = this.prefillContent.primaryStorageRADOSMonitor?.value || '' + const rbdpool = this.prefillContent.primaryStorageRADOSPool?.value || '' + const rbdid = this.prefillContent.primaryStorageRADOSUser?.value || '' + const rbdsecret = this.prefillContent.primaryStorageRADOSSecret?.value || '' url = this.rbdURL(rbdmonitor, rbdpool, rbdid, rbdsecret) } else if (protocol === 'vmfs') { - let path = this.prefillContent.primaryStorageVmfsDatacenter.value + let path = this.prefillContent.primaryStorageVmfsDatacenter?.value || '' if (path.substring(0, 1) !== '/') { path = '/' + path } - path += '/' + this.prefillContent.primaryStorageVmfsDatastore.value + path += '/' + this.prefillContent.primaryStorageVmfsDatastore?.value || '' url = this.vmfsURL('dummy', path) } else { - let iqn = this.prefillContent.primaryStorageTargetIQN.value + let iqn = this.prefillContent.primaryStorageTargetIQN?.value || '' if (iqn.substring(0, 1) !== '/') { iqn = '/' + iqn } - const lun = this.prefillContent.primaryStorageLUN.value + const lun = this.prefillContent.primaryStorageLUN?.value || '' url = this.iscsiURL(server, iqn, lun) } params.url = url - params.tags = this.prefillContent.primaryStorageTags.value + params.tags = this.prefillContent.primaryStorageTags?.value || '' try { if (!this.stepData.stepMove.includes('createStoragePool')) { From 3fd92502bb31ebd247b48ea746f5b970c064e437 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Fri, 9 Jul 2021 15:11:30 +0530 Subject: [PATCH 097/120] Prevent starting a VM in destroyed state (or any state but Stopped) (#5165) * Prevent starting a VM in destroyed state (or any state but Stopped) --- .../main/java/com/cloud/vm/VirtualMachineManagerImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index 0cb766e7b6ee..9ec5779790a1 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -881,8 +881,9 @@ public Ternary doInTransaction(final } if (state != State.Stopped) { - s_logger.debug("VM " + vm + " is not in a state to be started: " + state); - return null; + String msg = String.format("Cannot start %s in %s state", vm, state); + s_logger.warn(msg); + throw new CloudRuntimeException(msg); } } From a8cfb77b2bcf6c7993efabb6ffe5642c6094e0c3 Mon Sep 17 00:00:00 2001 From: Gregor Riepl Date: Fri, 9 Jul 2021 19:27:09 +0200 Subject: [PATCH 098/120] Document cidrlist parameter deprecation (#4037) * Document cidrlist param deprecation in CreatePortForwardingRule and CreateFirewallRule Co-authored-by: dahn --- .../api/command/user/firewall/CreateFirewallRuleCmd.java | 2 +- .../api/command/user/firewall/CreatePortForwardingRuleCmd.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java index ea5657cf9657..e0310a184122 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java @@ -73,7 +73,7 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of firewall rule") private Integer publicEndPort; - @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the CIDR list to forward traffic from. Multiple entries must be separated by a single comma character (,).") + @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the CIDR list to forward traffic from. Multiple entries must be separated by a single comma character (,). This parameter is deprecated. Do not use.") private List cidrlist; @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent") diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java index c569afc7460d..f3c9e590851d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java @@ -108,7 +108,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P description = "the ID of the virtual machine for the port forwarding rule") private Long virtualMachineId; - @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from. Multiple entries must be separated by a single comma character (,).") + @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from. Multiple entries must be separated by a single comma character (,). This parameter is deprecated. Do not use.") private List cidrlist; @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end public port is automatically created; " From fcb81528deba61fee9abb9e9a0db7e2f8149c0d9 Mon Sep 17 00:00:00 2001 From: junxuan Date: Fri, 9 Jul 2021 14:51:23 -0400 Subject: [PATCH 099/120] fix the import typos --- .../java/com/cloud/vm/UserVmManagerImpl.java | 56 +++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 4be22defc2f6..f06f8cdad073 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -22,8 +22,19 @@ import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -46,7 +57,24 @@ import com.cloud.network.NetworkModel; import com.cloud.network.PhysicalNetwork; import com.cloud.network.security.SecurityGroupVO; -import com.cloud.storage.*; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.GuestOSVO; +import com.cloud.storage.ScopeType; +import com.cloud.storage.Snapshot; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.Storage; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VMTemplateZoneVO; +import com.cloud.storage.Volume; +import com.cloud.storage.VolumeApiService; +import com.cloud.storage.VolumeApiServiceImpl; +import com.cloud.storage.VolumeVO; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountService; @@ -58,7 +86,17 @@ import com.cloud.user.UserStatisticsVO; import com.cloud.user.UserVO; import com.cloud.user.VmDiskStatisticsVO; -import com.cloud.utils.db.*; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.EntityManager; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionCallbackWithException; +import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn; +import com.cloud.utils.db.TransactionStatus; +import com.cloud.utils.db.UUIDManager; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; @@ -116,13 +154,15 @@ import org.apache.cloudstack.query.QueryService; import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DettachCommand; -import org.apache.cloudstack.storage.datastore.db.*; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; -import org.owasp.esapi.util.CollectionsUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -4468,9 +4508,11 @@ protected String validateUserData(String userData, HTTPMethod httpmethod) { @Override public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueException, ResourceUnavailableException, CloudRuntimeException, ResourceAllocationException { + if (cmd.getAccountName() != null && cmd.getDomainId() == null) { throw new InvalidParameterValueException("You must input the domainId together with the account name"); } + final DomainVO domain = cmd.getDomainId() == null ? null : _domainDao.findById(cmd.getDomainId()); final Account account = cmd.getAccountName() == null ? null : _accountService.getActiveAccountByName(cmd.getAccountName(), cmd.getDomainId()); if (domain != null && account != null) { @@ -4492,6 +4534,10 @@ public void checkCloneCondition(CloneVMCmd cmd) throws InvalidParameterValueExce if (vmStatus.getHypervisorType() != HypervisorType.KVM && vmStatus.getHypervisorType() != HypervisorType.Simulator) { throw new CloudRuntimeException("The clone operation is only supported on KVM and Simulator!"); } + String kvmEnabled = _configDao.getValue("kvm.snapshot.enabled"); + if (kvmEnabled == null || !kvmEnabled.equalsIgnoreCase("true")) { + throw new CloudRuntimeException("Clone VM is not supported, as snapshots are disabled"); + } Long accountId = curVm.getAccountId(); Account vmOwner = _accountDao.findById(accountId); if (vmOwner == null) { From 78d5295b926d0d6607d7e64310b123dd9906af2e Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 11 Jul 2021 03:29:34 -0400 Subject: [PATCH 100/120] fix the service api impl --- api/src/main/java/com/cloud/storage/VolumeApiService.java | 2 ++ .../main/java/com/cloud/storage/VolumeApiServiceImpl.java | 5 +++++ server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/cloud/storage/VolumeApiService.java b/api/src/main/java/com/cloud/storage/VolumeApiService.java index 5ea49650ae37..c9a5139043f6 100644 --- a/api/src/main/java/com/cloud/storage/VolumeApiService.java +++ b/api/src/main/java/com/cloud/storage/VolumeApiService.java @@ -105,6 +105,8 @@ Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account acc Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long owner, String chainInfo); + Volume attachVolumeToVm(CloneVMCmd cmd, Long volumeId, Long deviceId); + /** * Extracts the volume to a particular location. * diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 732ece2345db..95072721109a 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -1670,6 +1670,11 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device return newVol; } + @Override + public Volume attachVolumeToVm(CloneVMCmd cmd, Long volumeId, Long deviceId) { + return attachVolumeToVM(cmd.getEntityId(), volumeId, deviceId); + } + public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) { Account caller = CallContext.current().getCallingAccount(); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index f06f8cdad073..471b88c5815d 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4678,7 +4678,8 @@ public Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService vol createdVolumes.add(volumeEntity); } for (VolumeVO createdVol : createdVolumes) { - ((VolumeApiServiceImpl) volumeService).attachVolumeToVM(vmId, createdVol.getId(), createdVol.getDeviceId()); +// ((VolumeApiServiceImpl) volumeService).attachVolumeToVM(vmId, createdVol.getId(), createdVol.getDeviceId()); + volumeService.attachVolumeToVm(cmd, createdVol.getId(), createdVol.getDeviceId()); } } catch (CloudRuntimeException e){ // clear the created disks From 1414e3a2621bfd5d9e15b1125835262b7014d4c0 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 11 Jul 2021 14:21:03 -0400 Subject: [PATCH 101/120] clear unused import --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 471b88c5815d..9a940d402d4d 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -73,7 +73,6 @@ import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.Volume; import com.cloud.storage.VolumeApiService; -import com.cloud.storage.VolumeApiServiceImpl; import com.cloud.storage.VolumeVO; import com.cloud.user.Account; import com.cloud.user.AccountManager; From 877172893d2f555b50b5b8a70ca7ae0a383a0839 Mon Sep 17 00:00:00 2001 From: junxuan Date: Sun, 11 Jul 2021 15:48:16 -0400 Subject: [PATCH 102/120] ake the data disk shown --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 9a940d402d4d..7b0a2ff7d8ac 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4671,7 +4671,7 @@ public Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService vol DataCenterVO dataCenter = _dcDao.findById(zoneId); String volumeName = snapshotEntity.getName() + "-DataDisk-Volume"; VolumeVO parentVolume = _volsDao.findByIdIncludingRemoved(snapshotEntity.getVolumeId()); - newDatadisk = saveDataDiskVolumeFromSnapShot(caller, false, zoneId, + newDatadisk = saveDataDiskVolumeFromSnapShot(caller, true, zoneId, diskOfferingId, provisioningType, size, minIops, maxIops, parentVolume, volumeName, _uuidMgr.generateUuid(Volume.class, null), new HashMap<>()); VolumeVO volumeEntity = (VolumeVO) volumeService.cloneDataVolume(cmd, snapshotEntity.getId(), newDatadisk); createdVolumes.add(volumeEntity); From c6279ce1c70a5a74c877441addb4fa3a6d1bc0a1 Mon Sep 17 00:00:00 2001 From: junxuan Date: Mon, 12 Jul 2021 18:08:53 -0400 Subject: [PATCH 103/120] data disk snapshot clearance and exception handler --- .../main/java/com/cloud/vm/UserVmService.java | 3 +- .../api/command/user/vm/CloneVMCmd.java | 5 ++-- .../java/com/cloud/vm/UserVmManagerImpl.java | 29 ++++++++++++++----- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java index 74c090eb5f32..da8c2373ca79 100644 --- a/api/src/main/java/com/cloud/vm/UserVmService.java +++ b/api/src/main/java/com/cloud/vm/UserVmService.java @@ -21,6 +21,7 @@ import java.util.Optional; import com.cloud.storage.VolumeApiService; +import com.cloud.storage.snapshot.SnapshotApiService; import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; @@ -95,7 +96,7 @@ public interface UserVmService { * - the command specifying vmId to be cloned * @return the VM if cloneVM operation is successful * */ - Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService volumeService) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; + Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService volumeService, SnapshotApiService snapshotService) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; void checkCloneCondition(CloneVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ResourceAllocationException; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java index 66414dc28969..136f5b9ce087 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/CloneVMCmd.java @@ -108,6 +108,7 @@ public void create() throws ResourceAllocationException { s_logger.info("The template id recorded is: " + template.getId()); setTemporaryTemlateId(template.getId()); _templateService.createPrivateTemplate(this); + _snapshotService.deleteSnapshot(getTemporarySnapShotId()); UserVm vmRecord = _userVmService.recordVirtualMachineToDB(this); if (vmRecord == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "unable to record a new VM to db!"); @@ -146,7 +147,7 @@ public void execute() { try { CallContext.current().setEventDetails("Vm Id for full clone: " + getEntityId()); s_logger.info("starting actual VM id: " + getEntityId()); - result = _userVmService.cloneVirtualMachine(this, _volumeService); + result = _userVmService.cloneVirtualMachine(this, _volumeService, _snapshotService); } catch (ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); @@ -160,7 +161,7 @@ public void execute() { } result.ifPresentOrElse((userVm)-> { UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), "virtualmachine", result.get()).get(0); - response.setResponseName("test_clone"); + response.setResponseName("full_clone"); setResponseObject(response); }, ()-> { throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, "failed to clone VM: " + getId()); diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 7b0a2ff7d8ac..d5691007469b 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -74,6 +74,7 @@ import com.cloud.storage.Volume; import com.cloud.storage.VolumeApiService; import com.cloud.storage.VolumeVO; +import com.cloud.storage.snapshot.SnapshotApiService; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountService; @@ -4634,7 +4635,7 @@ private VolumeVO saveDataDiskVolumeFromSnapShot(final Account owner, final Boole @Override @ActionEvent(eventType = EventTypes.EVENT_VM_CLONE, eventDescription = "clone vm", async = true) - public Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService volumeService) throws ResourceUnavailableException, ConcurrentOperationException, CloudRuntimeException, InsufficientCapacityException, ResourceAllocationException { + public Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService volumeService, SnapshotApiService snapshotService) throws ResourceUnavailableException, ConcurrentOperationException, CloudRuntimeException, InsufficientCapacityException, ResourceAllocationException { long vmId = cmd.getEntityId(); UserVmVO curVm = _vmDao.findById(vmId); // create and attach data disk @@ -4676,22 +4677,34 @@ public Optional cloneVirtualMachine(CloneVMCmd cmd, VolumeApiService vol VolumeVO volumeEntity = (VolumeVO) volumeService.cloneDataVolume(cmd, snapshotEntity.getId(), newDatadisk); createdVolumes.add(volumeEntity); } - for (VolumeVO createdVol : createdVolumes) { -// ((VolumeApiServiceImpl) volumeService).attachVolumeToVM(vmId, createdVol.getId(), createdVol.getDeviceId()); - volumeService.attachVolumeToVm(cmd, createdVol.getId(), createdVol.getDeviceId()); - } } catch (CloudRuntimeException e){ - // clear the created disks s_logger.warn("data disk process failed during clone, clearing the temporary resources..."); + for (VolumeVO dataDiskToClear : createdVolumes) { + volumeService.destroyVolume(dataDiskToClear.getId(), caller, true, false); + } + // clear the created disks if (newDatadisk != null) { - _resourceLimitMgr.decrementResourceCount(caller.getId(), ResourceType.volume, false); - _resourceLimitMgr.decrementResourceCount(caller.getId(), ResourceType.primary_storage, false, new Long(newDatadisk.getSize())); + volumeService.destroyVolume(newDatadisk.getId(), caller, true, false); } throw new CloudRuntimeException(e.getMessage()); } finally { // clear the temporary data snapshots + for (Snapshot snapshotLeftOver : createdSnapshots) { + snapshotService.deleteSnapshot(snapshotLeftOver.getId()); + } } } + + for (VolumeVO createdVol : createdVolumes) { + try { + volumeService.attachVolumeToVm(cmd, createdVol.getId(), createdVol.getDeviceId()); + } catch (CloudRuntimeException e) { + s_logger.warn("data disk: " + createdVol.getId() + " attachment to VM " + vmId + " failed due to" + e.getMessage()); + s_logger.info("Clearing the data disk: " + createdVol.getId()); + volumeService.destroyVolume(createdVol.getId(), caller, true, true); + } + } + // start the VM if successfull Long podId = curVm.getPodIdToDeployIn(); Long clusterId = null; From 2e376f219596e31ee985be9185248cca0b635070 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Tue, 13 Jul 2021 07:22:47 +0530 Subject: [PATCH 104/120] marvin: make deployDataCenter.py script py2/py3 compatible (#5139) --- tools/marvin/marvin/deployDataCenter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index c3e8511141f4..868768982f7d 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -71,9 +71,9 @@ def __persistDcConfig(self): ts = strftime("%b_%d_%Y_%H_%M_%S", localtime()) dc_file_path = "dc_entries_" + str(ts) + ".obj" - file_to_write = open(dc_file_path, 'w') + file_to_write = open(dc_file_path, 'wb') if file_to_write: - pickle.dump(self.__cleanUp, file_to_write) + pickle.dump(self.__cleanUp, file_to_write, protocol=0) print("\n=== Data Center Settings are dumped to %s===" % dc_file_path) self.__tcRunLogger.debug("\n=== Data Center Settings are dumped to %s===" % dc_file_path) except Exception as e: From b5d75352f234eb8d2d63b25bfed695ba22362714 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Tue, 13 Jul 2021 13:03:40 +0530 Subject: [PATCH 105/120] expunge vm: Allow expunging a VM in destroyed state (#5183) --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index c1743e74623d..bda752ded338 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -3011,7 +3011,7 @@ public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, C throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); } - if (vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { + if ((vm.getState() == State.Destroyed && !expunge) || vm.getState() == State.Expunging) { s_logger.debug("Vm id=" + vmId + " is already destroyed"); return vm; } From ca78f5b38687bee264d9df2212e8ae4d0cac9a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Beims=20Br=C3=A4scher?= Date: Tue, 13 Jul 2021 17:35:59 -0300 Subject: [PATCH 106/120] Enhance log messages with host name (#4575) * Enhance log messages with hostName * Use host.toString() on most of host logs. * Remove redundant "Host" in logs and enhance logs * duplicated "for" * Adopt String.format, and enhance code * Address reviews enhancing log messages Update server/src/main/java/com/cloud/resource/ResourceManagerImpl.java -- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java -- server/src/main/java/com/cloud/resource/RollingMaintenanceManagerImpl.java Co-authored-by: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> * Fix String.format issue and change log message from debug to warn * Fix checkstyle issue * Fix string.format log * Address review: enhance logs * Enhance log of hosts in maintenance avoid list * Remove "VM" on logs as vm.toString() already appends VM-
* Add more details of the VM when postStateTransitionEvent * Address reviewer and enhance VMInstanceVO.toString() Co-authored-by: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> --- .../manager/ClusteredAgentManagerImpl.java | 2 +- .../cloud/vm/VirtualMachineManagerImpl.java | 33 ++++++++----- .../src/main/java/com/cloud/dc/ClusterVO.java | 5 ++ .../main/java/com/cloud/vm/VMInstanceVO.java | 2 +- .../cloud/capacity/CapacityManagerImpl.java | 7 ++- .../network/element/VirtualRouterElement.java | 5 +- .../cloud/resource/ResourceManagerImpl.java | 49 ++++++++++--------- .../RollingMaintenanceManagerImpl.java | 38 +++++++------- .../java/com/cloud/vm/UserVmManagerImpl.java | 2 +- .../agent/lb/IndirectAgentLBServiceImpl.java | 2 +- .../OutOfBandManagementServiceImpl.java | 32 ++++++------ 11 files changed, 100 insertions(+), 77 deletions(-) diff --git a/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentManagerImpl.java index 7a16971ee71d..fa24df290d34 100644 --- a/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentManagerImpl.java @@ -286,7 +286,7 @@ protected AgentAttache createAttacheForConnect(final HostVO host, final Link lin @Override protected AgentAttache createAttacheForDirectConnect(final Host host, final ServerResource resource) { - s_logger.debug("create ClusteredDirectAgentAttache for " + host.getId()); + s_logger.debug(String.format("Create ClusteredDirectAgentAttache for %s.", host)); final DirectAgentAttache attache = new ClusteredDirectAgentAttache(this, host.getId(), host.getName(), _nodeId, resource, host.isInMaintenanceStates()); AgentAttache old = null; synchronized (_agents) { diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index 9ec5779790a1..eca0852060d8 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -4346,19 +4346,25 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI throws ResourceUnavailableException, ConcurrentOperationException { VMInstanceVO vm = _vmDao.findByUuid(vmUuid); - s_logger.info("Migrating " + vm + " to " + dest); + s_logger.info(String.format("Migrating %s to %s", vm, dest)); vm.getServiceOfferingId(); final long dstHostId = dest.getHost().getId(); final Host fromHost = _hostDao.findById(srcHostId); + Host srcHost = _hostDao.findById(srcHostId); if (fromHost == null) { - s_logger.info("Unable to find the host to migrate from: " + srcHostId); - throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId); + String logMessageUnableToFindHost = String.format("Unable to find host to migrate from %s.", srcHost); + s_logger.info(logMessageUnableToFindHost); + throw new CloudRuntimeException(logMessageUnableToFindHost); } - if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) { - s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dstHostId); - throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId()); + Host dstHost = _hostDao.findById(dstHostId); + long destHostClusterId = dest.getCluster().getId(); + long fromHostClusterId = fromHost.getClusterId(); + if (fromHostClusterId != destHostClusterId) { + String logMessageHostsOnDifferentCluster = String.format("Source and destination host are not in same cluster, unable to migrate to %s", srcHost); + s_logger.info(logMessageHostsOnDifferentCluster); + throw new CloudRuntimeException(logMessageHostsOnDifferentCluster); } final VirtualMachineGuru vmGuru = getVmGuru(vm); @@ -4475,13 +4481,13 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI try { _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null); } catch (final AgentUnavailableException e) { - s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId); + s_logger.error(String.format("Unable to cleanup source %s. ", srcHost), e); } cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true); throw new CloudRuntimeException("Unable to complete migration for " + vm); } } catch (final OperationTimedoutException e) { - s_logger.debug("Error while checking the vm " + vm + " on host " + dstHostId, e); + s_logger.debug(String.format("Error while checking the %s on %s", vm, dstHost), e); } migrated = true; @@ -4489,9 +4495,10 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI if (!migrated) { s_logger.info("Migration was unsuccessful. Cleaning up: " + vm); - _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), - "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " + - dest.getPod().getName(), "Migrate Command failed. Please check logs."); + String alertSubject = String.format("Unable to migrate %s from %s in Zone [%s] and Pod [%s].", + vm.getInstanceName(), fromHost, dest.getDataCenter().getName(), dest.getPod().getName()); + String alertBody = "Migrate Command failed. Please check logs."; + _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), alertSubject, alertBody); try { _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null); } catch (final AgentUnavailableException ae) { @@ -4841,6 +4848,8 @@ private void handlePowerOnReportWithNoPendingJobsOnVM(final VMInstanceVO vm) { // 3) handle out of sync stationary states, marking VM from Stopped to Running with // alert messages // + Host host = _hostDao.findById(vm.getHostId()); + Host poweredHost = _hostDao.findById(vm.getPowerHostId()); switch (vm.getState()) { case Starting: s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-on report while there is no pending jobs on it"); @@ -4862,7 +4871,7 @@ private void handlePowerOnReportWithNoPendingJobsOnVM(final VMInstanceVO vm) { case Running: try { if (vm.getHostId() != null && vm.getHostId().longValue() != vm.getPowerHostId().longValue()) { - s_logger.info("Detected out of band VM migration from host " + vm.getHostId() + " to host " + vm.getPowerHostId()); + s_logger.info(String.format("Detected out of band VM migration from %s to %s", host, poweredHost)); } stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId()); } catch (final NoTransitionException e) { diff --git a/engine/schema/src/main/java/com/cloud/dc/ClusterVO.java b/engine/schema/src/main/java/com/cloud/dc/ClusterVO.java index 2a76789136a9..f60765e28566 100644 --- a/engine/schema/src/main/java/com/cloud/dc/ClusterVO.java +++ b/engine/schema/src/main/java/com/cloud/dc/ClusterVO.java @@ -196,4 +196,9 @@ public void setUuid(String uuid) { public PartitionType partitionType() { return PartitionType.Cluster; } + + @Override + public String toString() { + return String.format("Cluster {id: \"%s\", name: \"%s\", uuid: \"%s\"}", id, name, uuid); + } } diff --git a/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java index aa2e7360bf4b..afc7134990c9 100644 --- a/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java +++ b/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java @@ -506,7 +506,7 @@ public void setRemoved(Date removed) { @Override public String toString() { - return String.format("VM instance {\"id\": \"%s\", \"name\": \"%s\", \"uuid\": \"%s\", \"type\"=\"%s\"}", id, getInstanceName(), uuid, type); + return String.format("VM instance {id: \"%s\", name: \"%s\", uuid: \"%s\", type=\"%s\"}", id, getInstanceName(), uuid, type); } @Override diff --git a/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java b/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java index a5c1f3b4927e..05ea9fd94ca2 100644 --- a/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java +++ b/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java @@ -926,8 +926,11 @@ public boolean postStateTransitionEvent(StateMachine2.Transition t State oldState = transition.getCurrentState(); State newState = transition.getToState(); Event event = transition.getEvent(); - s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event + "vm's original host id: " + vm.getLastHostId() + - " new host id: " + vm.getHostId() + " host id before state transition: " + oldHostId); + Host lastHost = _hostDao.findById(vm.getLastHostId()); + Host oldHost = _hostDao.findById(oldHostId); + Host newHost = _hostDao.findById(vm.getHostId()); + s_logger.debug(String.format("%s state transited from [%s] to [%s] with event [%s]. VM's original host: %s, new host: %s, host before state transition: %s", vm, oldState, + newState, event, lastHost, newHost, oldHost)); if (oldState == State.Starting) { if (newState != State.Running) { diff --git a/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java b/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java index 9191ddddb5b9..d101a5e4f607 100644 --- a/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java @@ -411,12 +411,13 @@ public boolean stopVpn(final RemoteAccessVpn vpn) throws ResourceUnavailableExce if (canHandle(network, Service.Vpn)) { final List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't " + "exist in the network " + network.getId()); + s_logger.debug(String.format("There is no virtual router in network [uuid: %s, name: %s], it is not necessary to stop the VPN on backend.", + network.getUuid(), network.getName())); return true; } return _routerMgr.deleteRemoteAccessVpn(network, vpn, routers); } else { - s_logger.debug("Element " + getName() + " doesn't handle removeVpn command"); + s_logger.debug(String.format("Element %s doesn't handle removeVpn command", getName())); return false; } } diff --git a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java index ca3505fb6800..488be99e32da 100755 --- a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java @@ -909,6 +909,7 @@ public void doInTransactionWithoutResult(final TransactionStatus status) { host.setClusterId(null); _hostDao.update(host.getId(), host); + Host hostRemoved = _hostDao.findById(hostId); _hostDao.remove(hostId); if (clusterId != null) { final List hosts = listAllHostsInCluster(clusterId); @@ -922,7 +923,7 @@ public void doInTransactionWithoutResult(final TransactionStatus status) { try { resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId); } catch (final NoTransitionException e) { - s_logger.debug("Cannot transmit host " + host.getId() + " to Enabled state", e); + s_logger.debug(String.format("Cannot transit %s to Enabled state", host), e); } // Delete the associated entries in host ref table @@ -947,7 +948,7 @@ public void doInTransactionWithoutResult(final TransactionStatus status) { storagePool.setClusterId(null); _storagePoolDao.update(poolId, storagePool); _storagePoolDao.remove(poolId); - s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId); + s_logger.debug(String.format("Local storage [id: %s] is removed as a part of %s removal", poolId, hostRemoved.toString())); } } @@ -1278,7 +1279,7 @@ private boolean doMaintain(final long hostId) { try { resourceStateTransitTo(host, ResourceState.Event.AdminAskMaintenance, _nodeId); } catch (final NoTransitionException e) { - final String err = "Cannot transmit resource state of host " + host.getId() + " to " + ResourceState.Maintenance; + final String err = String.format("Cannot transit resource state of %s to %s", host, ResourceState.Maintenance); s_logger.debug(err, e); throw new CloudRuntimeException(err + e.getMessage()); } @@ -1530,7 +1531,7 @@ protected boolean setHostIntoPrepareForMaintenanceAfterErrorsFixed(HostVO host) protected boolean attemptMaintain(HostVO host) throws NoTransitionException { final long hostId = host.getId(); - s_logger.info("Attempting maintenance for host " + host.getName()); + s_logger.info(String.format("Attempting maintenance for %s", host)); // Step 0: First gather if VMs have pending HAWork for migration with retries left. final List allVmsOnHost = _vmDao.listByHostId(hostId); @@ -1538,7 +1539,7 @@ protected boolean attemptMaintain(HostVO host) throws NoTransitionException { boolean hasPendingMigrationRetries = false; for (VMInstanceVO vmInstanceVO : allVmsOnHost) { if (_haMgr.hasPendingMigrationsWork(vmInstanceVO.getId())) { - s_logger.info("Attempting maintenance for " + host + " found pending migration for VM " + vmInstanceVO); + s_logger.info(String.format("Attempting maintenance for %s found pending migration for %s.", host, vmInstanceVO)); hasPendingMigrationRetries = true; break; } @@ -1595,7 +1596,7 @@ public boolean checkAndMaintain(final long hostId) { hostInMaintenance = attemptMaintain(host); } } catch (final NoTransitionException e) { - s_logger.debug("Cannot transmit host " + host.getId() + " to Maintenance state", e); + s_logger.warn(String.format("Cannot transit %s from %s to Maintenance state.", host, host.getResourceState()), e); } return hostInMaintenance; } @@ -2062,12 +2063,12 @@ protected HostVO createHostVO(final StartupCommand[] cmds, final ServerResource /* Agent goes to Connecting status */ _agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, _nodeId); } catch (final Exception e) { - s_logger.debug("Cannot transmit host " + host.getId() + " to Creating state", e); + s_logger.debug(String.format("Cannot transit %s to Creating state", host), e); _agentMgr.agentStatusTransitTo(host, Status.Event.Error, _nodeId); try { resourceStateTransitTo(host, ResourceState.Event.Error, _nodeId); } catch (final NoTransitionException e1) { - s_logger.debug("Cannot transmit host " + host.getId() + "to Error state", e); + s_logger.debug(String.format("Cannot transit %s to Error state", host), e); } } @@ -2202,7 +2203,7 @@ private Host createHostAndAgent(final ServerResource resource, final Map " + host.getUuid() + " / " + host.getId() + ". Please make sure you are still able to connect to your hosts."); + throw new CloudRuntimeException( + String.format("CloudStack failed to update the password of %s. Please make sure you are still able to connect to your hosts.", host)); } } } @@ -2797,8 +2799,7 @@ public boolean migrateAwayFailed(final long hostId, final long vmId) { ". Emitting event UnableToMigrate."); return resourceStateTransitTo(host, ResourceState.Event.UnableToMigrate, _nodeId); } catch (final NoTransitionException e) { - s_logger.debug("No next resource state for host " + host.getId() + " while current state is " + host.getResourceState() + " with event " + - ResourceState.Event.UnableToMigrate, e); + s_logger.debug(String.format("No next resource state for %s while current state is [%s] with event %s", host, host.getResourceState(), ResourceState.Event.UnableToMigrate), e); return false; } } @@ -3117,7 +3118,7 @@ public HashMap> getGPUStatistics(final Ho return null; } if (answer == null || !answer.getResult()) { - final String msg = "Unable to obtain GPU stats for host " + host.getName(); + final String msg = String.format("Unable to obtain GPU stats for %s", host); s_logger.warn(msg); return null; } else { diff --git a/server/src/main/java/com/cloud/resource/RollingMaintenanceManagerImpl.java b/server/src/main/java/com/cloud/resource/RollingMaintenanceManagerImpl.java index 0bc88276fad7..80a243156aa0 100644 --- a/server/src/main/java/com/cloud/resource/RollingMaintenanceManagerImpl.java +++ b/server/src/main/java/com/cloud/resource/RollingMaintenanceManagerImpl.java @@ -395,7 +395,7 @@ private Ternary performMaintenanceStageOnHost(Host hos * @throws AgentUnavailableException */ private void putHostIntoMaintenance(Host host) throws InterruptedException, AgentUnavailableException { - s_logger.debug("Trying to set the host " + host.getId() + " into maintenance"); + s_logger.debug(String.format("Trying to set %s into maintenance", host)); PrepareForMaintenanceCmd cmd = new PrepareForMaintenanceCmd(); cmd.setId(host.getId()); resourceManager.maintain(cmd); @@ -423,9 +423,9 @@ private void enableClusterIfDisabled(Cluster cluster, Set disabledClusters private Ternary reCheckCapacityBeforeMaintenanceOnHost(Cluster cluster, Host host, Boolean forced, List hostsSkipped) { Pair capacityCheckBeforeMaintenance = performCapacityChecksBeforeHostInMaintenance(host, cluster); if (!capacityCheckBeforeMaintenance.first()) { - String errorMsg = "Capacity check failed for host " + host.getUuid() + ": " + capacityCheckBeforeMaintenance.second(); + String errorMsg = String.format("Capacity check failed for %s: %s", host, capacityCheckBeforeMaintenance.second()); if (forced) { - s_logger.info("Skipping host " + host.getUuid() + " as: " + errorMsg); + s_logger.info(String.format("Skipping %s as: %s", host, errorMsg)); hostsSkipped.add(new HostSkipped(host, errorMsg)); return new Ternary<>(true, true, capacityCheckBeforeMaintenance.second()); } @@ -439,9 +439,9 @@ private Ternary reCheckCapacityBeforeMaintenanceOnHost */ private boolean isMaintenanceStageAvoided(Host host, Map hostsToAvoidMaintenance, List hostsSkipped) { if (hostsToAvoidMaintenance.containsKey(host.getId())) { - s_logger.debug("Host " + host.getId() + " is not being put into maintenance, skipping it"); HostSkipped hostSkipped = new HostSkipped(host, hostsToAvoidMaintenance.get(host.getId())); hostsSkipped.add(hostSkipped); + s_logger.debug(String.format("%s is in avoid maintenance list [hosts skipped: %d], skipping its maintenance.", host, hostsSkipped.size())); return true; } return false; @@ -468,7 +468,7 @@ private Ternary performPreMaintenanceStageOnHost(Host return new Ternary<>(true, false, result.second()); } if (result.third() && !hostsToAvoidMaintenance.containsKey(host.getId())) { - s_logger.debug("Host " + host.getId() + " added to the avoid maintenance set"); + logHostAddedToAvoidMaintenanceSet(host); hostsToAvoidMaintenance.put(host.getId(), "Pre-maintenance stage set to avoid maintenance"); } return new Ternary<>(false, false, result.second()); @@ -491,7 +491,7 @@ private boolean isMaintenanceScriptDefinedOnHost(Host host, List ho RollingMaintenanceAnswer answer = (RollingMaintenanceAnswer) agentManager.send(host.getId(), new RollingMaintenanceCommand(true)); return answer.isMaintenaceScriptDefined(); } catch (AgentUnavailableException | OperationTimedoutException e) { - String msg = "Could not check for maintenance script on host " + host.getId() + " due to: " + e.getMessage(); + String msg = String.format("Could not check for maintenance script on %s due to: %s", host, e.getMessage()); s_logger.error(msg, e); return false; } @@ -537,8 +537,8 @@ private Ternary sendRollingMaintenanceCommandToHost(Ho answer = agentManager.send(host.getId(), cmd); } catch (AgentUnavailableException | OperationTimedoutException e) { // Agent may be restarted on the scripts - continue polling until it is up - String msg = "Cannot send command to host: " + host.getId() + ", waiting " + pingInterval + "ms - " + e.getMessage(); - s_logger.warn(msg); + String msg = String.format("Cannot send command to %s, waiting %sms - %s", host, pingInterval, e.getMessage()); + s_logger.warn(msg, e); cmd.setStarted(true); Thread.sleep(pingInterval); timeSpent += pingInterval; @@ -571,12 +571,16 @@ private void performPreFlightChecks(List hosts, int timeout, String payloa for (Host host : hosts) { Ternary result = performStageOnHost(host, Stage.PreFlight, timeout, payload, forced); if (result.third() && !hostsToAvoidMaintenance.containsKey(host.getId())) { - s_logger.debug("Host " + host.getId() + " added to the avoid maintenance set"); + logHostAddedToAvoidMaintenanceSet(host); hostsToAvoidMaintenance.put(host.getId(), "Pre-flight stage set to avoid maintenance"); } } } + private void logHostAddedToAvoidMaintenanceSet(Host host) { + s_logger.debug(String.format("%s added to the avoid maintenance set.", host)); + } + /** * Capacity checks on hosts */ @@ -584,7 +588,7 @@ private void performCapacityChecks(Cluster cluster, List hosts, Boolean fo for (Host host : hosts) { Pair result = performCapacityChecksBeforeHostInMaintenance(host, cluster); if (!result.first() && !forced) { - throw new CloudRuntimeException("Capacity check failed for host " + host.getUuid() + ": " + result.second()); + throw new CloudRuntimeException(String.format("Capacity check failed for %s : %s", host, result.second())); } } } @@ -616,8 +620,7 @@ private Pair performCapacityChecksBeforeHostInMaintenance(Host ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(runningVM.getServiceOfferingId()); for (Host hostInCluster : hostsInCluster) { if (!checkHostTags(hostTags, hostTagsDao.gethostTags(hostInCluster.getId()), serviceOffering.getHostTag())) { - s_logger.debug("Host tags mismatch between host " + host.getUuid() + " and host " + hostInCluster.getUuid() + - ". Skipping it from the capacity check"); + s_logger.debug(String.format("Host tags mismatch between %s and %s Skipping it from the capacity check", host, hostInCluster)); continue; } DeployDestination deployDestination = new DeployDestination(null, null, null, host); @@ -627,8 +630,7 @@ private Pair performCapacityChecksBeforeHostInMaintenance(Host affinityChecks = affinityChecks && affinityProcessor.check(vmProfile, deployDestination); } if (!affinityChecks) { - s_logger.debug("Affinity check failed between host " + host.getUuid() + " and host " + hostInCluster.getUuid() + - ". Skipping it from the capacity check"); + s_logger.debug(String.format("Affinity check failed between %s and %s Skipping it from the capacity check", host, hostInCluster)); continue; } boolean maxGuestLimit = capacityManager.checkIfHostReachMaxGuestLimit(host); @@ -647,15 +649,15 @@ private Pair performCapacityChecksBeforeHostInMaintenance(Host } } if (!canMigrateVm) { - String msg = "VM " + runningVM.getUuid() + " cannot be migrated away from host " + host.getUuid() + - " to any other host in the cluster"; + String msg = String.format("%s cannot be migrated away from %s to any other host in the cluster", runningVM, host); s_logger.error(msg); return new Pair<>(false, msg); } sucessfullyCheckedVmMigrations++; } if (sucessfullyCheckedVmMigrations != vmsRunning.size()) { - return new Pair<>(false, "Host " + host.getId() + " cannot enter maintenance mode as capacity check failed for hosts in cluster " + cluster.getUuid()); + String migrationCheckDetails = String.format("%s cannot enter maintenance mode as capacity check failed for hosts in cluster %s", host, cluster); + return new Pair<>(false, migrationCheckDetails); } return new Pair<>(true, "OK"); } @@ -735,4 +737,4 @@ public String getConfigComponentName() { public ConfigKey[] getConfigKeys() { return new ConfigKey[] {KvmRollingMaintenanceStageTimeout, KvmRollingMaintenancePingInterval, KvmRollingMaintenanceWaitForMaintenanceTimeout}; } -} \ No newline at end of file +} diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index bda752ded338..99548f97a382 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -5255,7 +5255,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { } }); } catch (Exception e) { - s_logger.warn("Unable to update vm disk statistics for vm: " + userVm.getId() + " from host: " + hostId, e); + s_logger.warn(String.format("Unable to update VM disk statistics for %s from %s", userVm.getInstanceName(), host), e); } } } diff --git a/server/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImpl.java b/server/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImpl.java index a25575cd175a..003664cc5e7c 100644 --- a/server/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImpl.java @@ -221,7 +221,7 @@ public void propagateMSListToAgents() { final SetupMSListCommand cmd = new SetupMSListCommand(msList, lbAlgorithm, lbCheckInterval); final Answer answer = agentManager.easySend(host.getId(), cmd); if (answer == null || !answer.getResult()) { - LOG.warn("Failed to setup management servers list to the agent of host id=" + host.getId()); + LOG.warn(String.format("Failed to setup management servers list to the agent of %s", host)); } } } diff --git a/server/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceImpl.java b/server/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceImpl.java index 89f6ae718ee6..a956cf6727b5 100644 --- a/server/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceImpl.java @@ -189,7 +189,7 @@ private void sendAuthError(final Host host, final String message) { if (sentCount != null && sentCount <= 0) { boolean concurrentUpdateResult = hostAlertCache.asMap().replace(host.getId(), sentCount, sentCount+1L); if (concurrentUpdateResult) { - final String subject = String.format("Out-of-band management auth-error detected for host:%d in cluster:%d, zone:%d", host.getId(), host.getClusterId(), host.getDataCenterId()); + final String subject = String.format("Out-of-band management auth-error detected for %s in cluster [id: %d] and zone [id: %d].", host, host.getClusterId(), host.getDataCenterId()); LOG.error(subject + ": " + message); alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_OOBM_AUTH_ERROR, host.getDataCenterId(), host.getPodId(), subject, message); } @@ -203,11 +203,12 @@ private boolean transitionPowerState(OutOfBandManagement.PowerState.Event event, return false; } OutOfBandManagement.PowerState currentPowerState = outOfBandManagementHost.getPowerState(); + Host host = hostDao.findById(outOfBandManagementHost.getHostId()); try { OutOfBandManagement.PowerState newPowerState = OutOfBandManagement.PowerState.getStateMachine().getNextState(currentPowerState, event); boolean result = OutOfBandManagement.PowerState.getStateMachine().transitTo(outOfBandManagementHost, event, null, outOfBandManagementDao); if (result) { - final String message = String.format("Transitioned out-of-band management power state from:%s to:%s due to event:%s for the host id:%d", currentPowerState, newPowerState, event, outOfBandManagementHost.getHostId()); + final String message = String.format("Transitioned out-of-band management power state from %s to %s due to event: %s for %s", currentPowerState, newPowerState, event, host); LOG.debug(message); if (newPowerState == OutOfBandManagement.PowerState.Unknown) { ActionEventUtils.onActionEvent(CallContext.current().getCallingUserId(), CallContext.current().getCallingAccountId(), Domain.ROOT_DOMAIN, @@ -216,7 +217,7 @@ private boolean transitionPowerState(OutOfBandManagement.PowerState.Event event, } return result; } catch (NoTransitionException ignored) { - LOG.trace(String.format("Unable to transition out-of-band management power state for host id=%s for the event=%s and current power state=%s", outOfBandManagementHost.getHostId(), event, currentPowerState)); + LOG.trace(String.format("Unable to transition out-of-band management power state for %s for the event: %s and current power state: %s", host, event, currentPowerState)); } return false; } @@ -372,13 +373,14 @@ public OutOfBandManagementResponse configure(final Host host, final ImmutableMap } boolean updatedConfig = outOfBandManagementDao.update(outOfBandManagementConfig.getId(), (OutOfBandManagementVO) outOfBandManagementConfig); - CallContext.current().setEventDetails("host id:" + host.getId() + " configuration:" + outOfBandManagementConfig.getAddress() + ":" + outOfBandManagementConfig.getPort()); + String eventDetails = String.format("Configuring %s out-of-band with address [%s] and port [%s]", host, outOfBandManagementConfig.getAddress(), outOfBandManagementConfig.getPort()); + CallContext.current().setEventDetails(eventDetails); if (!updatedConfig) { - throw new CloudRuntimeException("Failed to update out-of-band management config for the host in the database."); + throw new CloudRuntimeException(String.format("Failed to update out-of-band management config for %s in the database.", host)); } - String result = "Out-of-band management successfully configured for the host"; + String result = String.format("Out-of-band management successfully configured for %s.", host); LOG.debug(result); final OutOfBandManagementResponse response = new OutOfBandManagementResponse(outOfBandManagementDao.findByHost(host.getId())); @@ -404,7 +406,7 @@ public OutOfBandManagementResponse executePowerOperation(final Host host, final final OutOfBandManagementDriverResponse driverResponse = driver.execute(cmd); if (driverResponse == null) { - throw new CloudRuntimeException(String.format("Out-of-band Management action (%s) on host (%s) failed due to no response from the driver", powerOperation, host.getUuid())); + throw new CloudRuntimeException(String.format("Out-of-band Management action [%s] on %s failed due to no response from the driver", powerOperation, host)); } if (powerOperation.equals(OutOfBandManagement.PowerOperation.STATUS)) { @@ -412,9 +414,9 @@ public OutOfBandManagementResponse executePowerOperation(final Host host, final } if (!driverResponse.isSuccess()) { - String errorMessage = String.format("Out-of-band Management action (%s) on host (%s) failed with error: %s", powerOperation, host.getUuid(), driverResponse.getError()); + String errorMessage = String.format("Out-of-band Management action [%s] on %s failed with error: %s", powerOperation, host, driverResponse.getError()); if (driverResponse.hasAuthFailure()) { - errorMessage = String.format("Out-of-band Management action (%s) on host (%s) failed due to authentication error: %s. Please check configured credentials.", powerOperation, host.getUuid(), driverResponse.getError()); + errorMessage = String.format("Out-of-band Management action [%s] on %s failed due to authentication error: %s. Please check configured credentials.", powerOperation, host, driverResponse.getError()); sendAuthError(host, errorMessage); } if (!powerOperation.equals(OutOfBandManagement.PowerOperation.STATUS)) { @@ -436,13 +438,13 @@ public OutOfBandManagementResponse executePowerOperation(final Host host, final public OutOfBandManagementResponse changePassword(final Host host, final String newPassword) { checkOutOfBandManagementEnabledByZoneClusterHost(host); if (Strings.isNullOrEmpty(newPassword)) { - throw new CloudRuntimeException(String.format("Cannot change out-of-band management password as provided new-password is null or empty for the host %s.", host.getUuid())); + throw new CloudRuntimeException(String.format("Cannot change out-of-band management password as provided new-password is null or empty for %s.", host)); } final OutOfBandManagement outOfBandManagementConfig = outOfBandManagementDao.findByHost(host.getId()); final ImmutableMap options = getOptions(outOfBandManagementConfig); if (!(options.containsKey(OutOfBandManagement.Option.PASSWORD) && !Strings.isNullOrEmpty(options.get(OutOfBandManagement.Option.PASSWORD)))) { - throw new CloudRuntimeException(String.format("Cannot change out-of-band management password as we've no previously configured password for the host %s.", host.getUuid())); + throw new CloudRuntimeException(String.format("Cannot change out-of-band management password as we've no previously configured password for %s.", host)); } final OutOfBandManagementDriver driver = getDriver(outOfBandManagementConfig); final OutOfBandManagementDriverChangePasswordCommand changePasswordCmd = new OutOfBandManagementDriverChangePasswordCommand(options, ActionTimeout.valueIn(host.getClusterId()), newPassword); @@ -455,7 +457,7 @@ public Boolean doInTransaction(TransactionStatus status) { boolean result = outOfBandManagementDao.update(updatedOutOfBandManagementConfig.getId(), (OutOfBandManagementVO) updatedOutOfBandManagementConfig); if (!result) { - throw new CloudRuntimeException(String.format("Failed to change out-of-band management password for host (%s) in the database.", host.getUuid())); + throw new CloudRuntimeException(String.format("Failed to change out-of-band management password for %s in the database.", host)); } final OutOfBandManagementDriverResponse driverResponse; @@ -463,11 +465,11 @@ public Boolean doInTransaction(TransactionStatus status) { driverResponse = driver.execute(changePasswordCmd); } catch (Exception e) { LOG.error("Out-of-band management change password failed due to driver error: " + e.getMessage()); - throw new CloudRuntimeException(String.format("Failed to change out-of-band management password for host (%s) due to driver error: %s", host.getUuid(), e.getMessage())); + throw new CloudRuntimeException(String.format("Failed to change out-of-band management password for %s due to driver error: %s", host, e.getMessage())); } if (!driverResponse.isSuccess()) { - throw new CloudRuntimeException(String.format("Failed to change out-of-band management password for host (%s) with error: %s", host.getUuid(), driverResponse.getError())); + throw new CloudRuntimeException(String.format("Failed to change out-of-band management password for %s with error: %s", host, driverResponse.getError())); } return result && driverResponse.isSuccess(); @@ -566,7 +568,7 @@ protected void runInContext() { } else if (outOfBandManagementHost.getPowerState() != OutOfBandManagement.PowerState.Disabled) { if (transitionPowerStateToDisabled(Collections.singletonList(host))) { if (LOG.isDebugEnabled()) { - LOG.debug("Out-of-band management was disabled in zone/cluster/host, disabled power state for host id:" + host.getId()); + LOG.debug(String.format("Out-of-band management was disabled in zone/cluster/host, disabled power state for %s", host)); } } } From 9678c7bd1e0cb6b4fa53b8bbef75d50d8d6812f6 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Wed, 14 Jul 2021 02:07:29 +0530 Subject: [PATCH 107/120] ui: Fix traversal to domain details via domain router-link of a resource (#5182) --- ui/src/components/view/InfoCard.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/components/view/InfoCard.vue b/ui/src/components/view/InfoCard.vue index bfdac6a56947..62fe8872190b 100644 --- a/ui/src/components/view/InfoCard.vue +++ b/ui/src/components/view/InfoCard.vue @@ -536,7 +536,7 @@
{{ $t('label.domain') }}
- {{ resource.domain || resource.domainid }} + {{ resource.domain || resource.domainid }} {{ resource.domain || resource.domainid }}
From 041948c04f8b20bebe74f34564c912d19c91bde0 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 15 Jul 2021 12:45:38 +0530 Subject: [PATCH 108/120] ui: refactor labels with tooltip in forms (#5133) * ui: refactor labels with tooltip in forms Adds new Vue component TooltipLabel for easier re-use Signed-off-by: Abhishek Kumar * changes Signed-off-by: Abhishek Kumar * changes Signed-off-by: Abhishek Kumar * changes Signed-off-by: Abhishek Kumar * changes Signed-off-by: Abhishek Kumar * changes Signed-off-by: Abhishek Kumar * moved component in widgets Signed-off-by: Abhishek Kumar * moved TooltipButton in widgets Signed-off-by: Abhishek Kumar * missing change in previous commit Signed-off-by: Abhishek Kumar * changes Signed-off-by: Abhishek Kumar * fix Signed-off-by: Abhishek Kumar * form improvements Signed-off-by: Abhishek Kumar * tooltip icon class fix Signed-off-by: Abhishek Kumar * fix Signed-off-by: Abhishek Kumar * Update ui/src/views/storage/UploadLocalVolume.vue Co-authored-by: Pearl Dsilva * Update ui/src/views/storage/CreateVolume.vue Co-authored-by: davidjumani * fix Signed-off-by: Abhishek Kumar Co-authored-by: Pearl Dsilva Co-authored-by: davidjumani --- ui/src/components/view/DetailSettings.vue | 2 +- ui/src/components/view/InfoCard.vue | 2 +- ui/src/components/view/ListView.vue | 2 +- ui/src/components/view/SearchView.vue | 2 +- ui/src/components/view/SettingsTab.vue | 2 +- .../{view => widgets}/TooltipButton.vue | 0 ui/src/components/widgets/TooltipLabel.vue | 52 ++ ui/src/views/AutogenView.vue | 11 +- .../views/compute/CreateKubernetesCluster.vue | 109 +-- ui/src/views/compute/CreateSnapshotWizard.vue | 32 +- ui/src/views/compute/DeployVM.vue | 36 +- ui/src/views/compute/DestroyVM.vue | 18 +- ui/src/views/compute/EditVM.vue | 46 +- ui/src/views/compute/InstanceTab.vue | 2 +- ui/src/views/compute/MigrateVMStorage.vue | 11 +- .../views/compute/ScaleKubernetesCluster.vue | 18 +- ui/src/views/compute/StartVirtualMachine.vue | 32 +- .../compute/UpgradeKubernetesCluster.vue | 11 +- .../views/compute/backup/BackupSchedule.vue | 2 +- ui/src/views/iam/AddAccount.vue | 88 +- ui/src/views/iam/AddUser.vue | 74 +- ui/src/views/iam/ChangeUserPassword.vue | 25 +- ui/src/views/iam/CreateRole.vue | 53 +- ui/src/views/iam/DomainActionForm.vue | 11 +- ui/src/views/iam/EditUser.vue | 39 +- ui/src/views/iam/ImportRole.vue | 49 +- ui/src/views/iam/RolePermissionTab.vue | 2 +- ui/src/views/iam/RuleDelete.vue | 2 +- ui/src/views/iam/SSLCertificateTab.vue | 2 +- .../image/AddKubernetesSupportedVersion.vue | 54 +- ui/src/views/image/IsoZones.vue | 2 +- ui/src/views/image/TemplateZones.vue | 2 +- ui/src/views/infra/AddPrimaryStorage.vue | 151 +--- ui/src/views/infra/InfraSummary.vue | 39 +- .../views/infra/network/DedicatedVLANTab.vue | 2 +- .../views/infra/network/EditTrafficLabel.vue | 46 +- .../infra/network/IpRangesTabManagement.vue | 2 +- .../views/infra/network/IpRangesTabPublic.vue | 2 +- .../infra/network/IpRangesTabStorage.vue | 2 +- .../network/providers/ProviderListView.vue | 2 +- .../views/infra/routers/RouterHealthCheck.vue | 11 +- .../views/infra/zone/IpAddressRangeForm.vue | 2 +- .../ZoneWizardPhysicalNetworkSetupStep.vue | 2 +- ui/src/views/network/AclListRulesTab.vue | 2 +- .../network/CreateIsolatedNetworkForm.vue | 88 +- ui/src/views/network/CreateL2NetworkForm.vue | 74 +- .../views/network/CreateSharedNetworkForm.vue | 285 ++----- ui/src/views/network/CreateVlanIpRange.vue | 63 +- ui/src/views/network/CreateVpc.vue | 54 +- .../network/CreateVpnCustomerGateway.vue | 75 +- ui/src/views/network/EgressRulesTab.vue | 2 +- ui/src/views/network/FirewallRules.vue | 2 +- ui/src/views/network/GuestIpRanges.vue | 2 +- .../network/IngressEgressRuleConfigure.vue | 2 +- .../views/network/InternalLBAssignedVmTab.vue | 2 +- ui/src/views/network/IpAddressesTab.vue | 2 +- ui/src/views/network/LoadBalancing.vue | 2 +- ui/src/views/network/PortForwarding.vue | 2 +- ui/src/views/network/StaticRoutesTab.vue | 2 +- ui/src/views/network/VpcTiersTab.vue | 11 +- ui/src/views/offering/AddComputeOffering.vue | 807 +++++++----------- ui/src/views/offering/AddDiskOffering.vue | 245 ++---- ui/src/views/offering/AddNetworkOffering.vue | 240 ++---- ui/src/views/offering/AddVpcOffering.vue | 78 +- .../views/offering/ImportBackupOffering.vue | 39 +- ui/src/views/project/AccountsTab.vue | 2 +- .../project/AddAccountOrUserToProject.vue | 61 +- ui/src/views/project/InvitationsTemplate.vue | 2 +- .../project/iam/ProjectRolePermissionTab.vue | 2 +- ui/src/views/project/iam/ProjectRoleTab.vue | 2 +- ui/src/views/storage/CreateVolume.vue | 32 +- ui/src/views/storage/FormSchedule.vue | 2 +- ui/src/views/storage/ScheduledSnapshots.vue | 2 +- ui/src/views/storage/TakeSnapshot.vue | 2 +- ui/src/views/storage/UploadLocalVolume.vue | 32 +- 75 files changed, 981 insertions(+), 2291 deletions(-) rename ui/src/components/{view => widgets}/TooltipButton.vue (100%) create mode 100644 ui/src/components/widgets/TooltipLabel.vue diff --git a/ui/src/components/view/DetailSettings.vue b/ui/src/components/view/DetailSettings.vue index 1af56bf321a2..302fd63af780 100644 --- a/ui/src/components/view/DetailSettings.vue +++ b/ui/src/components/view/DetailSettings.vue @@ -110,7 +110,7 @@ + + diff --git a/ui/src/views/AutogenView.vue b/ui/src/views/AutogenView.vue index ecd8547466e2..697194102567 100644 --- a/ui/src/views/AutogenView.vue +++ b/ui/src/views/AutogenView.vue @@ -159,12 +159,7 @@ :v-bind="field.name" v-if="!(currentAction.mapping && field.name in currentAction.mapping && currentAction.mapping[field.name].value)" > - - {{ $t('label.' + field.name) }} - - - - + - - {{ $t('label.name') }} - - - - + - {{ $t('label.description') }} - - - - + - - {{ $t('label.zoneid') }} - - - - + - {{ $t('label.kubernetesversionid') }} - - - - + - {{ $t('label.serviceofferingid') }} - - - - + - {{ $t('label.noderootdisksize') }} - - - - + - - {{ $t('label.networkid') }} - - - - + - - {{ $t('label.controlnodes') }} - - - - + - - {{ $t('label.externalloadbalanceripaddress') }} - - - - + - - {{ $t('label.cks.cluster.size') }} - - - - + - - {{ $t('label.keypair') }} - - - - +
- - {{ $t('label.username') }} - - - - + - - {{ $t('label.password') }} - - - - + - - {{ $t('label.url') }} - - - - + - - {{ $t('label.email') }} - - - - + - - {{ $t('label.volumeid') }} - - - - + - - {{ $t('label.name') }} - - - - + - - {{ $t('label.quiescevm') }} - - - - + - - {{ $t('label.asyncbackup') }} - - - - +
@@ -85,9 +65,13 @@