Skip to content

Commit 732ef96

Browse files
authored
Merge branch '4.20' into ghi9800-updateVrOnSettingChange
2 parents bd5d2f2 + 823080c commit 732ef96

File tree

130 files changed

+9660
-1104
lines changed

Some content is hidden

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

130 files changed

+9660
-1104
lines changed

.github/workflows/main-sonar-check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
uses: actions/cache@v4
5555
with:
5656
path: ~/.m2/repository
57-
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
57+
key: ${{ runner.os }}-m2-${{ hashFiles('pom.xml', '*/pom.xml', '*/*/pom.xml', '*/*/*/pom.xml') }}
5858
restore-keys: |
5959
${{ runner.os }}-m2
6060

.github/workflows/sonar-check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
uses: actions/cache@v4
5757
with:
5858
path: ~/.m2/repository
59-
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
59+
key: ${{ runner.os }}-m2-${{ hashFiles('pom.xml', '*/pom.xml', '*/*/pom.xml', '*/*/*/pom.xml') }}
6060
restore-keys: |
6161
${{ runner.os }}-m2
6262

api/src/main/java/com/cloud/kubernetes/cluster/KubernetesServiceHelper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.apache.cloudstack.acl.ControlledEntity;
2020

21+
import com.cloud.user.Account;
2122
import com.cloud.uservm.UserVm;
2223
import com.cloud.utils.component.Adapter;
2324

@@ -26,4 +27,5 @@ public interface KubernetesServiceHelper extends Adapter {
2627
ControlledEntity findByUuid(String uuid);
2728
ControlledEntity findByVmId(long vmId);
2829
void checkVmCanBeDestroyed(UserVm userVm);
30+
void cleanupForAccount(Account account);
2931
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public static Type getFromValue(Integer type){
7171
}
7272

7373
public static final long ACCOUNT_ID_SYSTEM = 1;
74+
public static final long ACCOUNT_ID_ADMIN = 2;
7475

7576
public String getAccountName();
7677

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ public class ApiConstants {
448448
public static final String SENT = "sent";
449449
public static final String SENT_BYTES = "sentbytes";
450450
public static final String SERIAL = "serial";
451+
public static final String SERVICE_IP = "serviceip";
451452
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
452453
public static final String SESSIONKEY = "sessionkey";
453454
public static final String SHOW_CAPACITIES = "showcapacities";

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ public class ManagementServerResponse extends BaseResponse {
7474
@Param(description = "the running OS kernel version for this Management Server")
7575
private String kernelVersion;
7676

77+
@Deprecated
78+
@SerializedName(ApiConstants.SERVICE_IP)
79+
@Param(description = "the IP Address for this Management Server. This is deprecated, please use 'ipaddress' instead.")
80+
private String serviceIp;
81+
7782
@SerializedName(ApiConstants.IP_ADDRESS)
7883
@Param(description = "the IP Address for this Management Server")
7984
private String ipAddress;
@@ -122,6 +127,10 @@ public Date getLastBoot() {
122127
return lastBoot;
123128
}
124129

130+
public String getServiceIp() {
131+
return serviceIp;
132+
}
133+
125134
public String getIpAddress() {
126135
return ipAddress;
127136
}
@@ -170,6 +179,10 @@ public void setKernelVersion(String kernelVersion) {
170179
this.kernelVersion = kernelVersion;
171180
}
172181

182+
public void setServiceIp(String serviceIp) {
183+
this.serviceIp = serviceIp;
184+
}
185+
173186
public void setIpAddress(String ipAddress) {
174187
this.ipAddress = ipAddress;
175188
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ public class UnmanagedInstanceResponse extends BaseResponse {
7979
@Param(description = "the operating system of the virtual machine")
8080
private String operatingSystem;
8181

82+
@SerializedName(ApiConstants.BOOT_MODE)
83+
@Param(description = "indicates the boot mode")
84+
private String bootMode;
85+
86+
@SerializedName(ApiConstants.BOOT_TYPE)
87+
@Param(description = "indicates the boot type")
88+
private String bootType;
89+
8290
@SerializedName(ApiConstants.DISK)
8391
@Param(description = "the list of disks associated with the virtual machine", responseObject = UnmanagedInstanceDiskResponse.class)
8492
private Set<UnmanagedInstanceDiskResponse> disks;
@@ -211,4 +219,20 @@ public void setNics(Set<NicResponse> nics) {
211219
public void addNic(NicResponse nic) {
212220
this.nics.add(nic);
213221
}
222+
223+
public String getBootMode() {
224+
return bootMode;
225+
}
226+
227+
public void setBootMode(String bootMode) {
228+
this.bootMode = bootMode;
229+
}
230+
231+
public String getBootType() {
232+
return bootType;
233+
}
234+
235+
public void setBootType(String bootType) {
236+
this.bootType = bootType;
237+
}
214238
}

api/src/main/java/org/apache/cloudstack/vm/UnmanagedInstanceTO.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ public enum PowerState {
6161

6262
private String vncPassword;
6363

64+
private String bootType;
65+
private String bootMode;
66+
6467
public String getName() {
6568
return name;
6669
}
@@ -196,6 +199,22 @@ public String toString() {
196199
this, "name", "internalCSName", "hostName", "clusterName"));
197200
}
198201

202+
public String getBootType() {
203+
return bootType;
204+
}
205+
206+
public void setBootType(String bootType) {
207+
this.bootType = bootType;
208+
}
209+
210+
public String getBootMode() {
211+
return bootMode;
212+
}
213+
214+
public void setBootMode(String bootMode) {
215+
this.bootMode = bootMode;
216+
}
217+
199218
public static class Disk {
200219
private String diskId;
201220

core/src/main/java/com/cloud/agent/api/GetVmIpAddressCommand.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ public class GetVmIpAddressCommand extends Command {
2424
String vmName;
2525
String vmNetworkCidr;
2626
boolean windows = false;
27+
String macAddress;
2728

28-
public GetVmIpAddressCommand(String vmName, String vmNetworkCidr, boolean windows) {
29+
public GetVmIpAddressCommand(String vmName, String vmNetworkCidr, boolean windows, String macAddress) {
2930
this.vmName = vmName;
3031
this.windows = windows;
3132
this.vmNetworkCidr = vmNetworkCidr;
33+
this.macAddress = macAddress;
3234
}
3335

3436
@Override
@@ -47,4 +49,8 @@ public boolean isWindows(){
4749
public String getVmNetworkCidr() {
4850
return vmNetworkCidr;
4951
}
52+
53+
public String getMacAddress() {
54+
return macAddress;
55+
}
5056
}

core/src/main/java/com/cloud/storage/template/HttpTemplateDownloader.java

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.io.RandomAccessFile;
2828
import java.net.URI;
2929
import java.net.URISyntaxException;
30+
import java.util.Arrays;
3031
import java.util.Date;
3132
import java.util.List;
3233

@@ -80,6 +81,18 @@ public class HttpTemplateDownloader extends ManagedContextRunnable implements Te
8081
private ResourceType resourceType = ResourceType.TEMPLATE;
8182
private final HttpMethodRetryHandler myretryhandler;
8283
private boolean followRedirects = false;
84+
private boolean isChunkedTransfer;
85+
86+
protected static final List<String> CUSTOM_HEADERS_FOR_CHUNKED_TRANSFER_SIZE = Arrays.asList(
87+
"x-goog-stored-content-length",
88+
"x-goog-meta-size",
89+
"x-amz-meta-size",
90+
"x-amz-meta-content-length",
91+
"x-object-meta-size",
92+
"x-original-content-length",
93+
"x-oss-meta-content-length",
94+
"x-file-size");
95+
private static final long MIN_FORMAT_VERIFICATION_SIZE = 1024 * 1024;
8396

8497
public HttpTemplateDownloader(StorageLayer storageLayer, String downloadUrl, String toDir, DownloadCompleteCallback callback, long maxTemplateSizeInBytes,
8598
String user, String password, Proxy proxy, ResourceType resourceType) {
@@ -205,13 +218,11 @@ public long download(boolean resume, DownloadCompleteCallback callback) {
205218
RandomAccessFile out = new RandomAccessFile(file, "rw");
206219
) {
207220
out.seek(localFileSize);
208-
209-
logger.info("Starting download from " + downloadUrl + " to " + toFile + " remoteSize=" + toHumanReadableSize(remoteSize) + " , max size=" + toHumanReadableSize(maxTemplateSizeInBytes));
210-
211-
if (copyBytes(file, in, out)) return 0;
212-
221+
logger.info("Starting download from {} to {} remoteSize={} , max size={}",downloadUrl, toFile,
222+
toHumanReadableSize(remoteSize), toHumanReadableSize(maxTemplateSizeInBytes));
223+
boolean eof = copyBytes(file, in, out);
213224
Date finish = new Date();
214-
checkDowloadCompletion();
225+
checkDownloadCompletion(eof);
215226
downloadTime += finish.getTime() - start.getTime();
216227
} finally { /* in.close() and out.close() */ }
217228
return totalBytes;
@@ -237,28 +248,32 @@ public long download(boolean resume, DownloadCompleteCallback callback) {
237248
}
238249

239250
private boolean copyBytes(File file, InputStream in, RandomAccessFile out) throws IOException {
240-
int bytes;
241-
byte[] block = new byte[CHUNK_SIZE];
251+
byte[] buffer = new byte[CHUNK_SIZE];
242252
long offset = 0;
243-
boolean done = false;
244253
VerifyFormat verifyFormat = new VerifyFormat(file);
245254
status = Status.IN_PROGRESS;
246-
while (!done && status != Status.ABORTED && offset <= remoteSize) {
247-
if ((bytes = in.read(block, 0, CHUNK_SIZE)) > -1) {
248-
offset = writeBlock(bytes, out, block, offset);
249-
if (!ResourceType.SNAPSHOT.equals(resourceType) &&
250-
!verifyFormat.isVerifiedFormat() &&
251-
(offset >= 1048576 || offset >= remoteSize)) { //let's check format after we get 1MB or full file
252-
verifyFormat.invoke();
253-
}
254-
} else {
255-
done = true;
255+
while (status != Status.ABORTED) {
256+
int bytesRead = in.read(buffer, 0, CHUNK_SIZE);
257+
if (bytesRead == -1) {
258+
logger.debug("Reached EOF on input stream");
259+
break;
260+
}
261+
offset = writeBlock(bytesRead, out, buffer, offset);
262+
if (!ResourceType.SNAPSHOT.equals(resourceType)
263+
&& !verifyFormat.isVerifiedFormat()
264+
&& (offset >= MIN_FORMAT_VERIFICATION_SIZE || offset >= remoteSize)) {
265+
verifyFormat.invoke();
266+
}
267+
if (offset >= remoteSize) {
268+
logger.debug("Reached expected remote size limit: {} bytes", remoteSize);
269+
break;
256270
}
257271
}
258272
out.getFD().sync();
259-
return false;
273+
return !Status.ABORTED.equals(status);
260274
}
261275

276+
262277
private long writeBlock(int bytes, RandomAccessFile out, byte[] block, long offset) throws IOException {
263278
out.write(block, 0, bytes);
264279
offset += bytes;
@@ -267,11 +282,13 @@ private long writeBlock(int bytes, RandomAccessFile out, byte[] block, long offs
267282
return offset;
268283
}
269284

270-
private void checkDowloadCompletion() {
285+
private void checkDownloadCompletion(boolean eof) {
271286
String downloaded = "(incomplete download)";
272-
if (totalBytes >= remoteSize) {
287+
if (eof && ((totalBytes >= remoteSize) || (isChunkedTransfer && remoteSize == maxTemplateSizeInBytes))) {
273288
status = Status.DOWNLOAD_FINISHED;
274-
downloaded = "(download complete remote=" + toHumanReadableSize(remoteSize) + " bytes)";
289+
downloaded = "(download complete remote=" +
290+
(remoteSize == maxTemplateSizeInBytes ? toHumanReadableSize(remoteSize) : "unknown") +
291+
" bytes)";
275292
}
276293
errorString = "Downloaded " + toHumanReadableSize(totalBytes) + " bytes " + downloaded;
277294
}
@@ -293,18 +310,42 @@ private void checkAndSetDownloadSize() {
293310
}
294311
}
295312

313+
protected long getRemoteSizeForChunkedTransfer() {
314+
for (String headerKey : CUSTOM_HEADERS_FOR_CHUNKED_TRANSFER_SIZE) {
315+
Header header = request.getResponseHeader(headerKey);
316+
if (header == null) {
317+
continue;
318+
}
319+
try {
320+
return Long.parseLong(header.getValue());
321+
} catch (NumberFormatException ignored) {}
322+
}
323+
Header contentRangeHeader = request.getResponseHeader("Content-Range");
324+
if (contentRangeHeader != null) {
325+
String contentRange = contentRangeHeader.getValue();
326+
if (contentRange != null && contentRange.contains("/")) {
327+
String totalSize = contentRange.substring(contentRange.indexOf('/') + 1).trim();
328+
return Long.parseLong(totalSize);
329+
}
330+
}
331+
return 0;
332+
}
333+
296334
private boolean tryAndGetRemoteSize() {
297335
Header contentLengthHeader = request.getResponseHeader("content-length");
298-
boolean chunked = false;
336+
isChunkedTransfer = false;
299337
long reportedRemoteSize = 0;
300338
if (contentLengthHeader == null) {
301339
Header chunkedHeader = request.getResponseHeader("Transfer-Encoding");
302-
if (chunkedHeader == null || !"chunked".equalsIgnoreCase(chunkedHeader.getValue())) {
340+
if (chunkedHeader != null && "chunked".equalsIgnoreCase(chunkedHeader.getValue())) {
341+
isChunkedTransfer = true;
342+
reportedRemoteSize = getRemoteSizeForChunkedTransfer();
343+
logger.debug("{} is using chunked transfer encoding, possible remote size: {}", downloadUrl,
344+
reportedRemoteSize);
345+
} else {
303346
status = Status.UNRECOVERABLE_ERROR;
304347
errorString = " Failed to receive length of download ";
305348
return false;
306-
} else if ("chunked".equalsIgnoreCase(chunkedHeader.getValue())) {
307-
chunked = true;
308349
}
309350
} else {
310351
reportedRemoteSize = Long.parseLong(contentLengthHeader.getValue());
@@ -316,9 +357,11 @@ private boolean tryAndGetRemoteSize() {
316357
return false;
317358
}
318359
}
319-
320360
if (remoteSize == 0) {
321361
remoteSize = reportedRemoteSize;
362+
if (remoteSize != 0) {
363+
logger.debug("Remote size for {} found to be {}", downloadUrl, toHumanReadableSize(remoteSize));
364+
}
322365
}
323366
return true;
324367
}

0 commit comments

Comments
 (0)