Skip to content

Commit 45c9742

Browse files
committed
Merge remote-tracking branch 'apache/main' into feature-ui-logs
2 parents 32ed16a + 98debd2 commit 45c9742

File tree

21 files changed

+228
-146
lines changed

21 files changed

+228
-146
lines changed

.github/workflows/stale.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,9 @@ jobs:
4141
days-before-pr-close: 240
4242
exempt-issue-labels: 'gsoc,good-first-issue,long-term-plan'
4343
exempt-pr-labels: 'status:ready-for-merge,status:needs-testing,status:on-hold'
44+
- uses: actions/stale@v10
45+
with:
46+
stale-issue-label: 'archive'
47+
days-before-stale: 240
48+
exempt-issue-labels: 'gsoc,good-first-issue,long-term-plan'
49+
days-before-close: -1

api/src/main/java/com/cloud/storage/VolumeApiService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ public interface VolumeApiService {
5656
Boolean.class,
5757
"use.https.to.upload",
5858
"true",
59-
"Determines the protocol (HTTPS or HTTP) ACS will use to generate links to upload ISOs, volumes, and templates. When set as 'true', ACS will use protocol HTTPS, otherwise, it will use protocol HTTP. Default value is 'true'.",
59+
"Controls whether upload links for ISOs, volumes, and templates use HTTPS (true, default) or HTTP (false). After changing this setting, the Secondary Storage VM (SSVM) must be recreated",
6060
true,
61-
ConfigKey.Scope.StoragePool);
61+
ConfigKey.Scope.Zone);
6262

6363
/**
6464
* Creates the database object for a volume based on the given criteria

core/src/main/java/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ public class TemplateOrVolumePostUploadCommand {
5757

5858
private String nfsVersion;
5959

60-
public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo,
61-
String dataToRole) {
60+
private long zoneId;
61+
62+
public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum,
63+
String type, String name, String imageFormat, String dataTo, String dataToRole, long zoneId) {
6264
this.entityId = entityId;
6365
this.entityUUID = entityUUID;
6466
this.absolutePath = absolutePath;
@@ -68,9 +70,7 @@ public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, Strin
6870
this.imageFormat = imageFormat;
6971
this.dataTo = dataTo;
7072
this.dataToRole = dataToRole;
71-
}
72-
73-
public TemplateOrVolumePostUploadCommand() {
73+
this.zoneId = zoneId;
7474
}
7575

7676
public String getRemoteEndPoint() {
@@ -216,4 +216,8 @@ public void setProcessTimeout(long processTimeout) {
216216
public long getProcessTimeout() {
217217
return processTimeout;
218218
}
219+
220+
public long getZoneId() {
221+
return zoneId;
222+
}
219223
}

developer/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
<plugin>
6767
<groupId>org.codehaus.mojo</groupId>
6868
<artifactId>properties-maven-plugin</artifactId>
69-
<version>1.0-alpha-2</version>
69+
<version>1.2.1</version>
7070
<executions>
7171
<execution>
7272
<phase>initialize</phase>

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,11 @@ public void start(final String vmUuid, final Map<VirtualMachineProfile.Param, Ob
935935
throw new CloudRuntimeException(String.format("Unable to start a VM [%s] due to [%s].", vmUuid, e.getMessage()), e).add(VirtualMachine.class, vmUuid);
936936
} catch (final ResourceUnavailableException e) {
937937
if (e.getScope() != null && e.getScope().equals(VirtualRouter.class)){
938-
throw new CloudRuntimeException("Network is unavailable. Please contact administrator", e).add(VirtualMachine.class, vmUuid);
938+
Account callingAccount = CallContext.current().getCallingAccount();
939+
String errorSuffix = (callingAccount != null && callingAccount.getType() == Account.Type.ADMIN) ?
940+
String.format("Failure: %s", e.getMessage()) :
941+
"Please contact administrator.";
942+
throw new CloudRuntimeException(String.format("The Network for VM %s is unavailable. %s", vmUuid, errorSuffix), e).add(VirtualMachine.class, vmUuid);
939943
}
940944
throw new CloudRuntimeException(String.format("Unable to start a VM [%s] due to [%s].", vmUuid, e.getMessage()), e).add(VirtualMachine.class, vmUuid);
941945
}

engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,8 @@ CALL `cloud`.`INSERT_EXTENSION_DETAIL_IF_NOT_EXISTS`('MaaS', 'orchestratorrequir
8787

8888
CALL `cloud`.`IDEMPOTENT_DROP_UNIQUE_KEY`('counter', 'uc_counter__provider__source__value');
8989
CALL `cloud`.`IDEMPOTENT_ADD_UNIQUE_KEY`('cloud.counter', 'uc_counter__provider__source__value__removed', '(provider, source, value, removed)');
90+
91+
-- Change scope for configuration - 'use.https.to.upload from' from StoragePool to Zone
92+
UPDATE `cloud`.`configuration` SET `scope` = 2 WHERE `name` = 'use.https.to.upload';
93+
-- Delete the configuration for 'use.https.to.upload' from StoragePool
94+
DELETE FROM `cloud`.`storage_pool_details` WHERE `name` = 'use.https.to.upload';

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

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

54+
import com.xensource.xenapi.VTPM;
5455
import org.apache.cloudstack.api.ApiConstants;
5556
import org.apache.cloudstack.diagnostics.CopyToSecondaryStorageAnswer;
5657
import org.apache.cloudstack.diagnostics.CopyToSecondaryStorageCommand;
@@ -5826,4 +5827,82 @@ public void destroyVm(VM vm, Connection connection, boolean forced) throws XenAP
58265827
public void destroyVm(VM vm, Connection connection) throws XenAPIException, XmlRpcException {
58275828
destroyVm(vm, connection, false);
58285829
}
5830+
5831+
/**
5832+
* Configure vTPM (Virtual Trusted Platform Module) support for a VM.
5833+
* vTPM provides a virtual TPM 2.0 device for VMs, enabling features like Secure Boot and disk encryption.
5834+
*
5835+
* Requirements:
5836+
* - XenServer/XCP-ng 8.3 (and above)
5837+
* - UEFI Secure Boot enabled
5838+
* - VM in halted state
5839+
*
5840+
* @param conn XenServer connection
5841+
* @param vm The VM to configure
5842+
* @param vmSpec VM specification containing vTPM settings
5843+
*/
5844+
public void configureVTPM(Connection conn, VM vm, VirtualMachineTO vmSpec) throws XenAPIException, XmlRpcException {
5845+
if (vmSpec == null || vmSpec.getDetails() == null) {
5846+
return;
5847+
}
5848+
5849+
String vtpmEnabled = vmSpec.getDetails().getOrDefault(VmDetailConstants.VIRTUAL_TPM_ENABLED, null);
5850+
5851+
final Map<String, String> platform = vm.getPlatform(conn);
5852+
if (platform != null) {
5853+
final String guestRequiresVtpm = platform.get("vtpm");
5854+
if (guestRequiresVtpm != null && Boolean.parseBoolean(guestRequiresVtpm) && !Boolean.parseBoolean(vtpmEnabled)) {
5855+
logger.warn("Guest OS requires vTPM by default, even if VM details doesn't have the setting: {}", vmSpec.getName());
5856+
return;
5857+
}
5858+
}
5859+
5860+
if (!Boolean.parseBoolean(vtpmEnabled)) {
5861+
return;
5862+
}
5863+
5864+
String bootMode = StringUtils.defaultIfEmpty(vmSpec.getDetails().get(ApiConstants.BootType.UEFI.toString()), null);
5865+
String bootType = (bootMode == null) ? ApiConstants.BootType.BIOS.toString() : ApiConstants.BootType.UEFI.toString();
5866+
5867+
if (!ApiConstants.BootType.UEFI.toString().equals(bootType)) {
5868+
logger.warn("vTPM requires UEFI boot mode. Skipping vTPM configuration for VM: {}", vmSpec.getName());
5869+
return;
5870+
}
5871+
5872+
try {
5873+
Set<VTPM> existingVtpms = vm.getVTPMs(conn);
5874+
if (!existingVtpms.isEmpty()) {
5875+
logger.debug("vTPM already exists for VM: {}", vmSpec.getName());
5876+
return;
5877+
}
5878+
5879+
// Creates vTPM using: xe vtpm-create vm-uuid=<uuid>
5880+
String vmUuid = vm.getUuid(conn);
5881+
String result = callHostPlugin(conn, "vmops", "create_vtpm", "vm_uuid", vmUuid);
5882+
5883+
if (result == null || result.isEmpty() || result.startsWith("ERROR:") || result.startsWith("EXCEPTION:")) {
5884+
throw new CloudRuntimeException("Failed to create vTPM, result: " + result);
5885+
}
5886+
5887+
logger.info("Successfully created vTPM {} for VM: {}", result.trim(), vmSpec.getName());
5888+
} catch (Exception e) {
5889+
logger.warn("Failed to configure vTPM for VM: {}, continuing without vTPM", vmSpec.getName(), e);
5890+
}
5891+
}
5892+
5893+
public boolean isVTPMSupported(Connection conn, Host host) {
5894+
try {
5895+
Host.Record hostRecord = host.getRecord(conn);
5896+
String productVersion = hostRecord.softwareVersion.get("product_version");
5897+
if (productVersion == null) {
5898+
return false;
5899+
}
5900+
ComparableVersion currentVersion = new ComparableVersion(productVersion);
5901+
ComparableVersion minVersion = new ComparableVersion("8.2.0");
5902+
return currentVersion.compareTo(minVersion) >= 0;
5903+
} catch (Exception e) {
5904+
logger.warn("Failed to check vTPM support on host", e);
5905+
return false;
5906+
}
5907+
}
58295908
}

plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,20 @@ public Answer execute(final ReadyCommand command, final CitrixResourceBase citri
6060
final Set<VM> vms = host.getResidentVMs(conn);
6161
citrixResourceBase.destroyPatchVbd(conn, vms);
6262

63+
} catch (final Exception e) {
64+
logger.warn("Unable to destroy CD-ROM device for system VMs", e);
65+
}
66+
67+
try {
68+
final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid());
6369
final Host.Record hr = host.getRecord(conn);
6470
if (isUefiSupported(CitrixHelper.getProductVersion(hr))) {
6571
hostDetails.put(com.cloud.host.Host.HOST_UEFI_ENABLE, Boolean.TRUE.toString());
6672
}
67-
} catch (final Exception e) {
73+
} catch (Exception e) {
74+
logger.warn("Unable to get UEFI support info", e);
6875
}
76+
6977
try {
7078
final boolean result = citrixResourceBase.cleanupHaltedVms(conn);
7179
if (!result) {

plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ public Answer execute(final StartCommand command, final CitrixResourceBase citri
9797
citrixResourceBase.createVGPU(conn, command, vm, gpuDevice);
9898
}
9999

100+
try {
101+
if (citrixResourceBase.isVTPMSupported(conn, host)) {
102+
citrixResourceBase.configureVTPM(conn, vm, vmSpec);
103+
}
104+
} catch (Exception e) {
105+
logger.warn("Failed to configure vTPM for VM " + vmName + ", continuing without vTPM", e);
106+
}
107+
100108
Host.Record record = host.getRecord(conn);
101109
String xenBrand = record.softwareVersion.get("product_brand");
102110
String xenVersion = record.softwareVersion.get("product_version");

plugins/maintenance/src/test/java/org/apache/cloudstack/maintenance/ManagementServerMaintenanceManagerImplTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,6 @@ public void prepareForMaintenanceAndCancelFromMaintenanceState() {
321321
spy.prepareForMaintenance("static", false);
322322
});
323323

324-
Mockito.when(msHost.getState()).thenReturn(ManagementServerHost.State.Maintenance);
325324
Mockito.doNothing().when(jobManagerMock).enableAsyncJobs();
326325
spy.cancelMaintenance();
327326
Mockito.verify(jobManagerMock).enableAsyncJobs();
@@ -339,7 +338,6 @@ public void prepareForMaintenanceAndCancelFromPreparingForMaintenanceState() {
339338
spy.prepareForMaintenance("static", false);
340339
});
341340

342-
Mockito.when(msHost.getState()).thenReturn(ManagementServerHost.State.PreparingForMaintenance);
343341
Mockito.doNothing().when(jobManagerMock).enableAsyncJobs();
344342
spy.cancelMaintenance();
345343
Mockito.verify(jobManagerMock).enableAsyncJobs();

0 commit comments

Comments
 (0)