server: update template to another template type (#3945)

this contains other changes
(1) add isrouting field for vm templates on UI
(2) show register URL of template/iso on UI
(3) set 'Bootable' field to changable for existing ISO
This commit is contained in:
Wei Zhou 2020-10-28 11:11:36 +01:00 committed by GitHub
parent b9f15fd159
commit dbb66850b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 119 additions and 4 deletions

View File

@ -21,6 +21,7 @@ import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.user.UserCmd;
@ -35,6 +36,13 @@ public class UpdateTemplateCmd extends BaseUpdateTemplateOrIsoCmd implements Use
public static final Logger s_logger = Logger.getLogger(UpdateTemplateCmd.class.getName());
private static final String s_name = "updatetemplateresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = "templatetype", type = CommandType.STRING, description = "the type of the template")
private String templateType;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -44,6 +52,10 @@ public class UpdateTemplateCmd extends BaseUpdateTemplateOrIsoCmd implements Use
return null;
}
public String getTemplateType() {
return templateType;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -201,6 +201,10 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements
@Param(description = "true if template requires HVM enabled, false otherwise")
private Boolean requiresHvm;
@SerializedName(ApiConstants.URL)
@Param(description = "the URL which the template/iso is registered from")
private String url;
public TemplateResponse() {
tags = new LinkedHashSet<>();
}
@ -402,4 +406,8 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements
public void setRequiresHvm(Boolean requiresHvm) {
this.requiresHvm = requiresHvm;
}
public void setUrl(String url) {
this.url = url;
}
}

View File

@ -184,6 +184,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
if (templateStatus != null) {
templateResponse.setStatus(templateStatus);
}
templateResponse.setUrl(template.getUrl());
}
if (template.getDataCenterId() > 0) {
@ -373,6 +374,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa
} else {
isoResponse.setStatus("Successfully Installed");
}
isoResponse.setUrl(iso.getUrl());
}
if (iso.getDataCenterId() > 0) {

View File

@ -2075,6 +2075,25 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
}
}
// update template type
TemplateType templateType = null;
if (cmd instanceof UpdateTemplateCmd) {
String newType = ((UpdateTemplateCmd)cmd).getTemplateType();
if (newType != null) {
if (!_accountService.isRootAdmin(account.getId())) {
throw new PermissionDeniedException("Parameter templatetype can only be specified by a Root Admin, permission denied");
}
try {
templateType = TemplateType.valueOf(newType.toUpperCase());
} catch (IllegalArgumentException ex) {
throw new InvalidParameterValueException("Please specify a valid templatetype: ROUTING / SYSTEM / USER / BUILTIN / PERHOST");
}
}
if (templateType != null && cmd.isRoutingType() != null && (TemplateType.ROUTING.equals(templateType) != cmd.isRoutingType())) {
throw new InvalidParameterValueException("Please specify a valid templatetype (consistent with isrouting parameter).");
}
}
// update is needed if any of the fields below got filled by the user
boolean updateNeeded =
!(name == null &&
@ -2088,6 +2107,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
sortKey == null &&
isDynamicallyScalable == null &&
isRoutingTemplate == null &&
templateType == null &&
(! cleanupDetails && details == null) //update details in every case except this one
);
if (!updateNeeded) {
@ -2165,9 +2185,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
if (isRoutingTemplate != null) {
if (isRoutingTemplate) {
template.setTemplateType(TemplateType.ROUTING);
} else if (templateType != null) {
template.setTemplateType(templateType);
} else {
template.setTemplateType(TemplateType.USER);
}
} else if (templateType != null) {
template.setTemplateType(templateType);
}
if (cleanupDetails) {

View File

@ -1336,9 +1336,15 @@
name: args.data.name,
displaytext: args.data.displaytext,
ostypeid: args.data.ostypeid,
templatetype: args.data.templatetype,
passwordenabled: (args.data.passwordenabled == "on"),
isdynamicallyscalable: (args.data.isdynamicallyscalable == "on")
};
if (args.data.isrouting != null) {
$.extend(data, {
isrouting: (args.data.isrouting === 'on')
});
}
$.ajax({
url: createURL('updateTemplate'),
data: data,
@ -1846,7 +1852,7 @@
if (isAdmin()) {
hiddenFields = [];
} else {
hiddenFields = ["hypervisor", 'xenserverToolsVersion61plus'];
hiddenFields = ["hypervisor", 'xenserverToolsVersion61plus', 'isrouting'];
}
if ('templates' in args.context && args.context.templates[0].hypervisor != 'XenServer') {
@ -1878,6 +1884,9 @@
}
}
if (!('templates' in args.context && args.context.templates[0].domainid == g_domainid && args.context.templates[0].account == g_account) && !isAdmin()) {
hiddenFields.push('url');
}
return hiddenFields;
},
@ -1991,6 +2000,19 @@
}
},
isrouting: {
label: 'label.routing',
isBoolean: true,
isEditable: function() {
if (isAdmin()) {
return true;
} else {
return false;
}
},
converter: cloudStack.converters.toBooleanText
},
crossZones: {
label: 'label.cross.zones',
converter: cloudStack.converters.toBooleanText
@ -2013,9 +2035,45 @@
label: 'label.created',
converter: cloudStack.converters.toLocalDate
},
url: {
label: 'label.url'
},
templatetype: {
label: 'label.type'
label: 'label.type',
isEditable: function() {
if (isAdmin()) {
return true;
} else {
return false;
}
},
select: function(args) {
var items = [];
items.push({
id: 'ROUTING',
description: 'ROUTING'
});
items.push({
id: 'SYSTEM',
description: 'SYSTEM'
});
items.push({
id: 'BUILTIN',
description: 'BUILTIN'
});
items.push({
id: 'PERHOST',
description: 'PERHOST'
});
items.push({
id: 'USER',
description: 'USER'
});
args.response.success({
data: items
});
}
},
id: {
@ -2045,6 +2103,11 @@
else
jsonObj.xenserverToolsVersion61plus = false;
}
if (jsonObj.templatetype == 'ROUTING') {
jsonObj.isrouting = true;
} else {
jsonObj.isrouting = false;
}
args.response.success({
actionFilter: templateActionfilter,
@ -3236,6 +3299,7 @@
//zoneid: args.context.isos[0].zoneid, //can't update template/ISO in only one zone. It always get updated in all zones.
name: args.data.name,
displaytext: args.data.displaytext,
bootable: (args.data.bootable == "on"),
ostypeid: args.data.ostypeid
};
$.ajax({
@ -3410,6 +3474,8 @@
},
bootable: {
label: 'label.bootable',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
ispublic: {
@ -3470,6 +3536,9 @@
created: {
label: 'label.created',
converter: cloudStack.converters.toLocalDate
},
url: {
label: 'label.url'
}
}],
@ -3805,7 +3874,7 @@
// "Edit Template", "Copy Template", "Create VM"
if ((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id)) //if neither root-admin, nor the same account, nor the same project
|| jsonObj.templatetype == "SYSTEM" || jsonObj.isready == false) {
|| jsonObj.isready == false) {
//do nothing
} else {
allowedActions.push("edit");
@ -3815,7 +3884,7 @@
// "Download Template" , "Update Template Permissions"
if (((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id))) //if neither root-admin, nor the same account, nor the same project
|| (jsonObj.isready == false) || jsonObj.templatetype == "SYSTEM") {
|| (jsonObj.isready == false)) {
//do nothing
} else {
if (jsonObj.isextractable){