Change `vmsnapshot.max` setting scope to the account level (#11616)

This commit is contained in:
Bernardo De Marco Gonçalves 2026-01-29 06:01:54 -03:00 committed by GitHub
parent 9b4f16b73f
commit c681d0d0a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 20 additions and 4 deletions

View File

@ -31,7 +31,7 @@ public interface VMSnapshotManager extends VMSnapshotService, Manager {
static final ConfigKey<Integer> VMSnapshotExpireInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vmsnapshot.expire.interval", "-1",
"VM Snapshot expire interval in hours", true, ConfigKey.Scope.Account);
ConfigKey<Integer> VMSnapshotMax = new ConfigKey<Integer>("Advanced", Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a single vm", true, ConfigKey.Scope.Global);
ConfigKey<Integer> VMSnapshotMax = new ConfigKey<Integer>("Advanced", Integer.class, "vmsnapshot.max", "10", "Maximum VM snapshots for a single VM", true, ConfigKey.Scope.Account);
/**
* Delete all VM snapshots belonging to one VM

View File

@ -400,10 +400,11 @@ public class VMSnapshotManagerImpl extends MutualExclusiveIdsManagerBase impleme
_accountMgr.checkAccess(caller, null, true, userVmVo);
// check max snapshot limit for per VM
int vmSnapshotMax = VMSnapshotManager.VMSnapshotMax.value();
boolean vmBelongsToProject = _accountMgr.getAccount(userVmVo.getAccountId()).getType() == Account.Type.PROJECT;
long accountIdToRetrieveConfigurationValueFrom = vmBelongsToProject ? caller.getId() : userVmVo.getAccountId();
int vmSnapshotMax = VMSnapshotManager.VMSnapshotMax.valueIn(accountIdToRetrieveConfigurationValueFrom);
if (_vmSnapshotDao.findByVm(vmId).size() >= vmSnapshotMax) {
throw new CloudRuntimeException("Creating Instance Snapshot failed due to a Instance can just have : " + vmSnapshotMax + " Instance Snapshots. Please delete old ones");
throw new CloudRuntimeException(String.format("Each VM can have at most [%s] VM snapshots.", vmSnapshotMax));
}
// check if there are active volume snapshots tasks

View File

@ -41,6 +41,7 @@ import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.uservm.UserVm;
@ -136,6 +137,8 @@ public class VMSnapshotManagerTest {
VMSnapshotDetailsDao _vmSnapshotDetailsDao;
@Mock
UserVmManager _userVmManager;
@Mock
private AccountVO accountVOMock;
private static final long TEST_VM_ID = 3L;
private static final long SERVICE_OFFERING_ID = 1L;
@ -285,8 +288,12 @@ public class VMSnapshotManagerTest {
@SuppressWarnings("unchecked")
@Test(expected = CloudRuntimeException.class)
public void testAllocVMSnapshotF4() throws ResourceAllocationException {
long accountId = 1L;
List<VMSnapshotVO> mockList = mock(List.class);
when(mockList.size()).thenReturn(10);
when(_userVMDao.findById(TEST_VM_ID)).thenReturn(vmMock);
when(userVm.getAccountId()).thenReturn(accountId);
when(_accountMgr.getAccount(accountId)).thenReturn(accountVOMock);
when(_vmSnapshotDao.findByVm(TEST_VM_ID)).thenReturn(mockList);
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID, "", "", true);
}
@ -295,8 +302,12 @@ public class VMSnapshotManagerTest {
@SuppressWarnings("unchecked")
@Test(expected = CloudRuntimeException.class)
public void testAllocVMSnapshotF5() throws ResourceAllocationException {
long accountId = 1L;
List<SnapshotVO> mockList = mock(List.class);
when(mockList.size()).thenReturn(1);
when(_userVMDao.findById(TEST_VM_ID)).thenReturn(vmMock);
when(userVm.getAccountId()).thenReturn(accountId);
when(_accountMgr.getAccount(accountId)).thenReturn(accountVOMock);
when(_snapshotDao.listByInstanceId(TEST_VM_ID, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList);
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID, "", "", true);
}
@ -304,6 +315,10 @@ public class VMSnapshotManagerTest {
// successful creation case
@Test
public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTimedoutException, ResourceAllocationException, NoTransitionException {
long accountId = 1L;
when(_userVMDao.findById(TEST_VM_ID)).thenReturn(vmMock);
when(userVm.getAccountId()).thenReturn(accountId);
when(_accountMgr.getAccount(accountId)).thenReturn(accountVOMock);
when(vmMock.getState()).thenReturn(State.Running);
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID, "", "", true);
}