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

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

commit 1bff543e58e626a7bcdea265284c8f3bcf57c7b0
Merge: b744824f658 c1af36f8fc9
Author: Suresh Kumar Anaparti <[email protected]>
AuthorDate: Fri Mar 27 01:25:42 2026 +0530

    Merge branch '4.22'

 api/src/main/java/com/cloud/vm/UserVmService.java  |   3 +-
 api/src/main/java/com/cloud/vm/VirtualMachine.java |   3 +
 .../api/command/admin/vm/ImportVmCmd.java          |  12 ++
 .../api/command/user/guest/ListGuestOsCmd.java     |   9 ++
 .../api/command/user/vpc/CreateStaticRouteCmd.java |   1 -
 .../api/response/UnmanagedInstanceResponse.java    |  24 ++++
 .../volume/VolumeImportUnmanageService.java        |  13 +-
 .../apache/cloudstack/vm/UnmanagedInstanceTO.java  |  19 +++
 .../apache/cloudstack/vm/UnmanagedVMsManager.java  |   2 +
 .../engine/orchestration/NetworkOrchestrator.java  |   7 +-
 .../java/com/cloud/storage/dao/GuestOSDao.java     |   2 +-
 .../java/com/cloud/storage/dao/GuestOSDaoImpl.java |   6 +-
 .../main/java/com/cloud/storage/dao/VolumeDao.java |   8 ++
 .../java/com/cloud/storage/dao/VolumeDaoImpl.java  |  12 ++
 .../com/cloud/upgrade/dao/Upgrade42200to42210.java |  51 ++++++++
 .../datastore/db/SnapshotDataStoreDaoImpl.java     |  14 +--
 .../META-INF/db/schema-42200to42210-cleanup.sql    |   2 +
 .../resources/META-INF/db/schema-42200to42210.sql  |   2 +
 .../db/views/cloud.account_netstats_view.sql       |  31 -----
 .../META-INF/db/views/cloud.account_view.sql       |  15 ++-
 .../motion/StorageSystemDataMotionStrategy.java    |   4 +-
 .../wrapper/LibvirtGetRemoteVmsCommandWrapper.java |   2 +
 ...LibvirtGetUnmanagedInstancesCommandWrapper.java |   2 +
 .../java/org/apache/cloudstack/saml/SAMLUtils.java |   3 +
 .../main/java/com/cloud/api/ApiResponseHelper.java |  17 ++-
 .../deploy/DeploymentPlanningManagerImpl.java      |   4 +-
 .../com/cloud/server/ManagementServerImpl.java     |  33 ++++--
 .../com/cloud/template/TemplateManagerImpl.java    |   3 +
 .../src/main/java/com/cloud/vm/UserVmManager.java  |   5 +
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  | 132 ++++++++++++++-------
 .../volume/VolumeImportUnmanageManagerImpl.java    |  15 ++-
 .../cloudstack/vm/UnmanagedVMsManagerImpl.java     | 100 ++++------------
 .../java/com/cloud/vm/UserVmManagerImplTest.java   |  54 +++++++++
 .../cloudstack/vm/UnmanagedVMsManagerImplTest.java |  55 ++++++++-
 test/integration/smoke/test_secondary_storage.py   |  16 ++-
 ui/public/locales/en.json                          |   1 +
 ui/src/permission.js                               |   1 +
 ui/src/views/compute/DeployVM.vue                  |   6 +
 .../compute/wizard/SecurityGroupSelection.vue      |  26 +++-
 ui/src/views/image/TemplateZones.vue               |  14 ++-
 ui/src/views/network/CreateNetwork.vue             |   2 +-
 ui/src/views/network/VpcTiersTab.vue               |  10 +-
 ui/src/views/tools/ImportUnmanagedInstance.vue     |  37 +++++-
 ui/src/views/tools/ManageInstances.vue             |  21 +++-
 .../com/cloud/hypervisor/vmware/mo/BaseMO.java     |  27 ++++-
 .../cloud/hypervisor/vmware/util/VmwareHelper.java |  16 ++-
 .../hypervisor/vmware/util/VmwareHelperTest.java   |  23 ++++
 47 files changed, 645 insertions(+), 220 deletions(-)

diff --cc server/src/main/java/com/cloud/server/ManagementServerImpl.java
index f8c4d1d44d4,4875002074c..15286eaaf54
--- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@@ -43,7 -43,7 +43,8 @@@ import javax.crypto.spec.SecretKeySpec
  import javax.inject.Inject;
  import javax.naming.ConfigurationException;
  
 +import org.apache.cloudstack.acl.ApiKeyPairVO;
+ import com.cloud.api.query.MutualExclusiveIdsManagerBase;
  import com.cloud.network.vpc.VpcVO;
  import org.apache.cloudstack.acl.ControlledEntity;
  import org.apache.cloudstack.acl.SecurityChecker;
diff --cc server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
index 4597ef81965,4cb721666bd..f4ea7bd9311
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@@ -1172,9 -1192,9 +1172,9 @@@ public class UserVmManagerImpl extends 
                  if (dc.getNetworkType() == DataCenter.NetworkType.Advanced) {
                      //List all networks of vm
                      List<Long> vmNetworks = 
_vmNetworkMapDao.getNetworks(vmId);
 -                    List<DomainRouterVO> routers = new 
ArrayList<DomainRouterVO>();
 +                    List<DomainRouterVO> routers = new ArrayList<>();
                      //List the stopped routers
-                     for(long vmNetworkId : vmNetworks) {
+                     for (long vmNetworkId : vmNetworks) {
                          List<DomainRouterVO> router = 
_routerDao.listStopped(vmNetworkId);
                          routers.addAll(router);
                      }
diff --cc server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
index f7439386fab,783be00c449..4e6627f4640
--- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
+++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
@@@ -198,6 -195,6 +198,7 @@@ import com.cloud.utils.db.EntityManager
  import com.cloud.utils.db.UUIDManager;
  import com.cloud.utils.exception.CloudRuntimeException;
  import com.cloud.utils.exception.ExceptionProxyObject;
++import com.cloud.utils.fsm.NoTransitionException;
  import com.cloud.vm.dao.NicDao;
  import com.cloud.vm.dao.UserVmDao;
  import com.cloud.vm.dao.VMInstanceDetailsDao;
@@@ -1501,6 -1477,9 +1502,7 @@@ public class UserVmManagerImplTest 
          when(cmd.getVmId()).thenReturn(vmId);
          when(cmd.getTemplateId()).thenReturn(2L);
          when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
 -        KubernetesServiceHelper helper = mock(KubernetesServiceHelper.class);
 -        when(helper.findByVmId(anyLong())).thenReturn(null);
 -        
userVmManagerImpl.setKubernetesServiceHelpers(Collections.singletonList(helper));
++        
Mockito.doReturn(false).when(userVmManagerImpl).isVMPartOfAnyCKSCluster(userVmVoMock);
  
          userVmManagerImpl.restoreVM(cmd);
      }
@@@ -4206,49 -4182,55 +4208,101 @@@
          verify(userVmDao, times(1)).releaseFromLockTable(vmId);
      }
  
 +    @Test
 +    public void updateVmExtraConfigCleansUpWhenCleanupFlagIsTrue() {
 +        UserVmVO userVm = mock(UserVmVO.class);
 +        when(userVm.getUuid()).thenReturn("test-uuid");
 +        when(userVm.getId()).thenReturn(1L);
 +
 +        userVmManagerImpl.updateVmExtraConfig(userVm, "someConfig", true);
 +
 +        verify(vmInstanceDetailsDao, times(1)).removeDetailsWithPrefix(1L, 
ApiConstants.EXTRA_CONFIG);
 +        verifyNoMoreInteractions(vmInstanceDetailsDao);
 +    }
 +
 +    @Test
 +    public void updateVmExtraConfigAddsConfigWhenValidAndEnabled() {
 +        UserVmVO userVm = mock(UserVmVO.class);
 +        when(userVm.getUuid()).thenReturn("test-uuid");
 +        when(userVm.getAccountId()).thenReturn(1L);
 +        
when(userVm.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
 +        
doNothing().when(userVmManagerImpl).persistExtraConfigKvm(anyString(), 
eq(userVm));
 +        updateDefaultConfigValue(UserVmManagerImpl.EnableAdditionalVmConfig, 
true, false);
 +
 +        userVmManagerImpl.updateVmExtraConfig(userVm, "validConfig", false);
 +
 +        verify(vmInstanceDetailsDao, 
never()).removeDetailsWithPrefix(anyLong(), anyString());
 +        verify(userVmManagerImpl, times(1)).addExtraConfig(userVm, 
"validConfig");
 +    }
 +
 +    @Test(expected = InvalidParameterValueException.class)
 +    public void updateVmExtraConfigThrowsExceptionWhenConfigDisabled() {
 +        UserVmVO userVm = mock(UserVmVO.class);
 +        when(userVm.getAccountId()).thenReturn(1L);
 +        updateDefaultConfigValue(UserVmManagerImpl.EnableAdditionalVmConfig, 
false, false);
 +
 +        userVmManagerImpl.updateVmExtraConfig(userVm, "validConfig", false);
 +    }
 +
 +    @Test
 +    public void updateVmExtraConfigDoesNothingWhenExtraConfigIsBlank() {
 +        UserVmVO userVm = mock(UserVmVO.class);
 +
 +        userVmManagerImpl.updateVmExtraConfig(userVm, "", false);
 +
 +        verify(vmInstanceDetailsDao, 
never()).removeDetailsWithPrefix(anyLong(), anyString());
 +        verify(userVmManagerImpl, 
never()).addExtraConfig(any(UserVmVO.class), anyString());
 +    }
++
+     @Test
+     public void testTransitionExpungingToErrorVmInExpungingState() throws 
Exception {
+         UserVmVO vm = mock(UserVmVO.class);
+         when(vm.getState()).thenReturn(VirtualMachine.State.Expunging);
+         when(vm.getUuid()).thenReturn("test-uuid");
+         when(userVmDao.findById(vmId)).thenReturn(vm);
+         when(virtualMachineManager.stateTransitTo(eq(vm), 
eq(VirtualMachine.Event.OperationFailedToError), eq(null))).thenReturn(true);
+ 
+         java.lang.reflect.Method method = 
UserVmManagerImpl.class.getDeclaredMethod("transitionExpungingToError", 
long.class);
+         method.setAccessible(true);
+         method.invoke(userVmManagerImpl, vmId);
+ 
+         Mockito.verify(virtualMachineManager).stateTransitTo(vm, 
VirtualMachine.Event.OperationFailedToError, null);
+     }
+ 
+     @Test
+     public void testTransitionExpungingToErrorVmNotInExpungingState() throws 
Exception {
+         UserVmVO vm = mock(UserVmVO.class);
+         when(vm.getState()).thenReturn(VirtualMachine.State.Stopped);
+         when(userVmDao.findById(vmId)).thenReturn(vm);
+ 
+         java.lang.reflect.Method method = 
UserVmManagerImpl.class.getDeclaredMethod("transitionExpungingToError", 
long.class);
+         method.setAccessible(true);
+         method.invoke(userVmManagerImpl, vmId);
+ 
+         Mockito.verify(virtualMachineManager, 
Mockito.never()).stateTransitTo(any(VirtualMachine.class), 
any(VirtualMachine.Event.class), any());
+     }
+ 
+     @Test
+     public void testTransitionExpungingToErrorVmNotFound() throws Exception {
+         when(userVmDao.findById(vmId)).thenReturn(null);
+ 
+         java.lang.reflect.Method method = 
UserVmManagerImpl.class.getDeclaredMethod("transitionExpungingToError", 
long.class);
+         method.setAccessible(true);
+         method.invoke(userVmManagerImpl, vmId);
+ 
+         Mockito.verify(virtualMachineManager, 
Mockito.never()).stateTransitTo(any(VirtualMachine.class), 
any(VirtualMachine.Event.class), any());
+     }
+ 
+     @Test
+     public void testTransitionExpungingToErrorHandlesNoTransitionException() 
throws Exception {
+         UserVmVO vm = mock(UserVmVO.class);
+         when(vm.getState()).thenReturn(VirtualMachine.State.Expunging);
+         when(userVmDao.findById(vmId)).thenReturn(vm);
+         when(virtualMachineManager.stateTransitTo(eq(vm), 
eq(VirtualMachine.Event.OperationFailedToError), eq(null)))
+                 .thenThrow(new NoTransitionException("no transition"));
+ 
+         java.lang.reflect.Method method = 
UserVmManagerImpl.class.getDeclaredMethod("transitionExpungingToError", 
long.class);
+         method.setAccessible(true);
+         method.invoke(userVmManagerImpl, vmId);
+     }
  }
diff --cc ui/src/permission.js
index 671d6626b93,eeb36c57117..0b87de92c6b
--- a/ui/src/permission.js
+++ b/ui/src/permission.js
@@@ -93,17 -93,8 +93,18 @@@ router.beforeEach((to, from, next) => 
            return
          }
          store.commit('SET_LOGIN_FLAG', true)
+         store.commit('SET_MS_ID', Cookies.get('managementserverid'))
        }
 +      // store already loaded
 +      if (store.getters.passwordChangeRequired) {
 +        if (to.path === '/user/forceChangePassword') {
 +          next()
 +        } else {
 +          next({ path: '/user/forceChangePassword' })
 +          NProgress.done()
 +        }
 +        return
 +      }
        if (Object.keys(store.getters.apis).length === 0) {
          const cachedApis = vueProps.$localStorage.get(APIS, {})
          if (Object.keys(cachedApis).length > 0) {

Reply via email to