Skip to content

Commit a968eb1

Browse files
authored
Merge branch 'apache:4.19' into 4.19
2 parents 60c84d1 + f055268 commit a968eb1

File tree

56 files changed

+572
-329
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+572
-329
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ jobs:
232232
233233
- name: Install Python dependencies
234234
run: |
235-
python3 -m pip install --user --upgrade urllib3 lxml paramiko nose texttable ipmisim pyopenssl pycrypto mock flask netaddr pylint pycodestyle six astroid
235+
python3 -m pip install --user --upgrade urllib3 lxml paramiko nose texttable ipmisim pyopenssl pycrypto mock flask netaddr pylint pycodestyle six astroid pynose
236236
237237
- name: Install jacoco dependencies
238238
run: |

api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.apache.cloudstack.api.response.SecurityGroupResponse;
4242
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
4343
import org.apache.cloudstack.api.response.TemplateResponse;
44+
import org.apache.cloudstack.api.response.UserDataResponse;
4445
import org.apache.cloudstack.api.response.UserResponse;
4546
import org.apache.cloudstack.api.response.UserVmResponse;
4647
import org.apache.cloudstack.api.response.VpcResponse;
@@ -151,6 +152,9 @@ public class ListVMsCmd extends BaseListRetrieveOnlyResourceCountCmd implements
151152
@Parameter(name = ApiConstants.USER_DATA, type = CommandType.BOOLEAN, description = "Whether to return the VMs' user data or not. By default, user data will not be returned.", since = "4.18.0.0")
152153
private Boolean showUserData;
153154

155+
@Parameter(name = ApiConstants.USER_DATA_ID, type = CommandType.UUID, entityType = UserDataResponse.class, required = false, description = "the instances by userdata", since = "4.20.1")
156+
private Long userdataId;
157+
154158
/////////////////////////////////////////////////////
155159
/////////////////// Accessors ///////////////////////
156160
/////////////////////////////////////////////////////
@@ -245,6 +249,10 @@ protected boolean isViewDetailsEmpty() {
245249
return CollectionUtils.isEmpty(viewDetails);
246250
}
247251

252+
public Long getUserdataId() {
253+
return userdataId;
254+
}
255+
248256
public EnumSet<VMDetails> getDetails() throws InvalidParameterValueException {
249257
if (isViewDetailsEmpty()) {
250258
if (_queryService.ReturnVmStatsOnVmList.value()) {

api/src/main/java/org/apache/cloudstack/api/response/NetworkResponse.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@
2727
import org.apache.cloudstack.api.EntityReference;
2828

2929
import com.cloud.network.Network;
30-
import com.cloud.projects.ProjectAccount;
3130
import com.cloud.serializer.Param;
3231
import com.google.gson.annotations.SerializedName;
3332

3433
@SuppressWarnings("unused")
35-
@EntityReference(value = {Network.class, ProjectAccount.class})
34+
@EntityReference(value = {Network.class})
3635
public class NetworkResponse extends BaseResponseWithAssociatedNetwork implements ControlledEntityResponse, SetResourceIconResponse {
3736

3837
@SerializedName(ApiConstants.ID)

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5248,10 +5248,9 @@ public Outcome<VirtualMachine> migrateVmAwayThroughJobQueue(final String vmUuid,
52485248
workJob = newVmWorkJobAndInfo.first();
52495249
VmWorkMigrateAway workInfo = new VmWorkMigrateAway(newVmWorkJobAndInfo.second(), srcHostId);
52505250

5251-
workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
5251+
setCmdInfoAndSubmitAsyncJob(workJob, workInfo, vmId);
52525252
}
52535253

5254-
_jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vmId);
52555254

52565255
AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
52575256

engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ public void setRemoved(Date removed) {
502502

503503
@Override
504504
public String toString() {
505-
return String.format("VM instance %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "instanceName", "uuid", "type"));
505+
return String.format("VM instance %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "instanceName", "uuid", "type", "state"));
506506
}
507507

508508
@Override

engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/BasePrimaryDataStoreLifeCycleImpl.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,13 @@
2222

2323
import javax.inject.Inject;
2424

25+
import com.cloud.storage.VMTemplateStoragePoolVO;
26+
import com.cloud.storage.VMTemplateStorageResourceAssoc;
27+
import com.cloud.template.TemplateManager;
2528
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
2629
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
30+
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
31+
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
2732
import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
2833
import org.apache.log4j.Logger;
2934

@@ -54,6 +59,10 @@ public class BasePrimaryDataStoreLifeCycleImpl {
5459
protected HostDao hostDao;
5560
@Inject
5661
protected StoragePoolHostDao storagePoolHostDao;
62+
@Inject
63+
private PrimaryDataStoreDao primaryDataStoreDao;
64+
@Inject
65+
private TemplateManager templateMgr;
5766

5867
private List<HostVO> getPoolHostsList(ClusterScope clusterScope, HypervisorType hypervisorType) {
5968
List<HostVO> hosts;
@@ -103,4 +112,42 @@ public void changeStoragePoolScopeToCluster(DataStore store, ClusterScope cluste
103112
}
104113
dataStoreHelper.switchToCluster(store, clusterScope);
105114
}
115+
116+
private void evictTemplates(StoragePoolVO storagePoolVO) {
117+
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = templateMgr.getUnusedTemplatesInPool(storagePoolVO);
118+
for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
119+
if (templatePoolVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
120+
templateMgr.evictTemplateFromStoragePool(templatePoolVO);
121+
}
122+
}
123+
}
124+
125+
private void deleteAgentStoragePools(StoragePool storagePool) {
126+
List<StoragePoolHostVO> poolHostVOs = storagePoolHostDao.listByPoolId(storagePool.getId());
127+
for (StoragePoolHostVO poolHostVO : poolHostVOs) {
128+
DeleteStoragePoolCommand deleteStoragePoolCommand = new DeleteStoragePoolCommand(storagePool);
129+
final Answer answer = agentMgr.easySend(poolHostVO.getHostId(), deleteStoragePoolCommand);
130+
if (answer != null && answer.getResult()) {
131+
s_logger.info("Successfully deleted storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId());
132+
} else {
133+
if (answer != null) {
134+
s_logger.error("Failed to delete storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId() + " , result: " + answer.getResult());
135+
} else {
136+
s_logger.error("Failed to delete storage pool: " + storagePool.getId() + " from host: " + poolHostVO.getHostId());
137+
}
138+
}
139+
}
140+
}
141+
142+
protected boolean cleanupDatastore(DataStore store) {
143+
StoragePool storagePool = (StoragePool)store;
144+
StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(storagePool.getId());
145+
if (storagePoolVO == null) {
146+
return false;
147+
}
148+
149+
evictTemplates(storagePoolVO);
150+
deleteAgentStoragePools(storagePool);
151+
return true;
152+
}
106153
}

framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,12 +1052,24 @@ public boolean stop() {
10521052
}
10531053

10541054
if (_mshostId != null) {
1055-
final ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId);
1056-
final ManagementServerStatusVO mshostStatus = mshostStatusDao.findByMsId(mshost.getUuid());
1057-
mshost.setState(ManagementServerHost.State.Down);
1058-
mshostStatus.setLastJvmStop(new Date());
1059-
_mshostDao.update(_mshostId, mshost);
1060-
mshostStatusDao.update(mshostStatus.getId(), mshostStatus);
1055+
ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId);
1056+
if (mshost != null) {
1057+
ManagementServerStatusVO mshostStatus = mshostStatusDao.findByMsId(mshost.getUuid());
1058+
if (mshostStatus != null) {
1059+
mshost.setState(ManagementServerHost.State.Down);
1060+
mshostStatus.setLastJvmStop(new Date());
1061+
_mshostDao.update(_mshostId, mshost);
1062+
mshostStatusDao.update(mshostStatus.getId(), mshostStatus);
1063+
} else {
1064+
s_logger.warn(String.format("Found a management server host [%s] without a status. This should never happen!", mshost));
1065+
mshostStatus = new ManagementServerStatusVO();
1066+
mshostStatus.setMsId(mshost.getUuid());
1067+
mshostStatus.setLastSystemBoot(new Date());
1068+
mshostStatus.setLastJvmStart(new Date());
1069+
mshostStatus.setUpdated(new Date());
1070+
mshostStatusDao.persist(mshostStatus);
1071+
}
1072+
}
10611073
}
10621074

10631075
_heartbeatScheduler.shutdownNow();

plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/VeeamBackupProvider.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ public boolean assignVMToBackupOffering(final VirtualMachine vm, final BackupOff
199199
public boolean removeVMFromBackupOffering(final VirtualMachine vm) {
200200
final VeeamClient client = getClient(vm.getDataCenterId());
201201
final VmwareDatacenter vmwareDC = findVmwareDatacenterForVM(vm);
202+
if (vm.getBackupExternalId() == null) {
203+
throw new CloudRuntimeException("The VM does not have a backup job assigned.");
204+
}
202205
try {
203206
if (!client.removeVMFromVeeamJob(vm.getBackupExternalId(), vm.getInstanceName(), vmwareDC.getVcenterHost())) {
204207
LOG.warn("Failed to remove VM from Veeam Job id: " + vm.getBackupExternalId());

plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@
5151
import javax.naming.ConfigurationException;
5252
import javax.xml.parsers.ParserConfigurationException;
5353

54-
import com.trilead.ssh2.SFTPException;
55-
import com.trilead.ssh2.SFTPv3Client;
56-
import com.trilead.ssh2.SFTPv3DirectoryEntry;
57-
import com.trilead.ssh2.SFTPv3FileAttributes;
5854
import org.apache.cloudstack.api.ApiConstants;
5955
import org.apache.cloudstack.diagnostics.CopyToSecondaryStorageAnswer;
6056
import org.apache.cloudstack.diagnostics.CopyToSecondaryStorageCommand;
@@ -72,6 +68,7 @@
7268
import org.apache.commons.lang3.BooleanUtils;
7369
import org.apache.commons.lang3.StringUtils;
7470
import org.apache.log4j.Logger;
71+
import org.apache.maven.artifact.versioning.ComparableVersion;
7572
import org.apache.xmlrpc.XmlRpcException;
7673
import org.joda.time.Duration;
7774
import org.w3c.dom.Document;
@@ -153,6 +150,10 @@
153150
import com.cloud.vm.VirtualMachine.PowerState;
154151
import com.cloud.vm.VmDetailConstants;
155152
import com.trilead.ssh2.SCPClient;
153+
import com.trilead.ssh2.SFTPException;
154+
import com.trilead.ssh2.SFTPv3Client;
155+
import com.trilead.ssh2.SFTPv3DirectoryEntry;
156+
import com.trilead.ssh2.SFTPv3FileAttributes;
156157
import com.xensource.xenapi.Bond;
157158
import com.xensource.xenapi.Connection;
158159
import com.xensource.xenapi.Console;
@@ -627,7 +628,7 @@ public boolean cleanupHaltedVms(final Connection conn) throws XenAPIException, X
627628

628629
if (VmPowerState.HALTED.equals(vmRec.powerState) && vmRec.affinity.equals(host) && !isAlienVm(vm, conn)) {
629630
try {
630-
vm.destroy(conn);
631+
destroyVm(vm, conn);
631632
} catch (final Exception e) {
632633
s_logger.warn("Catch Exception " + e.getClass().getName() + ": unable to destroy VM " + vmRec.nameLabel + " due to ", e);
633634
success = false;
@@ -1452,7 +1453,7 @@ public VM createVmFromTemplate(final Connection conn, final VirtualMachineTO vmS
14521453
vm.setPVBootloader(conn, "pygrub");
14531454
vm.setPVBootloaderArgs(conn, CitrixHelper.getPVbootloaderArgs(guestOsTypeName));
14541455
} else {
1455-
vm.destroy(conn);
1456+
destroyVm(vm, conn, true);
14561457
throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader());
14571458
}
14581459
}
@@ -2038,7 +2039,7 @@ void forceShutdownVM(final Connection conn, final VM vm) {
20382039
final Long domId = vm.getDomid(conn);
20392040
callHostPlugin(conn, "vmopspremium", "forceShutdownVM", "domId", domId.toString());
20402041
vm.powerStateReset(conn);
2041-
vm.destroy(conn);
2042+
destroyVm(vm, conn);
20422043
} catch (final Exception e) {
20432044
final String msg = "forceShutdown failed due to " + e.toString();
20442045
s_logger.warn(msg, e);
@@ -3690,7 +3691,7 @@ public String handleVmStartFailure(final Connection conn, final String vmName, f
36903691
}
36913692
if (vm.getPowerState(conn) == VmPowerState.HALTED) {
36923693
try {
3693-
vm.destroy(conn);
3694+
destroyVm(vm, conn, true);
36943695
} catch (final Exception e) {
36953696
s_logger.warn("VM destroy failed due to ", e);
36963697
}
@@ -5208,7 +5209,7 @@ protected void startvmfailhandle(final Connection conn, final VM vm, final List<
52085209
}
52095210
if (vm.getPowerState(conn) == VmPowerState.HALTED) {
52105211
try {
5211-
vm.destroy(conn);
5212+
destroyVm(vm, conn, true);
52125213
} catch (final Exception e) {
52135214
final String msg = "VM destroy failed due to " + e.toString();
52145215
s_logger.warn(msg, e);
@@ -5875,4 +5876,23 @@ private void umountNfs(Connection conn, String remoteDir, String localDir) {
58755876
s_logger.warn(errMsg);
58765877
}
58775878
}
5879+
5880+
public boolean isDestroyHaltedVms() {
5881+
ComparableVersion version = new ComparableVersion(getHost().getProductVersion());
5882+
if (version.compareTo(new ComparableVersion("8.0")) >= 0) {
5883+
return false;
5884+
}
5885+
return true;
5886+
}
5887+
5888+
public void destroyVm(VM vm, Connection connection, boolean forced) throws XenAPIException, XmlRpcException {
5889+
if (!isDestroyHaltedVms() && !forced) {
5890+
return;
5891+
}
5892+
vm.destroy(connection);
5893+
}
5894+
5895+
public void destroyVm(VM vm, Connection connection) throws XenAPIException, XmlRpcException {
5896+
destroyVm(vm, connection, false);
5897+
}
58785898
}

plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56FenceCommandWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public Answer execute(final FenceCommand command, final XenServer56Resource xenS
5656
for (final VM vm : vms) {
5757
s_logger.info("Fence command for VM " + command.getVmName());
5858
vm.powerStateReset(conn);
59-
vm.destroy(conn);
59+
xenServer56.destroyVm(vm, conn);
6060
}
6161
return new FenceAnswer(command);
6262
} catch (final XmlRpcException e) {

0 commit comments

Comments
 (0)