mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Allow config drive deletion of migrated VM, on host maintenance (#10045)
This commit is contained in:
parent
a2f2e87c12
commit
b4ad04badf
@ -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";
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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) {
|
||||||
|
if (isoPath.startsWith(getConfigPath() + "/" + ConfigDrive.CONFIGDRIVEDIR) && isoPath.contains(vmName)) {
|
||||||
|
iso.defISODisk(isoPath, diskSeq, DiskDef.DiskType.FILE);
|
||||||
|
} else {
|
||||||
final int index = isoPath.lastIndexOf("/");
|
final int index = isoPath.lastIndexOf("/");
|
||||||
final String path = isoPath.substring(0, index);
|
final String path = isoPath.substring(0, index);
|
||||||
final String name = isoPath.substring(index + 1);
|
final String name = isoPath.substring(index + 1);
|
||||||
final KVMStoragePool secondaryPool = storagePoolManager.getStoragePoolByURI(path);
|
final KVMStoragePool storagePool = storagePoolManager.getStoragePoolByURI(path);
|
||||||
final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
|
final KVMPhysicalDisk isoVol = storagePool.getPhysicalDisk(name);
|
||||||
final DiskDef.DiskType diskType = getDiskType(isoVol);
|
final DiskDef.DiskType diskType = getDiskType(isoVol);
|
||||||
isoPath = isoVol.getPath();
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user