Skip to content

Commit 5525242

Browse files
committed
changes for download via ssvm/secondary store
Signed-off-by: Abhishek Kumar <[email protected]>
1 parent f923de8 commit 5525242

File tree

14 files changed

+585
-61
lines changed

14 files changed

+585
-61
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ private boolean copyBytes(File file, InputStream in, RandomAccessFile out) throw
259259
break;
260260
}
261261
offset = writeBlock(bytesRead, out, buffer, offset);
262-
if (!ResourceType.SNAPSHOT.equals(resourceType)
262+
if (resourceType.shouldVerifyFormat()
263263
&& !verifyFormat.isVerifiedFormat()
264264
&& (offset >= MIN_FORMAT_VERIFICATION_SIZE || offset >= remoteSize)) {
265265
verifyFormat.invoke();

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.apache.cloudstack.storage.command;
2121

2222
import org.apache.cloudstack.api.InternalIdentity;
23+
import org.apache.cloudstack.storage.to.DownloadableArchiveObjectTO;
2324
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
2425
import org.apache.cloudstack.storage.to.TemplateObjectTO;
2526
import org.apache.cloudstack.storage.to.VolumeObjectTO;
@@ -34,7 +35,26 @@
3435
public class DownloadCommand extends AbstractDownloadCommand implements InternalIdentity {
3536

3637
public static enum ResourceType {
37-
VOLUME, TEMPLATE, SNAPSHOT
38+
VOLUME(true, true),
39+
TEMPLATE(true, true),
40+
SNAPSHOT(false, false),
41+
ARCHIVE(false, false);
42+
43+
private final boolean requiresPostDownloadProcessing;
44+
private final boolean verifyFormat;
45+
46+
ResourceType(boolean requiresPostDownloadProcessing, boolean verifyFormat) {
47+
this.requiresPostDownloadProcessing = requiresPostDownloadProcessing;
48+
this.verifyFormat = verifyFormat;
49+
}
50+
51+
public boolean doesRequirePostDownloadProcessing() {
52+
return requiresPostDownloadProcessing;
53+
}
54+
55+
public boolean shouldVerifyFormat() {
56+
return verifyFormat;
57+
}
3858
}
3959

4060
private boolean hvm;
@@ -114,6 +134,19 @@ public DownloadCommand(SnapshotObjectTO snapshot, Long maxDownloadSizeInBytes, S
114134
this.resourceType = ResourceType.SNAPSHOT;
115135
}
116136

137+
public DownloadCommand(DownloadableArchiveObjectTO archive, Long maxDownloadSizeInBytes, String url) {
138+
super(archive.getName(), url, archive.getFormat(), archive.getAccountId());
139+
_store = archive.getDataStore();
140+
installPath = archive.getPath();
141+
id = archive.getId();
142+
checksum = archive.getChecksum();
143+
if (_store instanceof NfsTO) {
144+
setSecUrl(((NfsTO)_store).getUrl());
145+
}
146+
this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
147+
this.resourceType = ResourceType.ARCHIVE;
148+
}
149+
117150
@Override
118151
public long getId() {
119152
return id;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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+
// with 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.storage.to;
19+
20+
import com.cloud.agent.api.to.DataObjectType;
21+
import com.cloud.agent.api.to.DataStoreTO;
22+
import com.cloud.agent.api.to.DataTO;
23+
import com.cloud.hypervisor.Hypervisor;
24+
import com.cloud.storage.Storage;
25+
26+
public class DownloadableArchiveObjectTO extends DownloadableObjectTO implements DataTO {
27+
private final DataStoreTO dataStore;
28+
private final String name;
29+
private final String checksum;
30+
private String path;
31+
private long accountId = 0L;
32+
private Storage.ImageFormat format = Storage.ImageFormat.ZIP;
33+
34+
public DownloadableArchiveObjectTO(DataStoreTO store, String name, String checksum, String path) {
35+
this.dataStore = store;
36+
this.name = name;
37+
this.checksum = checksum;
38+
this.path = path;
39+
}
40+
41+
@Override
42+
public DataStoreTO getDataStore() {
43+
return this.dataStore;
44+
}
45+
46+
@Override
47+
public long getId() {
48+
return 0;
49+
}
50+
51+
@Override
52+
public Hypervisor.HypervisorType getHypervisorType() {
53+
return null;
54+
}
55+
56+
@Override
57+
public DataObjectType getObjectType() {
58+
return DataObjectType.ARCHIVE;
59+
}
60+
61+
public long getAccountId() {
62+
return accountId;
63+
}
64+
65+
public String getName() {
66+
return name;
67+
}
68+
69+
public String getChecksum() {
70+
return checksum;
71+
}
72+
73+
@Override
74+
public String getPath() {
75+
return path;
76+
}
77+
78+
public void setPath(String path) {
79+
this.path = path;
80+
}
81+
82+
public void setAccountId(long accountId) {
83+
this.accountId = accountId;
84+
}
85+
86+
public Storage.ImageFormat getFormat() {
87+
return format;
88+
}
89+
90+
public void setFormat(Storage.ImageFormat format) {
91+
this.format = format;
92+
}
93+
94+
@Override
95+
public String toString() {
96+
return new StringBuilder("DownloadableArchiveObjectTO[datastore=").append(dataStore).append("|path").append(path).append("]").toString();
97+
}
98+
}

engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
5353
import org.apache.cloudstack.storage.endpoint.DefaultEndPointSelector;
5454
import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper;
55-
import org.apache.logging.log4j.Logger;
5655
import org.apache.logging.log4j.LogManager;
56+
import org.apache.logging.log4j.Logger;
5757

5858
import com.cloud.agent.AgentManager;
5959
import com.cloud.agent.api.Answer;
@@ -192,6 +192,12 @@ public void createAsync(DataStore dataStore, DataObject data, AsyncCompletionCal
192192
logger.debug("Downloading snapshot to data store {}", dataStore);
193193
}
194194
_downloadMonitor.downloadSnapshotToStorage(data, caller);
195+
} else if (data.getType() == DataObjectType.ARCHIVE) {
196+
caller.setCallback(caller.getTarget().createArchiveAsyncCallback(null, null));
197+
if (logger.isDebugEnabled()) {
198+
logger.debug("Downloading archive to data store {}", dataStore);
199+
}
200+
_downloadMonitor.downloadArchiveToStorage(data, caller);
195201
}
196202
}
197203

@@ -360,6 +366,33 @@ protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher<? extends Bas
360366
return null;
361367
}
362368

369+
protected Void createArchiveAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, CreateContext<CreateCmdResult> context) {
370+
DownloadAnswer answer = callback.getResult();
371+
DataObject obj = context.data;
372+
DataStore store = obj.getDataStore();
373+
AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
374+
if (List.of(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR,
375+
VMTemplateStorageResourceAssoc.Status.ABANDONED,
376+
VMTemplateStorageResourceAssoc.Status.UNKNOWN).contains(answer.getDownloadStatus())) {
377+
CreateCmdResult result = new CreateCmdResult(null, null);
378+
result.setSuccess(false);
379+
result.setResult(answer.getErrorString());
380+
caller.complete(result);
381+
String msg = "Failed to download archive: " + obj.getName() + " with error: " + answer.getErrorString();
382+
Long zoneId = dataStoreManager.getStoreZoneId(store.getId(), store.getRole());
383+
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED,
384+
zoneId, null, msg, msg);
385+
logger.error(msg);
386+
} else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
387+
if (answer.getTemplatePhySicalSize() == 0) {
388+
return null;
389+
}
390+
CreateCmdResult result = new CreateCmdResult(answer.getInstallPath(), answer);
391+
caller.complete(result);
392+
}
393+
return null;
394+
}
395+
363396
@Override
364397
public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
365398
CommandResult result = new CommandResult();
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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+
// with 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.framework.extensions;
19+
20+
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
21+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
22+
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
23+
import org.apache.cloudstack.extension.Extension;
24+
import org.apache.cloudstack.storage.to.DownloadableArchiveObjectTO;
25+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
26+
27+
import com.cloud.agent.api.Answer;
28+
import com.cloud.agent.api.to.DataObjectType;
29+
import com.cloud.agent.api.to.DataTO;
30+
31+
public class ExtensionArchiveDataObject implements DataObject {
32+
private final Extension extension;
33+
private final DataStore dataStore;
34+
private final String uri;
35+
private final long size;
36+
37+
private final DownloadableArchiveObjectTO dataTO;
38+
39+
public ExtensionArchiveDataObject(Extension extension, DataStore dataStore, String uri, long size, String checksum,
40+
String path) {
41+
this.extension = extension;
42+
this.dataStore = dataStore;
43+
this.uri = uri;
44+
this.size = size;
45+
this.dataTO = new DownloadableArchiveObjectTO(dataStore.getTO(), extension.getName(), checksum, path);
46+
}
47+
48+
@Override
49+
public String toString() {
50+
return String.format("ExtensionArchiveDataObject %s",
51+
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
52+
this, "dataTO", "dataStore"));
53+
}
54+
55+
@Override
56+
public long getId() {
57+
return 0;
58+
}
59+
60+
@Override
61+
public String getUri() {
62+
return uri;
63+
}
64+
65+
@Override
66+
public DataTO getTO() {
67+
return dataTO;
68+
}
69+
70+
@Override
71+
public DataStore getDataStore() {
72+
return dataStore;
73+
}
74+
75+
@Override
76+
public Long getSize() {
77+
return size;
78+
}
79+
80+
@Override
81+
public long getPhysicalSize() {
82+
return size;
83+
}
84+
85+
@Override
86+
public DataObjectType getType() {
87+
return DataObjectType.ARCHIVE;
88+
}
89+
90+
@Override
91+
public String getUuid() {
92+
return null;
93+
}
94+
95+
@Override
96+
public boolean delete() {
97+
return false;
98+
}
99+
100+
@Override
101+
public void processEvent(ObjectInDataStoreStateMachine.Event event) {
102+
}
103+
104+
@Override
105+
public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
106+
}
107+
108+
@Override
109+
public void incRefCount() {
110+
}
111+
112+
@Override
113+
public void decRefCount() {
114+
}
115+
116+
@Override
117+
public Long getRefCount() {
118+
return null;
119+
}
120+
121+
@Override
122+
public String getName() {
123+
return extension.getName();
124+
}
125+
126+
public void setPath(String path) {
127+
dataTO.setPath(path);
128+
}
129+
}

0 commit comments

Comments
 (0)