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 2025/04/17 14:46:40 UTC

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

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 3c75d9363b79d4d505177ac9fe7983403760959c
Merge: 55c811547a8 d7765343efe
Author: Daan Hoogland <da...@onecht.net>
AuthorDate: Thu Apr 17 15:59:41 2025 +0200

    Merge branch '4.20'

 .../storage/VMTemplateStorageResourceAssoc.java    |   3 +
 .../api/command/user/iso/ExtractIsoCmd.java        |  11 +-
 .../command/user/template/ExtractTemplateCmd.java  |  10 +-
 .../api/command/user/volume/ExtractVolumeCmd.java  |   8 +-
 .../com/cloud/vm/VirtualMachineManagerImpl.java    |   3 +-
 .../engine/orchestration/DataMigrationUtility.java |  32 ++++-
 .../orchestration/DataMigrationUtilityTest.java    |  88 +++++++++++++
 .../src/main/java/com/cloud/vm/VMInstanceVO.java   |   2 +-
 .../resources/META-INF/db/schema-42000to42010.sql  |  22 ++++
 .../storage/image/SecondaryStorageServiceImpl.java |  91 ++++++++++---
 .../image/SecondaryStorageServiceImplTest.java     | 138 ++++++++++++++++++++
 .../java/com/cloud/cluster/ClusterManagerImpl.java |  54 ++++----
 .../hypervisor/vmware/resource/VmwareResource.java |   4 +-
 .../motion/VmwareStorageMotionStrategy.java        |  29 +++--
 .../api/command/ListAndSwitchSAMLAccountCmd.java   |  25 ++--
 .../api/command/SAML2LoginAPIAuthenticatorCmd.java |  14 +-
 .../apache/cloudstack/saml/SAML2AuthManager.java   |   4 +
 .../cloudstack/saml/SAML2AuthManagerImpl.java      |   2 +-
 .../java/org/apache/cloudstack/saml/SAMLUtils.java |  88 ++++++++-----
 .../java/org/apache/cloudstack/SAMLUtilsTest.java  |   6 +-
 .../command/ListAndSwitchSAMLAccountCmdTest.java   |   2 -
 server/src/main/java/com/cloud/api/ApiServer.java  | 144 ++++++++++-----------
 server/src/main/java/com/cloud/api/ApiServlet.java |   7 +-
 .../cloud/api/query/dao/TemplateJoinDaoImpl.java   |   7 -
 .../com/cloud/ha/HighAvailabilityManagerImpl.java  |  25 +++-
 .../java/com/cloud/network/NetworkServiceImpl.java |  15 ++-
 .../network/element/ConfigDriveNetworkElement.java |   6 +-
 .../com/cloud/storage/VolumeApiServiceImpl.java    |  18 ++-
 .../storage/download/DownloadActiveState.java      |   2 +-
 .../cloud/storage/download/DownloadListener.java   |   1 +
 .../cloud/template/HypervisorTemplateAdapter.java  |  35 ++---
 .../com/cloud/template/TemplateManagerImpl.java    |   8 +-
 .../java/com/cloud/user/AccountManagerImpl.java    |  63 +++++++--
 .../com/cloud/user/AccountManagerImplTest.java     |  71 ++++++++++
 ui/src/components/header/SamlDomainSwitcher.vue    |   3 +
 ui/src/components/view/InfoCard.vue                |   4 +-
 ui/src/store/modules/user.js                       |   4 +-
 ui/src/views/image/IsoZones.vue                    |   8 ++
 ui/src/views/image/TemplateZones.vue               |   8 ++
 ui/src/views/infra/UsageRecords.vue                |   1 +
 ui/src/views/offering/AddVpcOffering.vue           |   8 +-
 ui/vue.config.js                                   |   2 +-
 42 files changed, 821 insertions(+), 255 deletions(-)

diff --cc framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java
index d2c85b498f2,b8102c63654..309d66e9d30
--- a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java
+++ b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java
@@@ -73,8 -73,8 +73,8 @@@ public class ClusterManagerImpl extend
      private static final int EXECUTOR_SHUTDOWN_TIMEOUT = 1000; // 1 second
      private static final int DEFAULT_OUTGOING_WORKERS = 5;
  
--    private final List<ClusterManagerListener> _listeners = new ArrayList<ClusterManagerListener>();
--    private final Map<Long, ManagementServerHostVO> _activePeers = new HashMap<Long, ManagementServerHostVO>();
++    private final List<ClusterManagerListener> _listeners = new ArrayList<>();
++    private final Map<Long, ManagementServerHostVO> _activePeers = new HashMap<>();
  
      private final Map<String, ClusterService> _clusterPeers;
  
@@@ -83,7 -83,7 +83,7 @@@
  
      private final ScheduledExecutorService _heartbeatScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Cluster-Heartbeat"));
      private final ExecutorService _notificationExecutor = Executors.newFixedThreadPool(1, new NamedThreadFactory("Cluster-Notification"));
--    private final List<ClusterManagerMessage> _notificationMsgs = new ArrayList<ClusterManagerMessage>();
++    private final List<ClusterManagerMessage> _notificationMsgs = new ArrayList<>();
      private ConnectionConcierge _heartbeatConnection = null;
  
      private final ExecutorService _executor;
@@@ -118,12 -118,12 +118,12 @@@
  
      private String _clusterNodeIP = "127.0.0.1";
  
--    private final List<ClusterServicePdu> _clusterPduOutgoingQueue = new ArrayList<ClusterServicePdu>();
--    private final List<ClusterServicePdu> _clusterPduIncomingQueue = new ArrayList<ClusterServicePdu>();
--    private final Map<Long, ClusterServiceRequestPdu> _outgoingPdusWaitingForAck = new HashMap<Long, ClusterServiceRequestPdu>();
++    private final List<ClusterServicePdu> _clusterPduOutgoingQueue = new ArrayList<>();
++    private final List<ClusterServicePdu> _clusterPduIncomingQueue = new ArrayList<>();
++    private final Map<Long, ClusterServiceRequestPdu> _outgoingPdusWaitingForAck = new HashMap<>();
  
      public ClusterManagerImpl() {
--        _clusterPeers = new HashMap<String, ClusterService>();
++        _clusterPeers = new HashMap<>();
  
          // executor to perform remote-calls in another thread context, to avoid potential
          // recursive remote calls between nodes
@@@ -161,7 -161,7 +161,7 @@@
      }
  
      private void cancelClusterRequestToPeer(final String strPeer) {
--        final List<ClusterServiceRequestPdu> candidates = new ArrayList<ClusterServiceRequestPdu>();
++        final List<ClusterServiceRequestPdu> candidates = new ArrayList<>();
          synchronized (_outgoingPdusWaitingForAck) {
              for (final Map.Entry<Long, ClusterServiceRequestPdu> entry : _outgoingPdusWaitingForAck.entrySet()) {
                  if (entry.getValue().getDestPeer().equalsIgnoreCase(strPeer)) {
@@@ -193,7 -193,7 +193,7 @@@
          synchronized (_clusterPduOutgoingQueue) {
              try {
                  _clusterPduOutgoingQueue.wait(timeoutMs);
--            } catch (final InterruptedException e) {
++            } catch (final InterruptedException ignored) {
              }
  
              if (_clusterPduOutgoingQueue.size() > 0) {
@@@ -216,7 -216,7 +216,7 @@@
          synchronized (_clusterPduIncomingQueue) {
              try {
                  _clusterPduIncomingQueue.wait(timeoutMs);
--            } catch (final InterruptedException e) {
++            } catch (final InterruptedException ignored) {
              }
  
              if (_clusterPduIncomingQueue.size() > 0) {
@@@ -449,7 -449,7 +449,7 @@@
          synchronized (pdu) {
              try {
                  pdu.wait();
--            } catch (final InterruptedException e) {
++            } catch (final InterruptedException ignored) {
              }
          }
  
@@@ -620,8 -620,8 +620,8 @@@
  
                          if (profiler.getDurationInMillis() >= HeartbeatInterval.value()) {
                              if (logger.isDebugEnabled()) {
--                                logger.debug("Management server heartbeat takes too long to finish. profiler: " + profiler.toString() + ", profilerHeartbeatUpdate: " +
--                                        profilerHeartbeatUpdate.toString() + ", profilerPeerScan: " + profilerPeerScan.toString());
++                                logger.debug("Management server heartbeat takes too long to finish. profiler: " + profiler + ", profilerHeartbeatUpdate: " +
++                                        profilerHeartbeatUpdate + ", profilerPeerScan: " + profilerPeerScan);
                              }
                          }
                      }
@@@ -685,7 -685,7 +685,7 @@@
                      synchronized (_notificationMsgs) {
                          try {
                              _notificationMsgs.wait(1000);
--                        } catch (final InterruptedException e) {
++                        } catch (final InterruptedException ignored) {
                          }
                      }
  
@@@ -745,7 -745,7 +745,7 @@@
  
                      try {
                          Thread.sleep(1000);
--                    } catch (final InterruptedException e) {
++                    } catch (final InterruptedException ignored) {
                      }
                  }
              }
@@@ -816,7 -816,7 +816,7 @@@
                  }
              }
  
--            final List<ManagementServerHostVO> downHostList = new ArrayList<ManagementServerHostVO>();
++            final List<ManagementServerHostVO> downHostList = new ArrayList<>();
              for (final ManagementServerHostVO host : inactiveList) {
                  // Check if peer state is Up in the period
                  if (!_mshostPeerDao.isPeerUpState(_mshostId, host.getId(), new Date(cutTime.getTime() - HeartbeatThreshold.value()))) {
@@@ -846,8 -846,8 +846,8 @@@
  
          final Profiler profilerSyncClusterInfo = new Profiler();
          profilerSyncClusterInfo.start();
--        final List<ManagementServerHostVO> removedNodeList = new ArrayList<ManagementServerHostVO>();
--        final List<ManagementServerHostVO> invalidatedNodeList = new ArrayList<ManagementServerHostVO>();
++        final List<ManagementServerHostVO> removedNodeList = new ArrayList<>();
++        final List<ManagementServerHostVO> invalidatedNodeList = new ArrayList<>();
  
          if (_mshostId != null) {
  
@@@ -941,7 -941,7 +941,7 @@@
                  try {
                      JmxUtil.unregisterMBean("ClusterManager", "Node " + mshost.getId());
                  } catch (final Exception e) {
-                     logger.warn("Unable to deregister cluster node from JMX monitoring due to exception " + e.toString());
 -                    logger.warn("Unable to deregiester cluster node from JMX monitoring due to exception " + e.toString());
++                    logger.warn("Unable to deregister cluster node from JMX monitoring due to exception " + e);
                  }
              }
  
@@@ -961,7 -961,7 +961,7 @@@
                  try {
                      JmxUtil.unregisterMBean("ClusterManager", "Node " + mshost.getId());
                  } catch (final Exception e) {
--                    logger.warn("Unable to deregiester cluster node from JMX monitoring due to exception " + e.toString());
++                    logger.warn("Unable to deregiester cluster node from JMX monitoring due to exception " + e);
                  }
              } else {
                  logger.info("Management node {} is detected inactive by timestamp but sent node status to this node", mshost);
@@@ -975,7 -975,7 +975,7 @@@
      }
  
      private void processNewNodes(Date cutTime, List<ManagementServerHostVO> currentList) {
--        final List<ManagementServerHostVO> newNodeList = new ArrayList<ManagementServerHostVO>();
++        final List<ManagementServerHostVO> newNodeList = new ArrayList<>();
          for (final ManagementServerHostVO mshost : currentList) {
              if (!_activePeers.containsKey(mshost.getId())) {
                  _activePeers.put(mshost.getId(), mshost);
@@@ -1037,7 -1037,7 +1037,7 @@@
              logger.info("Starting Cluster manager, msid: {}, mshost: {}", _msId, _mshost);
          }
  
--        final ManagementServerHostVO mshost = Transaction.execute(new TransactionCallback<ManagementServerHostVO>() {
++        final ManagementServerHostVO mshost = Transaction.execute(new TransactionCallback<>() {
              @Override
              public ManagementServerHostVO doInTransaction(final TransactionStatus status) {
  
@@@ -1109,10 -1105,12 +1109,12 @@@
              if (mshost != null) {
                  ManagementServerStatusVO mshostStatus = mshostStatusDao.findByMsId(mshost.getUuid());
                  if (mshostStatus != null) {
+                     mshost.setState(ManagementServerHost.State.Down);
                      mshostStatus.setLastJvmStop(new Date());
+                     _mshostDao.update(_mshostId, mshost);
                      mshostStatusDao.update(mshostStatus.getId(), mshostStatus);
                  } else {
 -                    logger.warn(String.format("Found a management server host [%s] without a status. This should never happen!", mshost));
 +                    logger.warn("Found a management server host [{}] without a status. This should never happen!", mshost);
                      mshostStatus = new ManagementServerStatusVO();
                      mshostStatus.setMsId(mshost.getUuid());
                      mshostStatus.setLastSystemBoot(new Date());
@@@ -1135,7 -1127,7 +1137,7 @@@
          try {
              _heartbeatScheduler.awaitTermination(EXECUTOR_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
              _executor.awaitTermination(EXECUTOR_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
--        } catch (final InterruptedException e) {
++        } catch (final InterruptedException ignored) {
          }
  
          if (logger.isInfoEnabled()) {
@@@ -1271,14 -1263,14 +1273,14 @@@
                  if (sch != null) {
                      try {
                          sch.close();
--                    } catch (final IOException e) {
++                    } catch (final IOException ignored) {
                      }
                  }
              }
  
              try {
                  Thread.sleep(1000);
--            } catch (final InterruptedException ex) {
++            } catch (final InterruptedException ignored) {
              }
          }
  
diff --cc server/src/main/java/com/cloud/api/ApiServer.java
index df72a2719c2,5e962cdb382..b8227ef9d58
--- a/server/src/main/java/com/cloud/api/ApiServer.java
+++ b/server/src/main/java/com/cloud/api/ApiServer.java
@@@ -750,13 -744,8 +748,13 @@@ public class ApiServer extends ManagerB
          // BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as BaseAsyncCmd.
          // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized and returned.
          if (cmdObj instanceof BaseAsyncCmd) {
 +            if (!asyncMgr.isAsyncJobsEnabled()) {
 +                String msg = "Maintenance or Shutdown has been initiated on this management server. Can not accept new jobs";
 +                logger.warn(msg);
 +                throw new ServerApiException(ApiErrorCode.SERVICE_UNAVAILABLE, msg);
 +            }
              Long objectId = null;
-             String objectUuid = null;
+             String objectUuid;
              if (cmdObj instanceof BaseAsyncCreateCmd) {
                  final BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd)cmdObj;
                  dispatcher.dispatchCreateCmd(createCmd, params);
diff --cc ui/src/store/modules/user.js
index 1dacc09a54e,6113f3ed940..1dbb4136de1
--- a/ui/src/store/modules/user.js
+++ b/ui/src/store/modules/user.js
@@@ -328,10 -311,9 +328,10 @@@ const user = 
            commit('SET_TIMEZONE_OFFSET', cachedTimezoneOffset)
            commit('SET_USE_BROWSER_TIMEZONE', cachedUseBrowserTimezone)
            commit('SET_CUSTOM_COLUMNS', cachedCustomColumns)
 +          commit('SET_MS_ID', msId)
  
            // Ensuring we get the user info so that store.getters.user is never empty when the page is freshly loaded
-           api('listUsers', { username: Cookies.get('username'), listall: true }).then(response => {
+           api('listUsers', { id: Cookies.get('userid'), listall: true }).then(response => {
              const result = response.listusersresponse.user[0]
              commit('SET_INFO', result)
              commit('SET_NAME', result.firstname + ' ' + result.lastname)