Allow config drive deletion of migrated VM, on host maintenance (#10045)

This commit is contained in:
Suresh Kumar Anaparti 2024-12-18 13:42:28 +05:30 committed by GitHub
parent a2f2e87c12
commit b4ad04badf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 59 additions and 27 deletions

View File

@ -73,6 +73,7 @@ public interface VmDetailConstants {
String ENCRYPTED_PASSWORD = "Encrypted.Password"; String ENCRYPTED_PASSWORD = "Encrypted.Password";
String CONFIG_DRIVE_LOCATION = "configDriveLocation"; String CONFIG_DRIVE_LOCATION = "configDriveLocation";
String LAST_CONFIG_DRIVE_LOCATION = "lastConfigDriveLocation";
String SKIP_DRS = "skipFromDRS"; String SKIP_DRS = "skipFromDRS";

View File

@ -46,6 +46,7 @@ import com.cloud.agent.api.CleanupNetworkRulesCmd;
import com.cloud.agent.api.Command; import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.HandleConfigDriveIsoCommand;
import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifySshKeysCommand;
@ -119,11 +120,10 @@ public abstract class AgentAttache {
public final static String[] s_commandsAllowedInMaintenanceMode = new String[] { MaintainCommand.class.toString(), MigrateCommand.class.toString(), public final static String[] s_commandsAllowedInMaintenanceMode = new String[] { MaintainCommand.class.toString(), MigrateCommand.class.toString(),
StopCommand.class.toString(), CheckVirtualMachineCommand.class.toString(), PingTestCommand.class.toString(), CheckHealthCommand.class.toString(), StopCommand.class.toString(), CheckVirtualMachineCommand.class.toString(), PingTestCommand.class.toString(), CheckHealthCommand.class.toString(),
ReadyCommand.class.toString(), ShutdownCommand.class.toString(), SetupCommand.class.toString(), ReadyCommand.class.toString(), ShutdownCommand.class.toString(), SetupCommand.class.toString(), CleanupNetworkRulesCmd.class.toString(),
CleanupNetworkRulesCmd.class.toString(), CheckNetworkCommand.class.toString(), PvlanSetupCommand.class.toString(), CheckOnHostCommand.class.toString(), CheckNetworkCommand.class.toString(), PvlanSetupCommand.class.toString(), CheckOnHostCommand.class.toString(), ModifyTargetsCommand.class.toString(),
ModifyTargetsCommand.class.toString(), ModifySshKeysCommand.class.toString(), ModifySshKeysCommand.class.toString(), CreateStoragePoolCommand.class.toString(), DeleteStoragePoolCommand.class.toString(), ModifyStoragePoolCommand.class.toString(),
CreateStoragePoolCommand.class.toString(), DeleteStoragePoolCommand.class.toString(), ModifyStoragePoolCommand.class.toString(), SetupMSListCommand.class.toString(), RollingMaintenanceCommand.class.toString(), CleanupPersistentNetworkResourceCommand.class.toString(), HandleConfigDriveIsoCommand.class.toString()};
SetupMSListCommand.class.toString(), RollingMaintenanceCommand.class.toString(), CleanupPersistentNetworkResourceCommand.class.toString()};
protected final static String[] s_commandsNotAllowedInConnectingMode = new String[] { StartCommand.class.toString(), CreateCommand.class.toString() }; protected final static String[] s_commandsNotAllowedInConnectingMode = new String[] { StartCommand.class.toString(), CreateCommand.class.toString() };
static { static {
Arrays.sort(s_commandsAllowedInMaintenanceMode); Arrays.sort(s_commandsAllowedInMaintenanceMode);

View File

@ -2985,9 +2985,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
public static boolean useBLOCKDiskType(KVMPhysicalDisk physicalDisk) { public static boolean useBLOCKDiskType(KVMPhysicalDisk physicalDisk) {
return physicalDisk != null && return physicalDisk != null &&
physicalDisk.getPool().getType() == StoragePoolType.Linstor && physicalDisk.getPool() != null &&
StoragePoolType.Linstor.equals(physicalDisk.getPool().getType()) &&
physicalDisk.getFormat() != null && physicalDisk.getFormat() != null &&
physicalDisk.getFormat()== PhysicalDiskFormat.RAW; PhysicalDiskFormat.RAW.equals(physicalDisk.getFormat());
} }
public static DiskDef.DiskType getDiskType(KVMPhysicalDisk physicalDisk) { public static DiskDef.DiskType getDiskType(KVMPhysicalDisk physicalDisk) {
@ -3402,13 +3403,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
} }
if (configdrive != null) { if (configdrive != null) {
try { try {
s_logger.debug(String.format("Detaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath()));
String result = attachOrDetachISO(conn, vmName, configdrive.getDiskPath(), false, CONFIG_DRIVE_ISO_DEVICE_ID); String result = attachOrDetachISO(conn, vmName, configdrive.getDiskPath(), false, CONFIG_DRIVE_ISO_DEVICE_ID);
if (result != null) { if (result != null) {
s_logger.warn("Detach ConfigDrive ISO with result: " + result); s_logger.warn(String.format("Detach ConfigDrive ISO of the VM %s, at path %s with %s: ", vmName, configdrive.getDiskPath(), result));
} }
s_logger.debug(String.format("Attaching ConfigDrive ISO of the VM %s, at path %s", vmName, configdrive.getDiskPath()));
result = attachOrDetachISO(conn, vmName, configdrive.getDiskPath(), true, CONFIG_DRIVE_ISO_DEVICE_ID); result = attachOrDetachISO(conn, vmName, configdrive.getDiskPath(), true, CONFIG_DRIVE_ISO_DEVICE_ID);
if (result != null) { if (result != null) {
s_logger.warn("Attach ConfigDrive ISO with result: " + result); s_logger.warn(String.format("Attach ConfigDrive ISO of the VM %s, at path %s with %s: ", vmName, configdrive.getDiskPath(), result));
} }
} catch (final LibvirtException | InternalErrorException | URISyntaxException e) { } catch (final LibvirtException | InternalErrorException | URISyntaxException e) {
final String msg = "Detach and attach ConfigDrive ISO failed due to " + e.toString(); final String msg = "Detach and attach ConfigDrive ISO failed due to " + e.toString();
@ -3420,16 +3423,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
public synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach, final Integer diskSeq) throws LibvirtException, URISyntaxException, public synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach, final Integer diskSeq) throws LibvirtException, URISyntaxException,
InternalErrorException { InternalErrorException {
final DiskDef iso = new DiskDef(); final DiskDef iso = new DiskDef();
if (isoPath != null && isAttach) { if (isAttach && StringUtils.isNotBlank(isoPath) && isoPath.lastIndexOf("/") > 0) {
final int index = isoPath.lastIndexOf("/"); if (isoPath.startsWith(getConfigPath() + "/" + ConfigDrive.CONFIGDRIVEDIR) && isoPath.contains(vmName)) {
final String path = isoPath.substring(0, index); iso.defISODisk(isoPath, diskSeq, DiskDef.DiskType.FILE);
final String name = isoPath.substring(index + 1); } else {
final KVMStoragePool secondaryPool = storagePoolManager.getStoragePoolByURI(path); final int index = isoPath.lastIndexOf("/");
final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name); final String path = isoPath.substring(0, index);
final DiskDef.DiskType diskType = getDiskType(isoVol); final String name = isoPath.substring(index + 1);
isoPath = isoVol.getPath(); final KVMStoragePool storagePool = storagePoolManager.getStoragePoolByURI(path);
final KVMPhysicalDisk isoVol = storagePool.getPhysicalDisk(name);
final DiskDef.DiskType diskType = getDiskType(isoVol);
isoPath = isoVol.getPath();
iso.defISODisk(isoPath, diskSeq, diskType); iso.defISODisk(isoPath, diskSeq, diskType);
}
} else { } else {
iso.defISODisk(null, diskSeq, DiskDef.DiskType.FILE); iso.defISODisk(null, diskSeq, DiskDef.DiskType.FILE);
} }

View File

@ -287,6 +287,7 @@ public class KVMStoragePoolManager {
URI storageUri = null; URI storageUri = null;
try { try {
s_logger.debug("Get storage pool by uri: " + uri);
storageUri = new URI(uri); storageUri = new URI(uri);
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
throw new CloudRuntimeException(e.toString()); throw new CloudRuntimeException(e.toString());
@ -296,7 +297,7 @@ public class KVMStoragePoolManager {
String uuid = null; String uuid = null;
String sourceHost = ""; String sourceHost = "";
StoragePoolType protocol = null; StoragePoolType protocol = null;
final String scheme = storageUri.getScheme().toLowerCase(); final String scheme = (storageUri.getScheme() != null) ? storageUri.getScheme().toLowerCase() : "";
List<String> acceptedSchemes = List.of("nfs", "networkfilesystem", "filesystem"); List<String> acceptedSchemes = List.of("nfs", "networkfilesystem", "filesystem");
if (acceptedSchemes.contains(scheme)) { if (acceptedSchemes.contains(scheme)) {
sourcePath = storageUri.getPath(); sourcePath = storageUri.getPath();

View File

@ -341,10 +341,10 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
try { try {
if (isConfigDriveIsoOnHostCache(vm.getId())) { if (isConfigDriveIsoOnHostCache(vm.getId())) {
vm.setConfigDriveLocation(Location.HOST); vm.setConfigDriveLocation(Location.HOST);
configureConfigDriveData(vm, nic, dest); if (configureConfigDriveData(vm, nic, dest)) {
// Create the config drive on dest host cache
// Create the config drive on dest host cache createConfigDriveIsoOnHostCache(vm, dest.getHost().getId());
createConfigDriveIsoOnHostCache(vm, dest.getHost().getId()); }
} else { } else {
vm.setConfigDriveLocation(getConfigDriveLocation(vm.getId())); vm.setConfigDriveLocation(getConfigDriveLocation(vm.getId()));
addPasswordAndUserdata(network, nic, vm, dest, context); addPasswordAndUserdata(network, nic, vm, dest, context);
@ -373,7 +373,7 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
@Override @Override
public void commitMigration(NicProfile nic, Network network, VirtualMachineProfile vm, ReservationContext src, ReservationContext dst) { public void commitMigration(NicProfile nic, Network network, VirtualMachineProfile vm, ReservationContext src, ReservationContext dst) {
try { try {
if (isConfigDriveIsoOnHostCache(vm.getId())) { if (isLastConfigDriveIsoOnHostCache(vm.getId())) {
vm.setConfigDriveLocation(Location.HOST); vm.setConfigDriveLocation(Location.HOST);
// Delete the config drive on src host cache // Delete the config drive on src host cache
deleteConfigDriveIsoOnHostCache(vm.getVirtualMachine(), vm.getHostId()); deleteConfigDriveIsoOnHostCache(vm.getVirtualMachine(), vm.getHostId());
@ -530,6 +530,17 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
return false; return false;
} }
private boolean isLastConfigDriveIsoOnHostCache(long vmId) {
final UserVmDetailVO vmDetailLastConfigDriveLocation = _userVmDetailsDao.findDetail(vmId, VmDetailConstants.LAST_CONFIG_DRIVE_LOCATION);
if (vmDetailLastConfigDriveLocation == null) {
return isConfigDriveIsoOnHostCache(vmId);
}
if (Location.HOST.toString().equalsIgnoreCase(vmDetailLastConfigDriveLocation.getValue())) {
return true;
}
return false;
}
private boolean createConfigDriveIsoOnHostCache(VirtualMachineProfile profile, Long hostId) throws ResourceUnavailableException { private boolean createConfigDriveIsoOnHostCache(VirtualMachineProfile profile, Long hostId) throws ResourceUnavailableException {
if (hostId == null) { if (hostId == null) {
throw new ResourceUnavailableException("Config drive iso creation failed, dest host not available", throw new ResourceUnavailableException("Config drive iso creation failed, dest host not available",
@ -556,7 +567,7 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
} }
profile.setConfigDriveLocation(answer.getConfigDriveLocation()); profile.setConfigDriveLocation(answer.getConfigDriveLocation());
_userVmDetailsDao.addDetail(profile.getId(), VmDetailConstants.CONFIG_DRIVE_LOCATION, answer.getConfigDriveLocation().toString(), false); updateConfigDriveLocationInVMDetails(profile.getId(), answer.getConfigDriveLocation());
addConfigDriveDisk(profile, null); addConfigDriveDisk(profile, null);
return true; return true;
} }
@ -618,11 +629,23 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
answer.getDetails()), ConfigDriveNetworkElement.class, 0L); answer.getDetails()), ConfigDriveNetworkElement.class, 0L);
} }
profile.setConfigDriveLocation(answer.getConfigDriveLocation()); profile.setConfigDriveLocation(answer.getConfigDriveLocation());
_userVmDetailsDao.addDetail(profile.getId(), VmDetailConstants.CONFIG_DRIVE_LOCATION, answer.getConfigDriveLocation().toString(), false); updateConfigDriveLocationInVMDetails(profile.getId(), answer.getConfigDriveLocation());
addConfigDriveDisk(profile, dataStore); addConfigDriveDisk(profile, dataStore);
return true; return true;
} }
private void updateConfigDriveLocationInVMDetails(long vmId, NetworkElement.Location configDriveLocation) {
final UserVmDetailVO vmDetailConfigDriveLocation = _userVmDetailsDao.findDetail(vmId, VmDetailConstants.CONFIG_DRIVE_LOCATION);
if (vmDetailConfigDriveLocation != null) {
if (!configDriveLocation.toString().equalsIgnoreCase(vmDetailConfigDriveLocation.getValue())) {
_userVmDetailsDao.addDetail(vmId, VmDetailConstants.LAST_CONFIG_DRIVE_LOCATION, vmDetailConfigDriveLocation.getValue(), false);
} else {
_userVmDetailsDao.removeDetail(vmId, VmDetailConstants.LAST_CONFIG_DRIVE_LOCATION);
}
}
_userVmDetailsDao.addDetail(vmId, VmDetailConstants.CONFIG_DRIVE_LOCATION, configDriveLocation.toString(), false);
}
private Map<String, String> getVMCustomUserdataParamMap(long vmId) { private Map<String, String> getVMCustomUserdataParamMap(long vmId) {
UserVmVO userVm = _userVmDao.findById(vmId); UserVmVO userVm = _userVmDao.findById(vmId);
String userDataDetails = userVm.getUserDataDetails(); String userDataDetails = userVm.getUserDataDetails();
@ -737,7 +760,7 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
private boolean configureConfigDriveData(final VirtualMachineProfile profile, final NicProfile nic, final DeployDestination dest) { private boolean configureConfigDriveData(final VirtualMachineProfile profile, final NicProfile nic, final DeployDestination dest) {
final UserVmVO vm = _userVmDao.findById(profile.getId()); final UserVmVO vm = _userVmDao.findById(profile.getId());
if (vm.getType() != VirtualMachine.Type.User) { if (vm == null || vm.getType() != VirtualMachine.Type.User) {
return false; return false;
} }
final Nic defaultNic = _networkModel.getDefaultNic(vm.getId()); final Nic defaultNic = _networkModel.getDefaultNic(vm.getId());