Skip to content

Commit a432852

Browse files
committed
Merge branch 'main' into feature-kms
2 parents 294ca3b + a1959f2 commit a432852

330 files changed

Lines changed: 34117 additions & 352 deletions

File tree

Some content is hidden

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

agent/conf/agent.properties

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ zone=default
7878
# Generated with "uuidgen".
7979
local.storage.uuid=
8080

81+
# Enable TLS for image server transfers. The keys are read from:
82+
# cert file = /etc/cloudstack/agent/cloud.crt
83+
# key file = /etc/cloudstack/agent/cloud.key
84+
image.server.tls.enabled=true
85+
86+
# The Address for the network interface that the image server listens on. If not specified, it will listen on the Management network.
87+
#image.server.listen.address=
88+
8189
# Location for KVM virtual router scripts.
8290
# The path defined in this property is relative to the directory "/usr/share/cloudstack-common/".
8391
domr.scripts.dir=scripts/network/domr/kvm

agent/src/main/java/com/cloud/agent/properties/AgentProperties.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,20 @@ public class AgentProperties{
123123
*/
124124
public static final Property<String> LOCAL_STORAGE_PATH = new Property<>("local.storage.path", "/var/lib/libvirt/images/");
125125

126+
/**
127+
* Enables TLS on the KVM image server transfer endpoint.<br>
128+
* Data type: Boolean.<br>
129+
* Default value: <code>true</code>
130+
*/
131+
public static final Property<Boolean> IMAGE_SERVER_TLS_ENABLED = new Property<>("image.server.tls.enabled", true);
132+
133+
/**
134+
* The IP address that the KVM image server listens on.<br>
135+
* Data type: String.<br>
136+
* Default value: <code>null</code>
137+
*/
138+
public static final Property<String> IMAGE_SERVER_LISTEN_ADDRESS = new Property<>("image.server.listen.address", null, String.class);
139+
126140
/**
127141
* Directory where Qemu sockets are placed.<br>
128142
* These sockets are for the Qemu Guest Agent and SSVM provisioning.<br>

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.List;
2323
import java.util.Map;
2424

25+
import com.cloud.dc.DataCenter;
2526
import com.cloud.exception.ResourceAllocationException;
2627
import com.cloud.offering.DiskOffering;
2728
import com.cloud.user.Account;
@@ -70,6 +71,10 @@ public interface VolumeApiService {
7071
*/
7172
Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException;
7273

74+
Volume allocVolume(long ownerId, Long zoneId, Long diskOfferingId, Long vmId, Long snapshotId, String name,
75+
Long cmdSize, Boolean displayVolume, Long cmdMinIops, Long cmdMaxIops, String customId, Long kmsKeyId)
76+
throws ResourceAllocationException;
77+
7378
/**
7479
* Creates the volume based on the given criteria
7580
*
@@ -80,6 +85,8 @@ public interface VolumeApiService {
8085
*/
8186
Volume createVolume(CreateVolumeCmd cmd);
8287

88+
Volume createVolume(long volumeId, Long vmId, Long snapshotId, Long storageId, Boolean display);
89+
8390
/**
8491
* Resizes the volume based on the given criteria
8592
*
@@ -203,4 +210,6 @@ Volume updateVolume(long volumeId, String path, String state, Long storageId,
203210
Pair<String, String> checkAndRepairVolume(CheckAndRepairVolumeCmd cmd) throws ResourceAllocationException;
204211

205212
Long getVolumePhysicalSize(Storage.ImageFormat format, String path, String chainInfo);
213+
214+
Long getCustomDiskOfferingIdForVolumeUpload(Account owner, DataCenter zone, boolean encryptEnabledOnly);
206215
}

api/src/main/java/com/cloud/user/AccountService.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,16 @@ User createUser(String userName, String password, String firstName, String lastN
8888

8989
Account getActiveAccountById(long accountId);
9090

91+
Account getActiveAccountByUuid(String accountUuid);
92+
9193
Account getAccount(long accountId);
9294

95+
Account getAccountByUuid(String accountUuid);
96+
9397
User getActiveUser(long userId);
9498

99+
User getOneActiveUserForAccount(Account account);
100+
95101
User getUserIncludingRemoved(long userId);
96102

97103
boolean isRootAdmin(Long accountId);

api/src/main/java/com/cloud/vm/VmDetailConstants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,10 @@ public interface VmDetailConstants {
130130
String EXTERNAL_DETAIL_PREFIX = "External:";
131131
String CLOUDSTACK_VM_DETAILS = "cloudstack.vm.details";
132132
String CLOUDSTACK_VLAN = "cloudstack.vlan";
133+
134+
// KVM Checkpoints related
135+
String ACTIVE_CHECKPOINT_ID = "active.checkpoint.id";
136+
String ACTIVE_CHECKPOINT_CREATE_TIME = "active.checkpoint.create.time";
137+
String LAST_CHECKPOINT_ID = "last.checkpoint.id";
138+
String LAST_CHECKPOINT_CREATE_TIME = "last.checkpoint.create.time";
133139
}

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public class ApiConstants {
7979
public static final String BOOTABLE = "bootable";
8080
public static final String BIND_DN = "binddn";
8181
public static final String BIND_PASSWORD = "bindpass";
82+
public static final String BLANK_INSTANCE = "blankinstance";
8283
public static final String BUS_ADDRESS = "busaddress";
8384
public static final String BYTES_READ_RATE = "bytesreadrate";
8485
public static final String BYTES_READ_RATE_MAX = "bytesreadratemax";
@@ -221,6 +222,7 @@ public class ApiConstants {
221222
public static final String DOMAIN_PATH = "domainpath";
222223
public static final String DOMAIN_ID = "domainid";
223224
public static final String DOMAIN__ID = "domainId";
225+
public static final String DUMMY = "dummy";
224226
public static final String DURATION = "duration";
225227
public static final String ELIGIBLE = "eligible";
226228
public static final String EMAIL = "email";
@@ -264,6 +266,7 @@ public class ApiConstants {
264266
public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
265267
public static final String FOR_SYSTEM_VMS = "forsystemvms";
266268
public static final String FOR_PROVIDER = "forprovider";
269+
public static final String FROM_CHECKPOINT_ID = "fromcheckpointid";
267270
public static final String FULL_PATH = "fullpath";
268271
public static final String GATEWAY = "gateway";
269272
public static final String IP6_GATEWAY = "ip6gateway";
@@ -336,6 +339,7 @@ public class ApiConstants {
336339
public static final String IS_2FA_VERIFIED = "is2faverified";
337340

338341
public static final String IS_2FA_MANDATED = "is2famandated";
342+
public static final String IS_ACTIVE = "isactive";
339343
public static final String IS_ASYNC = "isasync";
340344
public static final String IP_AVAILABLE = "ipavailable";
341345
public static final String IP_LIMIT = "iplimit";
@@ -612,6 +616,7 @@ public class ApiConstants {
612616
public static final String TENANT_NAME = "tenantname";
613617
public static final String TOTAL = "total";
614618
public static final String TOTAL_SUBNETS = "totalsubnets";
619+
public static final String TO_CHECKPOINT_ID = "tocheckpointid";
615620
public static final String TOTAL_QUOTA = "totalquota";
616621
public static final String TYPE = "type";
617622
public static final String TRUST_STORE = "truststore";

api/src/main/java/org/apache/cloudstack/api/ApiServerService.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121

2222
import javax.servlet.http.HttpSession;
2323

24+
import org.apache.cloudstack.context.CallContext;
25+
2426
import com.cloud.domain.Domain;
2527
import com.cloud.exception.CloudAuthenticationException;
28+
import com.cloud.user.Account;
2629
import com.cloud.user.UserAccount;
2730

2831
public interface ApiServerService {
@@ -52,4 +55,20 @@ public ResponseObject loginUser(HttpSession session, String username, String pas
5255
String getDomainId(Map<String, Object[]> params);
5356

5457
boolean isPostRequestsAndTimestampsEnforced();
58+
59+
AsyncCmdResult processAsyncCmd(BaseAsyncCmd cmdObj, Map<String, String> params, CallContext ctx, Long callerUserId, Account caller) throws Exception;
60+
61+
class AsyncCmdResult {
62+
public final Long objectId;
63+
public final String objectUuid;
64+
public final BaseAsyncCmd asyncCmd;
65+
public final long jobId;
66+
67+
public AsyncCmdResult(Long objectId, String objectUuid, BaseAsyncCmd asyncCmd, long jobId) {
68+
this.objectId = objectId;
69+
this.objectUuid = objectUuid;
70+
this.asyncCmd = asyncCmd;
71+
this.jobId = jobId;
72+
}
73+
}
5574
}

api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public abstract class BaseAsyncCreateCustomIdCmd extends BaseAsyncCreateCmd {
2020
@Parameter(name = ApiConstants.CUSTOM_ID,
2121
type = CommandType.STRING,
2222
description = "An optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only")
23-
private String customId;
23+
protected String customId;
2424

2525
public String getCustomId() {
2626
return customId;
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//Licensed to the Apache Software Foundation (ASF) under one
2+
//or more contributor license agreements. See the NOTICE file
3+
//distributed with this work for additional information
4+
//regarding copyright ownership. The ASF licenses this file
5+
//to you under the Apache License, Version 2.0 (the
6+
//"License"); you may not use this file except in compliance
7+
//the License. You may obtain a copy of the License at
8+
//
9+
//http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
//Unless required by applicable law or agreed to in writing,
12+
//software distributed under the License is distributed on an
13+
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
//KIND, either express or implied. See the License for the
15+
//specific language governing permissions and limitations
16+
//under the License.
17+
18+
package org.apache.cloudstack.api.command.admin.backup;
19+
20+
import javax.inject.Inject;
21+
22+
import org.apache.cloudstack.acl.RoleType;
23+
import org.apache.cloudstack.api.APICommand;
24+
import org.apache.cloudstack.api.ApiConstants;
25+
import org.apache.cloudstack.api.BaseCmd;
26+
import org.apache.cloudstack.api.Parameter;
27+
import org.apache.cloudstack.api.command.admin.AdminCmd;
28+
import org.apache.cloudstack.api.response.BackupResponse;
29+
import org.apache.cloudstack.api.response.ImageTransferResponse;
30+
import org.apache.cloudstack.api.response.VolumeResponse;
31+
import org.apache.cloudstack.backup.ImageTransfer;
32+
import org.apache.cloudstack.backup.KVMBackupExportService;
33+
import org.apache.cloudstack.context.CallContext;
34+
35+
import com.cloud.utils.EnumUtils;
36+
37+
@APICommand(name = "createImageTransfer",
38+
description = "Create image transfer for a disk in backup. This API is intended for testing only and is disabled by default.",
39+
responseObject = ImageTransferResponse.class,
40+
since = "4.23.0",
41+
authorized = {RoleType.Admin})
42+
public class CreateImageTransferCmd extends BaseCmd implements AdminCmd {
43+
44+
@Inject
45+
private KVMBackupExportService kvmBackupExportService;
46+
47+
@Parameter(name = ApiConstants.BACKUP_ID,
48+
type = CommandType.UUID,
49+
entityType = BackupResponse.class,
50+
description = "ID of the backup")
51+
private Long backupId;
52+
53+
@Parameter(name = ApiConstants.VOLUME_ID,
54+
type = CommandType.UUID,
55+
entityType = VolumeResponse.class,
56+
required = true,
57+
description = "ID of the disk/volume")
58+
private Long volumeId;
59+
60+
@Parameter(name = ApiConstants.DIRECTION,
61+
type = CommandType.STRING,
62+
required = true,
63+
description = "Direction of the transfer: upload, download")
64+
private String direction;
65+
66+
@Parameter(name = ApiConstants.FORMAT,
67+
type = CommandType.STRING,
68+
description = "Format for the image transfer: raw/cow. 'raw' will create an NBD backend. 'cow' will use the File backend." +
69+
"For download, only the 'raw' format is supported. Default: raw")
70+
private String format;
71+
72+
public Long getBackupId() {
73+
return backupId;
74+
}
75+
76+
public Long getVolumeId() {
77+
return volumeId;
78+
}
79+
80+
public ImageTransfer.Direction getDirection() {
81+
return ImageTransfer.Direction.valueOf(direction);
82+
}
83+
84+
public ImageTransfer.Format getFormat() {
85+
return EnumUtils.getEnum(ImageTransfer.Format.class, format);
86+
}
87+
88+
@Override
89+
public void execute() {
90+
ImageTransferResponse response = kvmBackupExportService.createImageTransfer(this);
91+
response.setObjectName(ImageTransfer.class.getSimpleName().toLowerCase());
92+
response.setResponseName(getCommandName());
93+
setResponseObject(response);
94+
}
95+
96+
@Override
97+
public long getEntityOwnerId() {
98+
return CallContext.current().getCallingAccount().getId();
99+
}
100+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//Licensed to the Apache Software Foundation (ASF) under one
2+
//or more contributor license agreements. See the NOTICE file
3+
//distributed with this work for additional information
4+
//regarding copyright ownership. The ASF licenses this file
5+
//to you under the Apache License, Version 2.0 (the
6+
//"License"); you may not use this file except in compliance
7+
//the License. You may obtain a copy of the License at
8+
//
9+
//http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
//Unless required by applicable law or agreed to in writing,
12+
//software distributed under the License is distributed on an
13+
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
//KIND, either express or implied. See the License for the
15+
//specific language governing permissions and limitations
16+
//under the License.
17+
18+
package org.apache.cloudstack.api.command.admin.backup;
19+
20+
import javax.inject.Inject;
21+
22+
import org.apache.cloudstack.acl.RoleType;
23+
import org.apache.cloudstack.api.APICommand;
24+
import org.apache.cloudstack.api.ApiConstants;
25+
import org.apache.cloudstack.api.BaseCmd;
26+
import org.apache.cloudstack.api.Parameter;
27+
import org.apache.cloudstack.api.command.admin.AdminCmd;
28+
import org.apache.cloudstack.api.response.SuccessResponse;
29+
import org.apache.cloudstack.api.response.UserVmResponse;
30+
import org.apache.cloudstack.backup.KVMBackupExportService;
31+
import org.apache.cloudstack.context.CallContext;
32+
33+
@APICommand(name = "deleteVirtualMachineCheckpoint",
34+
description = "Delete a VM checkpoint. This API is intended for testing only and is disabled by default.",
35+
responseObject = SuccessResponse.class,
36+
since = "4.23.0",
37+
authorized = {RoleType.Admin})
38+
public class DeleteVmCheckpointCmd extends BaseCmd implements AdminCmd {
39+
40+
@Inject
41+
private KVMBackupExportService kvmBackupExportService;
42+
43+
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
44+
type = CommandType.UUID,
45+
entityType = UserVmResponse.class,
46+
required = true,
47+
description = "ID of the VM")
48+
private Long vmId;
49+
50+
@Parameter(name = "checkpointid",
51+
type = CommandType.STRING,
52+
required = true,
53+
description = "Checkpoint ID")
54+
private String checkpointId;
55+
56+
public Long getVmId() {
57+
return vmId;
58+
}
59+
60+
public String getCheckpointId() {
61+
return checkpointId;
62+
}
63+
64+
public void setVmId(Long vmId) {
65+
this.vmId = vmId;
66+
}
67+
68+
public void setCheckpointId(String checkpointId) {
69+
this.checkpointId = checkpointId;
70+
}
71+
72+
@Override
73+
public void execute() {
74+
boolean result = kvmBackupExportService.deleteVmCheckpoint(this);
75+
SuccessResponse response = new SuccessResponse(getCommandName());
76+
response.setSuccess(result);
77+
response.setResponseName(getCommandName());
78+
setResponseObject(response);
79+
}
80+
81+
@Override
82+
public long getEntityOwnerId() {
83+
return CallContext.current().getCallingAccount().getId();
84+
}
85+
}

0 commit comments

Comments
 (0)