Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/src/main/java/com/cloud/template/TemplateApiService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
import org.apache.cloudstack.api.command.admin.template.GetSystemVMTemplateDefaultURLCmd;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
Expand All @@ -39,6 +40,7 @@
import com.cloud.exception.StorageUnavailableException;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.response.GetSystemVMTemplateDefaultURLResponse;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;

public interface TemplateApiService {
Expand All @@ -47,6 +49,10 @@ public interface TemplateApiService {

public GetUploadParamsResponse registerTemplateForPostUpload(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException, MalformedURLException;

GetSystemVMTemplateDefaultURLResponse getSystemVMTemplateDefaultURL(GetSystemVMTemplateDefaultURLCmd cmd);

VirtualMachineTemplate activateSystemVMTemplate(long templateId);

VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws IllegalArgumentException, ResourceAllocationException;

VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException;
Expand Down
2 changes: 2 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ public class ApiConstants {
public static final String TARGET_IQN = "targetiqn";
public static final String TEMPLATE_FILTER = "templatefilter";
public static final String TEMPLATE_ID = "templateid";
public static final String SYSTEM = "system";
public static final String ISO_ID = "isoid";
public static final String TIMEOUT = "timeout";
public static final String TIMEZONE = "timezone";
Expand Down Expand Up @@ -602,6 +603,7 @@ public class ApiConstants {
public static final String INTERVAL = "interval";
public static final String QUIETTIME = "quiettime";
public static final String ACTION = "action";
public static final String ACTIVATE = "activate";
public static final String CONDITION_ID = "conditionid";
public static final String CONDITION_IDS = "conditionids";
public static final String COUNTERPARAM_LIST = "counterparam";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.template;

import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.log4j.Logger;

import java.util.List;

@APICommand(name = "activateSystemVMTemplate", description = "Activates an existing system virtual machine template to be used by CloudStack to create system virtual machines.",
responseObject = TemplateResponse.class, authorized = {RoleType.Admin})
public class ActivateSystemVMTemplateCmd extends BaseCmd {

public static final Logger LOGGER = Logger.getLogger(ActivateSystemVMTemplateCmd.class.getName());
private static final String NAME = "activatesystemvmtemplateresponse";

/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////

@Parameter(name = ApiConstants.ID, type = CommandType.UUID,
entityType = TemplateResponse.class, required = true, description = "The template ID of the System VM Template to activate.")
private Long id;

public Long getId() {
return id;
}

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
VirtualMachineTemplate template = _templateService.activateSystemVMTemplate(id);
if (template != null) {
ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();
List<TemplateResponse> templateResponses = _responseGenerator.createTemplateResponses(ResponseObject.ResponseView.Restricted,
template, 1L , false);
response.setResponses(templateResponses);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to activate template.");
}
}

@Override
public String getCommandName() {
return NAME;
}

public ApiCommandJobType getInstanceType() {
return ApiCommandJobType.Template;
}

@Override
public long getEntityOwnerId() {
final VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, id);
if (template != null) {
return template.getAccountId();
}

// bad id given, parent this command to SYSTEM so ERROR events are tracked
return Account.ACCOUNT_ID_SYSTEM;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.template;

import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.GetSystemVMTemplateDefaultURLResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.log4j.Logger;

@APICommand(name = "getSystemVMTemplateDefaultURL", description = "Gets the system virtual machine template's default download URL.",
responseObject = GetSystemVMTemplateDefaultURLResponse.class, authorized = {RoleType.Admin})
public class GetSystemVMTemplateDefaultURLCmd extends BaseCmd {

public static final Logger LOGGER = Logger.getLogger(GetSystemVMTemplateDefaultURLCmd.class.getName());
private static final String NAME = "getsystemvmtemplatedefaulturlresponse";

/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////

@Parameter(name = ApiConstants.VERSION, type = CommandType.STRING,
entityType = TemplateResponse.class, required = false, description = "The CloudStack version for which to get System VM Template URL.")
private String version;

@Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, entityType = TemplateResponse.class, required = true, description = "The hypervisor for which to get System VM Template URL.")
private String hypervisor;

public String getVersion() {
return version;
}

public String getHypervisor() {
return hypervisor;
}

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
GetSystemVMTemplateDefaultURLResponse response = _templateService.getSystemVMTemplateDefaultURL(this);
if (response != null) {
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to find URL for version '%s' and hypervisor '%s'", version, hypervisor));
}
}

@Override
public String getCommandName() {
return NAME;
}

public ApiCommandJobType getInstanceType() {
return ApiCommandJobType.Template;
}

@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandJobType;
Expand Down Expand Up @@ -161,6 +162,13 @@ public class RegisterTemplateCmd extends BaseCmd {
description = "true if template should bypass Secondary Storage and be downloaded to Primary Storage on deployment")
private Boolean directDownload;

@Parameter(name = ApiConstants.SYSTEM, type = CommandType.BOOLEAN, description = "true if it is a system vm template.")
private Boolean system;

@Parameter(name=ApiConstants.ACTIVATE, type = CommandType.BOOLEAN,
description = "true if this template should be used by CloudStack to create System VMs. Must be used with template type of 'system'.")
private Boolean activate;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -273,6 +281,14 @@ public boolean isDirectDownload() {
return directDownload == null ? false : directDownload;
}

public Boolean isSystem() {
return Optional.ofNullable(system).orElse(false);
}

public Boolean isActivate() {
return Optional.ofNullable(activate).orElse(false);
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -323,7 +339,7 @@ protected void validateParameters() {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
"Both zoneid and zoneids cannot be specified at the same time");

if (zoneId == null && (zoneIds == null || zoneIds.isEmpty()))
if ((zoneId == null && (zoneIds == null || zoneIds.isEmpty())) && !isSystem())
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
"Either zoneid or zoneids is required. Both cannot be null.");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.response;

import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;

public class GetSystemVMTemplateDefaultURLResponse extends BaseResponse {

@SerializedName(ApiConstants.URL)
@Param(description = "The default URL of the System VM template.")
private String url;

public GetSystemVMTemplateDefaultURLResponse() {
}

public GetSystemVMTemplateDefaultURLResponse(String responseName, String url) {
setResponseName(responseName);
setObjectName("url");
this.url = url;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public final class TemplateConstants {
public static final String DEFAULT_TMPLT_FIRST_LEVEL_DIR = "tmpl/";

public static final String DEFAULT_SYSTEM_VM_TEMPLATE_PATH = "template/tmpl/1/";

public static final String DEFAULT_BASE_SYSTEMVM_URL = "https://download.cloudstack.org/systemvm";
public static final String DEFAULT_SYSTEM_VM_TMPLT_NAME = "routing";

public static final int DEFAULT_TMPLT_COPY_PORT = 80;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public TemplateInfo getTemplate() {

AsyncCallFuture<TemplateApiResult> copyTemplate(TemplateInfo srcTemplate, DataStore destStore);

AsyncCallFuture<TemplateApiResult> copySystemVMTemplate(TemplateInfo srcTemplate, DataStore destStore);

AsyncCallFuture<TemplateApiResult> prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool);

AsyncCallFuture<TemplateApiResult> deleteTemplateOnPrimary(TemplateInfo template, StoragePool pool);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<

public List<VMTemplateVO> listAllSystemVMTemplates();

List<VMTemplateVO> listSystemVMTemplatesByUrlLike(String partialUrl, String hType);

public List<VMTemplateVO> listDefaultBuiltinTemplates();

public String getRoutingTemplateUniqueName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
protected SearchBuilder<VMTemplateVO> tmpltTypeHyperSearch;
protected SearchBuilder<VMTemplateVO> readySystemTemplateSearch;
protected SearchBuilder<VMTemplateVO> tmpltTypeHyperSearch2;
protected SearchBuilder<VMTemplateVO> urlLikeSearch;

protected SearchBuilder<VMTemplateVO> AccountIdSearch;
protected SearchBuilder<VMTemplateVO> NameSearch;
Expand Down Expand Up @@ -221,6 +222,15 @@ public List<VMTemplateVO> listAllSystemVMTemplates() {
return listBy(sc, filter);
}

@Override
public List<VMTemplateVO> listSystemVMTemplatesByUrlLike(String partialUrl, String hypervisorType) {
SearchCriteria<VMTemplateVO> sc = urlLikeSearch.create();
sc.setParameters("templateType", TemplateType.SYSTEM);
sc.setParameters("hypervisorType", hypervisorType);
sc.setParameters("url", "%" + partialUrl + "%");
return listBy(sc);
}

@Override
public List<Long> listPrivateTemplatesByHost(Long hostId) {

Expand Down Expand Up @@ -417,6 +427,12 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
ParentTemplateIdSearch.and("state", ParentTemplateIdSearch.entity().getState(), SearchCriteria.Op.EQ);
ParentTemplateIdSearch.done();

urlLikeSearch = createSearchBuilder();
urlLikeSearch.and("templateType", urlLikeSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
urlLikeSearch.and("hypervisorType", urlLikeSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
urlLikeSearch.and("url", urlLikeSearch.entity().getUrl(), SearchCriteria.Op.LIKE);
urlLikeSearch.done();

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.Map;

import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.utils.Pair;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
Expand Down Expand Up @@ -82,6 +83,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<

List<VMInstanceVO> listByTypes(VirtualMachine.Type... types);

List<VMInstanceVO> listByHypervisorTypeAndNonUserTypes(HypervisorType hypervisorType);

VMInstanceVO findByIdTypes(long id, VirtualMachine.Type... types);

VMInstanceVO findVMByInstanceName(String name);
Expand Down
Loading