You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2024/04/29 09:37:58 UTC

(cloudstack) branch main updated (54926c324ff -> e61f3bae4da)

This is an automated email from the ASF dual-hosted git repository.

dahn pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


    from 54926c324ff sanatise log in case multiple passwordsa have been passed (#8891)
     add e409c6d870a Fixup listing of serivce offering & storagepools with tags (#8937)
     add 80a8b80a9d5 Update volume's passphrase to null if diskOffering doesn't support encryption (#8904)
     add 08132acaa2f Fix restore VM with allocated root disk (#8977)
     add b23ceefc7ea utils: cleanup MacAddress and MacAddressTest (#8988)
     add 0e08a126dfd systemvm: add template_zone_ref record when add a new zone with same hypervisor type (#8395)
     add cec6ade257c change live migration API used on kvm (#8952)
     add eead2710f81 explanatory error message on delete attempt of default system offering (#8883)
     add 9d5d4e55648 linstor: cleanup diskless nodes on disconnect (#8790)
     add 3de1f8b4baf Merge remote-tracking branch 'origin/4.18' into 4.19
     new e61f3bae4da Merge branch '4.19'

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/workflows/ci.yml                           |   1 +
 .../service/VolumeOrchestrationService.java        |   2 +-
 .../engine/orchestration/VolumeOrchestrator.java   |  11 +-
 .../upgrade/SystemVmTemplateRegistration.java      |  11 +-
 .../storage/volume/VolumeServiceImpl.java          |   2 +-
 .../hypervisor/kvm/resource/LibvirtVMDef.java      |   4 +
 .../hypervisor/kvm/resource/MigrateKVMAsync.java   |  45 +++-
 .../wrapper/LibvirtMigrateCommandWrapper.java      |  29 ++-
 .../kvm/resource/MigrateKVMAsyncTest.java          |  83 ++++++++
 .../wrapper/LibvirtMigrateCommandWrapperTest.java  |  78 ++++++-
 .../kvm/storage/LinstorStorageAdaptor.java         | 114 ++++++----
 .../java/com/cloud/api/query/QueryManagerImpl.java |   2 +-
 .../configuration/ConfigurationManagerImpl.java    |   2 +-
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  |  10 +-
 test/integration/smoke/test_restore_vm.py          | 108 ++++++++++
 ui/src/views/compute/ReinstallVm.vue               |  18 +-
 .../main/java/com/cloud/utils/net/MacAddress.java  | 231 +++------------------
 .../java/com/cloud/utils/net/MacAddressTest.java   |  14 +-
 18 files changed, 487 insertions(+), 278 deletions(-)
 create mode 100644 plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/MigrateKVMAsyncTest.java
 create mode 100644 test/integration/smoke/test_restore_vm.py


(cloudstack) 01/01: Merge branch '4.19'

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit e61f3bae4daf752b3d4cf23d1c4685e074d07c4d
Merge: 54926c324ff 3de1f8b4baf
Author: Daan Hoogland <da...@onecht.net>
AuthorDate: Mon Apr 29 11:37:40 2024 +0200

    Merge branch '4.19'

 .github/workflows/ci.yml                           |   1 +
 .../service/VolumeOrchestrationService.java        |   2 +-
 .../engine/orchestration/VolumeOrchestrator.java   |  11 +-
 .../upgrade/SystemVmTemplateRegistration.java      |  11 +-
 .../storage/volume/VolumeServiceImpl.java          |   2 +-
 .../hypervisor/kvm/resource/LibvirtVMDef.java      |   4 +
 .../hypervisor/kvm/resource/MigrateKVMAsync.java   |  45 +++-
 .../wrapper/LibvirtMigrateCommandWrapper.java      |  29 ++-
 .../kvm/resource/MigrateKVMAsyncTest.java          |  83 ++++++++
 .../wrapper/LibvirtMigrateCommandWrapperTest.java  |  78 ++++++-
 .../kvm/storage/LinstorStorageAdaptor.java         | 114 ++++++----
 .../java/com/cloud/api/query/QueryManagerImpl.java |   2 +-
 .../configuration/ConfigurationManagerImpl.java    |   2 +-
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  |  10 +-
 test/integration/smoke/test_restore_vm.py          | 108 ++++++++++
 ui/src/views/compute/ReinstallVm.vue               |  18 +-
 .../main/java/com/cloud/utils/net/MacAddress.java  | 231 +++------------------
 .../java/com/cloud/utils/net/MacAddressTest.java   |  14 +-
 18 files changed, 487 insertions(+), 278 deletions(-)

diff --cc plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
index c24214dd68c,aebbaa4119d..b97cb666de0
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
@@@ -188,15 -191,17 +189,17 @@@ public final class LibvirtMigrateComman
              // migrateStorage's value should always only be associated with the initial state of mapMigrateStorage.
              final boolean migrateStorage = MapUtils.isNotEmpty(mapMigrateStorage);
              final boolean migrateStorageManaged = command.isMigrateStorageManaged();
+             Set<String> migrateDiskLabels = null;
  
              if (migrateStorage) {
 -                if (s_logger.isDebugEnabled()) {
 -                    s_logger.debug(String.format("Changing VM [%s] volumes during migration to host: [%s].", vmName, target));
 +                if (logger.isDebugEnabled()) {
 +                    logger.debug(String.format("Changing VM [%s] volumes during migration to host: [%s].", vmName, target));
                  }
                  xmlDesc = replaceStorage(xmlDesc, mapMigrateStorage, migrateStorageManaged);
 -                if (s_logger.isDebugEnabled()) {
 -                    s_logger.debug(String.format("Changed VM [%s] XML configuration of used storage. New XML configuration is [%s].", vmName, xmlDesc));
 +                if (logger.isDebugEnabled()) {
 +                    logger.debug(String.format("Changed VM [%s] XML configuration of used storage. New XML configuration is [%s].", vmName, xmlDesc));
                  }
+                 migrateDiskLabels = getMigrateStorageDeviceLabels(disks, mapMigrateStorage);
              }
  
              Map<String, DpdkTO> dpdkPortsMapping = command.getDpdkInterfaceMapping();
@@@ -364,6 -368,30 +367,30 @@@
          return new MigrateAnswer(command, result == null, result, null);
      }
  
+     /**
+      * Gets the disk labels (vda, vdb...) of the disks mapped for migration on mapMigrateStorage.
+      * @param diskDefinitions list of all the disksDefinitions of the VM.
+      * @param mapMigrateStorage map of the disks that should be migrated.
+      * @return set with the labels of the disks that should be migrated.
+      * */
+     protected Set<String> getMigrateStorageDeviceLabels(List<DiskDef> diskDefinitions, Map<String, MigrateCommand.MigrateDiskInfo> mapMigrateStorage) {
+         HashSet<String> setOfLabels = new HashSet<>();
 -        s_logger.debug(String.format("Searching for disk labels of disks [%s].", mapMigrateStorage.keySet()));
++        logger.debug("Searching for disk labels of disks [{}].", mapMigrateStorage.keySet());
+         for (String fileName : mapMigrateStorage.keySet()) {
+             for (DiskDef diskDef : diskDefinitions) {
+                 String diskPath = diskDef.getDiskPath();
+                 if (diskPath != null && diskPath.contains(fileName)) {
+                     setOfLabels.add(diskDef.getDiskLabel());
 -                    s_logger.debug(String.format("Found label [%s] for disk [%s].", diskDef.getDiskLabel(), fileName));
++                    logger.debug("Found label [{}] for disk [{}].", diskDef.getDiskLabel(), fileName);
+                     break;
+                 }
+             }
+         }
+ 
+         return setOfLabels;
+     }
+ 
+ 
      /**
       * Checks if the CPU shares are equal in the source host and destination host.
       *  <ul>
diff --cc plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
index c5537eb9dd8,3a327b158d2..0ab51dbf112
--- a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
+++ b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
@@@ -296,16 -296,83 +301,83 @@@ public class LinstorStorageAdaptor impl
          return true;
      }
  
+     private boolean tryDisconnectLinstor(String volumePath, KVMStoragePool pool)
+     {
+         if (volumePath == null) {
+             return false;
+         }
+ 
 -        s_logger.debug("Linstor: Using storage pool: " + pool.getUuid());
++        logger.debug("Linstor: Using storage pool: " + pool.getUuid());
+         final DevelopersApi api = getLinstorAPI(pool);
+ 
+         Optional<ResourceWithVolumes> optRsc;
+         try
+         {
+             List<ResourceWithVolumes> resources = api.viewResources(
+                     Collections.singletonList(localNodeName),
+                     null,
+                     null,
+                     null,
+                     null,
+                     null);
+ 
+             optRsc = getResourceByPath(resources, volumePath);
+         } catch (ApiException apiEx) {
+             // couldn't query linstor controller
 -            s_logger.error(apiEx.getBestMessage());
++            logger.error(apiEx.getBestMessage());
+             return false;
+         }
+ 
+ 
+         if (optRsc.isPresent()) {
+             try {
+                 Resource rsc = optRsc.get();
+ 
+                 // if diskless resource remove it, in the worst case it will be transformed to a tiebreaker
+                 if (rsc.getFlags() != null &&
+                         rsc.getFlags().contains(ApiConsts.FLAG_DRBD_DISKLESS) &&
+                         !rsc.getFlags().contains(ApiConsts.FLAG_TIE_BREAKER)) {
+                     ApiCallRcList delAnswers = api.resourceDelete(rsc.getName(), localNodeName);
+                     logLinstorAnswers(delAnswers);
+                 }
+ 
+                 // remove allow-two-primaries
+                 ResourceDefinitionModify rdm = new ResourceDefinitionModify();
+                 rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries"));
+                 ApiCallRcList answers = api.resourceDefinitionModify(rsc.getName(), rdm);
+                 if (answers.hasError()) {
 -                    s_logger.error(
++                    logger.error(
+                             String.format("Failed to remove 'allow-two-primaries' on %s: %s",
+                                     rsc.getName(), LinstorUtil.getBestErrorMessage(answers)));
+                     // do not fail here as removing allow-two-primaries property isn't fatal
+                 }
+             } catch (ApiException apiEx) {
 -                s_logger.error(apiEx.getBestMessage());
++                logger.error(apiEx.getBestMessage());
+                 // do not fail here as removing allow-two-primaries property or deleting diskless isn't fatal
+             }
+ 
+             return true;
+         }
+ 
 -        s_logger.warn("Linstor: Couldn't find resource for this path: " + volumePath);
++        logger.warn("Linstor: Couldn't find resource for this path: " + volumePath);
+         return false;
+     }
+ 
      @Override
      public boolean disconnectPhysicalDisk(String volumePath, KVMStoragePool pool)
      {
 -        s_logger.debug("Linstor: disconnectPhysicalDisk " + pool.getUuid() + ":" + volumePath);
 +        logger.debug("Linstor: disconnectPhysicalDisk {}:{}", pool.getUuid(), volumePath);
+         if (MapStorageUuidToStoragePool.containsValue(pool)) {
+             return tryDisconnectLinstor(volumePath, pool);
+         }
          return false;
      }
  
      @Override
      public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect)
      {
+         // as of now this is only relevant for iscsi targets
 -        s_logger.info("Linstor: disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) called?");
++        logger.info("Linstor: disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) called?");
          return false;
      }
  
@@@ -330,49 -397,11 +402,11 @@@
          Optional<KVMStoragePool> optFirstPool = MapStorageUuidToStoragePool.values().stream().findFirst();
          if (optFirstPool.isPresent())
          {
 -            s_logger.debug("Linstor: disconnectPhysicalDiskByPath " + localPath);
 +            logger.debug("Linstor: disconnectPhysicalDiskByPath " + localPath);
              final KVMStoragePool pool = optFirstPool.get();
  
-             logger.debug("Linstor: Using storpool: " + pool.getUuid());
-             final DevelopersApi api = getLinstorAPI(pool);
- 
-             Optional<ResourceWithVolumes> optRsc;
-             try {
-                 List<ResourceWithVolumes> resources = api.viewResources(
-                         Collections.singletonList(localNodeName),
-                         null,
-                         null,
-                         null,
-                         null,
-                         null);
- 
-                 optRsc = getResourceByPath(resources, localPath);
-             } catch (ApiException apiEx) {
-                 // couldn't query linstor controller
-                 logger.error(apiEx.getBestMessage());
-                 return false;
-             }
- 
-             if (optRsc.isPresent()) {
-                 try {
-                     Resource rsc = optRsc.get();
-                     ResourceDefinitionModify rdm = new ResourceDefinitionModify();
-                     rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries"));
-                     ApiCallRcList answers = api.resourceDefinitionModify(rsc.getName(), rdm);
-                     if (answers.hasError()) {
-                         logger.error(
-                                 String.format("Failed to remove 'allow-two-primaries' on %s: %s",
-                                         rsc.getName(), LinstorUtil.getBestErrorMessage(answers)));
-                         // do not fail here as removing allow-two-primaries property isn't fatal
-                     }
-                 } catch(ApiException apiEx){
-                     logger.error(apiEx.getBestMessage());
-                     // do not fail here as removing allow-two-primaries property isn't fatal
-                     return true;
-                 }
-             }
+             return tryDisconnectLinstor(localPath, pool);
          }
-         logger.info("Linstor: Couldn't find resource for this path: {}", localPath);
          return false;
      }
  
diff --cc server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
index a1e0e770ee6,e574d9887c3..a9d9ad09095
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@@ -7979,9 -7843,10 +7979,9 @@@ public class UserVmManagerImpl extends 
              }
          }
  
 -        DiskOffering diskOffering = rootDiskOfferingId != null ? _diskOfferingDao.findById(rootDiskOfferingId) : null;
          for (VolumeVO root : rootVols) {
              if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ) {
-                 _volumeService.validateDestroyVolume(root, caller, expunge, false);
+                 _volumeService.validateDestroyVolume(root, caller, Volume.State.Allocated.equals(root.getState()) || expunge, false);
                  final UserVmVO userVm = vm;
                  Pair<UserVmVO, Volume> vmAndNewVol = Transaction.execute(new TransactionCallbackWithException<Pair<UserVmVO, Volume>, CloudRuntimeException>() {
                      @Override
@@@ -8044,13 -7909,8 +8044,13 @@@
  
                  // Detach, destroy and create the usage event for the old root volume.
                  _volsDao.detachVolume(root.getId());
-                 _volumeService.destroyVolume(root.getId(), caller, expunge, false);
+                 _volumeService.destroyVolume(root.getId(), caller, Volume.State.Allocated.equals(root.getState()) || expunge, false);
  
 +                if (currentTemplate.getId() != template.getId() && VirtualMachine.Type.User.equals(vm.type) && !VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
 +                    ServiceOfferingVO serviceOffering = serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
 +                    _resourceLimitMgr.updateVmResourceCountForTemplateChange(vm.getAccountId(), vm.isDisplay(), serviceOffering, currentTemplate, template);
 +                }
 +
                  // For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage
                  if (vm.getHypervisorType() == HypervisorType.VMware) {
                      VolumeInfo volumeInStorage = volFactory.getVolume(root.getId());
diff --cc utils/src/main/java/com/cloud/utils/net/MacAddress.java
index 5a72c48dd69,76f3f6c24ac..7555c03c2c0
--- a/utils/src/main/java/com/cloud/utils/net/MacAddress.java
+++ b/utils/src/main/java/com/cloud/utils/net/MacAddress.java
@@@ -19,26 -19,19 +19,24 @@@
  
  package com.cloud.utils.net;
  
- import static com.cloud.utils.AutoCloseableUtil.closeAutoCloseable;
- 
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStreamReader;
  import java.net.InetAddress;
+ import java.net.NetworkInterface;
+ import java.net.SocketException;
  import java.net.UnknownHostException;
+ import java.util.Collections;
  import java.util.Formatter;
 +
 +import org.apache.logging.log4j.Logger;
 +import org.apache.logging.log4j.LogManager;
+ import java.util.List;
  
  /**
   * This class retrieves the (first) MAC address for the machine is it is loaded on and stores it statically for retrieval.
   * It can also be used for formatting MAC addresses.
-  * copied fnd addpeted rom the public domain utility from John Burkard.
   **/
  public class MacAddress {
 +    protected static Logger LOGGER = LogManager.getLogger(MacAddress.class);
++
      private long _addr = 0;
  
      protected MacAddress() {