Skip to content

Commit 2315a73

Browse files
User friendly name of Downloaded Templates Volumes and ISOs (apache#9252)
1 parent 7a0cd55 commit 2315a73

File tree

6 files changed

+65
-23
lines changed

6 files changed

+65
-23
lines changed

core/src/main/java/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java

+18-9
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,28 @@
2323

2424
public class CreateEntityDownloadURLCommand extends AbstractDownloadCommand {
2525

26-
public CreateEntityDownloadURLCommand(String parent, String installPath, String uuid, DataTO data) { // this constructor is for creating template download url
26+
public CreateEntityDownloadURLCommand(String parent, String installPath, String fileName, String filePath, DataTO data) { // this constructor is for creating template download url
2727
super();
2828
this.parent = parent; // parent is required as not the template can be child of one of many parents
2929
this.installPath = installPath;
30-
this.extractLinkUUID = uuid;
30+
this.filenameInExtractURL = fileName;
31+
this.filepathInExtractURL = filePath;
3132
this.data = data;
3233
}
3334

34-
public CreateEntityDownloadURLCommand(String installPath, String uuid) {
35+
public CreateEntityDownloadURLCommand(String installPath, String filename) {
3536
super();
3637
this.installPath = installPath;
37-
this.extractLinkUUID = uuid;
38+
this.filenameInExtractURL = filename;
3839
}
3940

4041
public CreateEntityDownloadURLCommand() {
4142
}
4243

4344
private String installPath;
4445
private String parent;
45-
private String extractLinkUUID;
46+
private String filenameInExtractURL;
47+
private String filepathInExtractURL;
4648

4749
public DataTO getData() {
4850
return data;
@@ -75,12 +77,19 @@ public void setParent(String parent) {
7577
this.parent = parent;
7678
}
7779

78-
public String getExtractLinkUUID() {
79-
return extractLinkUUID;
80+
public String getFilenameInExtractURL() {
81+
return filenameInExtractURL;
8082
}
8183

82-
public void setExtractLinkUUID(String extractLinkUUID) {
83-
this.extractLinkUUID = extractLinkUUID;
84+
public void setFilenameInExtractURL(String filenameInExtractURL) {
85+
this.filenameInExtractURL = filenameInExtractURL;
8486
}
8587

88+
public String getFilepathInExtractURL() {
89+
return filepathInExtractURL;
90+
}
91+
92+
public void setFilepathInExtractURL(String filepathInExtractURL) {
93+
this.filepathInExtractURL = filepathInExtractURL;
94+
}
8695
}

engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java

+2
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,6 @@ public interface DataObject {
5050
void decRefCount();
5151

5252
Long getRefCount();
53+
54+
String getName();
5355
}

plugins/storage/image/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java

+34-10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
2626
import com.cloud.host.dao.HostDao;
2727
import com.cloud.storage.Upload;
28+
import com.cloud.utils.StringUtils;
2829
import org.apache.log4j.Logger;
2930

3031
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
@@ -64,20 +65,43 @@ public DataStoreTO getStoreTO(DataStore store) {
6465
return nfsTO;
6566
}
6667

68+
private String createObjectNameForExtractUrl(String installPath, ImageFormat format, DataObject dataObject) {
69+
String objectNameInUrl = dataObject.getName();
70+
try {
71+
objectNameInUrl = cleanObjectName(objectNameInUrl);
72+
} catch (Exception e) {
73+
objectNameInUrl = UUID.randomUUID().toString();
74+
}
75+
76+
if (format != null) {
77+
objectNameInUrl = objectNameInUrl + "." + format.getFileExtension();
78+
} else if (installPath.lastIndexOf(".") != -1) {
79+
objectNameInUrl = objectNameInUrl + "." + installPath.substring(installPath.lastIndexOf(".") + 1);
80+
}
81+
82+
return objectNameInUrl;
83+
}
84+
85+
private String cleanObjectName(String objectName) {
86+
if (StringUtils.isEmpty(objectName)) {
87+
throw new IllegalArgumentException("Object name is empty or null");
88+
}
89+
return objectName.trim()
90+
.replaceAll("[^a-zA-Z0-9]+", "-")
91+
.replaceAll("-{2,}", "-")
92+
.replaceAll("^-|-$", "");
93+
}
94+
6795
@Override
6896
public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format, DataObject dataObject) {
6997
// find an endpoint to send command
7098
EndPoint ep = _epSelector.select(store);
7199
// Create Symlink at ssvm
72100
String path = installPath;
73-
String uuid = UUID.randomUUID().toString();
74-
if (format != null) {
75-
uuid = uuid + "." + format.getFileExtension();
76-
} else if (path.lastIndexOf(".") != -1) {
77-
uuid = uuid + "." + path.substring(path.lastIndexOf(".") + 1);
78-
}
101+
String objectNameInUrl = createObjectNameForExtractUrl(path, format, dataObject);
102+
String objectPathInUrl = UUID.randomUUID().toString();
79103
CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)store).getMountPoint(),
80-
path, uuid, dataObject == null ? null: dataObject.getTO());
104+
path, objectNameInUrl, objectPathInUrl, dataObject == null ? null: dataObject.getTO());
81105
Answer ans = null;
82106
if (ep == null) {
83107
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
@@ -92,10 +116,10 @@ public String createEntityExtractUrl(DataStore store, String installPath, ImageF
92116
throw new CloudRuntimeException(errorString);
93117
}
94118
// Construct actual URL locally now that the symlink exists at SSVM
95-
return generateCopyUrl(ep.getPublicAddr(), uuid);
119+
return generateCopyUrl(ep.getPublicAddr(), objectNameInUrl, objectPathInUrl);
96120
}
97121

98-
private String generateCopyUrl(String ipAddress, String uuid) {
122+
private String generateCopyUrl(String ipAddress, String fileName, String filePath) {
99123

100124
String hostname = ipAddress;
101125
String scheme = "http";
@@ -118,7 +142,7 @@ private String generateCopyUrl(String ipAddress, String uuid) {
118142
}
119143
scheme = "https";
120144
}
121-
return scheme + "://" + hostname + "/userdata/" + uuid;
145+
return scheme + "://" + hostname + "/userdata/" + filePath + "/" + fileName;
122146
}
123147

124148
@Override

server/src/main/java/com/cloud/storage/upload/UploadMonitorImpl.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ else if ((token != null) && (token.length == 5) && (token[2].startsWith(hostname
261261
// Create Symlink at ssvm
262262
String path = vmTemplateHost.getInstallPath();
263263
String uuid = UUID.randomUUID().toString() + "." + template.getFormat().getFileExtension(); // adding "." + vhd/ova... etc.
264-
CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)store).getMountPoint(), path, uuid, null);
264+
CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)store).getMountPoint(), path, uuid, null, null);
265265
Answer ans = ep.sendMessage(cmd);
266266
if (ans == null || !ans.getResult()) {
267267
errorString = "Unable to create a link for " + type + " id:" + template.getId() + "," + (ans == null ? "" : ans.getDetails());
@@ -317,7 +317,7 @@ public void createVolumeDownloadURL(Long entityId, String path, Type type, Long
317317
throw new CloudRuntimeException(errorString);
318318
}
319319

320-
CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)secStore).getMountPoint(), path, uuid, null);
320+
CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)secStore).getMountPoint(), path, uuid, null, null);
321321
Answer ans = ep.sendMessage(cmd);
322322
if (ans == null || !ans.getResult()) {
323323
errorString = "Unable to create a link for " + type + " id:" + entityId + "," + (ans == null ? "" : ans.getDetails());

server/src/main/java/org/apache/cloudstack/diagnostics/to/DiagnosticsDataObject.java

+5
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,9 @@ public void decRefCount() {
9999
public Long getRefCount() {
100100
return null;
101101
}
102+
103+
@Override
104+
public String getName() {
105+
return dataStore.getName();
106+
}
102107
}

services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadManagerImpl.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ public CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDo
268268
}
269269
// Create the directory structure so that its visible under apache server root
270270
String extractDir = "/var/www/html/userdata/";
271+
extractDir = extractDir + cmd.getFilepathInExtractURL() + File.separator;
272+
s_logger.info("HARI " + extractDir);
271273
Script command = new Script("/bin/su", s_logger);
272274
command.add("-s");
273275
command.add("/bin/bash");
@@ -290,11 +292,11 @@ public CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDo
290292
}
291293

292294
// Create a random file under the directory for security reasons.
293-
String uuid = cmd.getExtractLinkUUID();
295+
String filename = cmd.getFilenameInExtractURL();
294296
// Create a symbolic link from the actual directory to the template location. The entity would be directly visible under /var/www/html/userdata/cmd.getInstallPath();
295297
command = new Script("/bin/bash", s_logger);
296298
command.add("-c");
297-
command.add("ln -sf /mnt/SecStorage/" + cmd.getParent() + File.separator + cmd.getInstallPath() + " " + extractDir + uuid);
299+
command.add("ln -sf /mnt/SecStorage/" + cmd.getParent() + File.separator + cmd.getInstallPath() + " " + extractDir + filename);
298300
result = command.execute();
299301
if (result != null) {
300302
String errorString = "Error in linking err=" + result;

0 commit comments

Comments
 (0)