Skip to content

Commit

Permalink
volume upload: persisting the template metadata
Browse files Browse the repository at this point in the history
on calling GetUploadParamsForTemplate, persisting the metadata to db
validating the account limits and incrementing the appropriate limits
encoded the metadata on management server using preshared key
  • Loading branch information
karuturi committed Dec 16, 2014
1 parent b963bb1 commit 7e030ee
Show file tree
Hide file tree
Showing 10 changed files with 297 additions and 34 deletions.
5 changes: 5 additions & 0 deletions api/src/com/cloud/template/TemplateApiService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// under the License.
package com.cloud.template;

import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.List;

Expand All @@ -29,6 +30,7 @@
import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplate;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd;

Expand All @@ -37,11 +39,14 @@
import com.cloud.exception.StorageUnavailableException;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;

public interface TemplateApiService {

VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException;

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

VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws IllegalArgumentException, ResourceAllocationException;

VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@
package org.apache.cloudstack.api.command.user.template;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;

import com.cloud.exception.ResourceAllocationException;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.AbstractGetUploadParamsCommand;
import org.apache.cloudstack.api.ApiConstants;
Expand Down Expand Up @@ -109,35 +108,35 @@ public Map getDetails() {
return params;
}

public Boolean getIsDynamicallyScalable() {
public Boolean isDynamicallyScalable() {
return isDynamicallyScalable;
}

public Boolean getExtractable() {
public Boolean isExtractable() {
return extractable;
}

public Boolean getFeatured() {
public Boolean isFeatured() {
return featured;
}

public Boolean getPublicTemplate() {
public Boolean isPublic() {
return publicTemplate;
}

public Boolean getIsRoutingType() {
public Boolean isRoutingType() {
return isRoutingType;
}

public Boolean getPasswordEnabled() {
public Boolean isPasswordEnabled() {
return passwordEnabled;
}

public Boolean getRequiresHvm() {
return requiresHvm;
}

public Boolean getSshKeyEnabled() {
public Boolean isSshKeyEnabled() {
return sshKeyEnabled;
}

Expand All @@ -147,17 +146,13 @@ public String getTemplateTag() {

@Override
public void execute() throws ServerApiException {
// TODO Auto-generated method stub
try {
GetUploadParamsResponse response = createGetUploadParamsResponse(
UUID.fromString("C7D351D2-F167-4CC8-A9FF-3BECB0A625C4"),
new URL("https://1-2-3-4.xyz.com/upload/C7D351D2-F167-4CC8-A9FF-3BECB0A625C4"),
"TKPFeuz2nHmE/kcREEu24mnj1MrLdzOeJIHXR9HLIGgk56bkRJHaD0RRL2lds1rKKhrro4/PuleEh4YhRinhxaAmPpU4e55eprG8gTCX0ItyFAtlZViVdKXMew5Dfp4Qg8W9I1/IsDJd2Kas9/ftDQLiemAlPt0uS7Ou6asOCpifnBaKvhM4UGEjHSnni1KhBzjgEyDW3Y42HKJSSv58Sgmxl9LCewBX8vtn9tXKr+j4afj7Jlh7DFhyo9HOPC5ogR4hPBKqP7xF9tHxAyq6YqfBzsng3Xwe+Pb8TU1kFHg1l2DM4tY6ooW2h8lOhWUkrJu4hOAOeTeRtCjW3H452NKoeA1M8pKWuqMo5zRMti2u2hNZs0YY2yOy8oWMMG+lG0hvIlajqEU=",
"2014-10-17T12:00:00+0530", "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9");
GetUploadParamsResponse response = _templateService.registerTemplateForPostUpload(this);
response.setResponseName(getCommandName());
setResponseObject(response);
} catch (MalformedURLException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "malformedurl exception: " + e.getMessage());
} catch (ResourceAllocationException | MalformedURLException e) {
s_logger.error("exception while registering template", e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "exception while registering template: " + e.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public GetUploadParamsResponse(UUID id, URL postURL, String metadata, String tim
setObjectName("getuploadparams");
}

public GetUploadParamsResponse() {
}

public void setId(UUID id) {
this.id = id;
}
Expand Down
14 changes: 0 additions & 14 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<executions>
<execution>
<id>cloudstack-checklicence</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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.storage.command;

import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;

public class TemplateOrVolumePostUploadCommand {
DataObject dataObject;
EndPoint endPoint;

public TemplateOrVolumePostUploadCommand(DataObject dataObject, EndPoint endPoint) {
this.dataObject = dataObject;
this.endPoint = endPoint;
}

public DataObject getDataObject() {
return dataObject;
}

public void setDataObject(DataObject dataObject) {
this.dataObject = dataObject;
}

public EndPoint getEndPoint() {
return endPoint;
}

public void setEndPoint(EndPoint endPoint) {
this.endPoint = endPoint;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

TemplateOrVolumePostUploadCommand that = (TemplateOrVolumePostUploadCommand) o;

return dataObject.equals(that.dataObject) && endPoint.equals(that.endPoint);

}

@Override
public int hashCode() {
int result = dataObject.hashCode();
result = 31 * result + endPoint.hashCode();
return result;
}

@Override public String toString() {
return "TemplateOrVolumePostUploadCommand{" +
"dataObject=" + dataObject +
", endPoint=" + endPoint +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.log4j.Logger;

Expand Down Expand Up @@ -104,6 +105,12 @@ public VMTemplateVO create(TemplateProfile profile) {
return template;
}

@Override
public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(TemplateProfile profile) {
// TODO: support baremetal for postupload
return null;
}

@Override
public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
throw new CloudRuntimeException("Baremetal doesn't support ISO, how the delete get here???");
Expand Down
78 changes: 78 additions & 0 deletions server/src/com/cloud/template/HypervisorTemplateAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@

import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import javax.ejb.Local;
import javax.inject.Inject;

import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplate;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
import org.apache.log4j.Logger;

import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
Expand Down Expand Up @@ -131,6 +136,15 @@ public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocatio
return profile;
}

@Override
public TemplateProfile prepare(GetUploadParamsForTemplate cmd) throws ResourceAllocationException {
TemplateProfile profile = super.prepare(cmd);

// Check that the resource limit for secondary storage won't be exceeded
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()), ResourceType.secondary_storage);
return profile;
}

@Override
public VMTemplateVO create(TemplateProfile profile) {
// persist entry in vm_template, vm_template_details and template_zone_ref tables, not that entry at template_store_ref is not created here, and created in createTemplateAsync.
Expand Down Expand Up @@ -185,6 +199,70 @@ public VMTemplateVO create(TemplateProfile profile) {
return template;
}

@Override
public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(TemplateProfile profile) {
// persist entry in vm_template, vm_template_details and template_zone_ref tables, not that entry at template_store_ref is not created here, and created in createTemplateAsync.
VMTemplateVO template = persistTemplate(profile);

if (template == null) {
throw new CloudRuntimeException("Unable to persist the template " + profile.getTemplate());
}

// find all eligible image stores for this zone scope
List<DataStore> imageStores = storeMgr.getImageStoresByScope(new ZoneScope(profile.getZoneId()));
if (imageStores == null || imageStores.size() == 0) {
throw new CloudRuntimeException("Unable to find image store to download template " + profile.getTemplate());
}

List<TemplateOrVolumePostUploadCommand> payloads = new LinkedList<>();
Set<Long> zoneSet = new HashSet<Long>();
Collections.shuffle(imageStores); // For private templates choose a random store. TODO - Have a better algorithm based on size, no. of objects, load etc.
for (DataStore imageStore : imageStores) {
// skip data stores for a disabled zone
Long zoneId = imageStore.getScope().getScopeId();
if (zoneId != null) {
DataCenterVO zone = _dcDao.findById(zoneId);
if (zone == null) {
s_logger.warn("Unable to find zone by id " + zoneId + ", so skip downloading template to its image store " + imageStore.getId());
continue;
}

// Check if zone is disabled
if (Grouping.AllocationState.Disabled == zone.getAllocationState()) {
s_logger.info("Zone " + zoneId + " is disabled, so skip downloading template to its image store " + imageStore.getId());
continue;
}

// We want to download private template to one of the image store in a zone
if (isPrivateTemplate(template) && zoneSet.contains(zoneId)) {
continue;
} else {
zoneSet.add(zoneId);
}

}

TemplateInfo tmpl = imageFactory.getTemplate(template.getId(), imageStore);
//imageService.createTemplateAsync(tmpl, imageStore, caller);

// persist template_store_ref entry
DataObject templateOnStore = imageStore.create(tmpl);
// update template_store_ref and template state

EndPoint ep = _epSelector.select(templateOnStore);
if (ep == null) {
String errMsg = "There is no secondary storage VM for downloading template to image store " + imageStore.getName();
s_logger.warn(errMsg);
throw new CloudRuntimeException(errMsg);
}

TemplateOrVolumePostUploadCommand payload = new TemplateOrVolumePostUploadCommand(templateOnStore, ep);
payloads.add(payload);
}
_resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
return payloads;
}

private boolean isPrivateTemplate(VMTemplateVO template){

// if public OR featured OR system template
Expand Down
7 changes: 7 additions & 0 deletions server/src/com/cloud/template/TemplateAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
// under the License.
package com.cloud.template;

import java.util.List;
import java.util.Map;

import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplate;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;

import com.cloud.exception.ResourceAllocationException;
Expand All @@ -31,6 +33,7 @@
import com.cloud.storage.VMTemplateVO;
import com.cloud.user.Account;
import com.cloud.utils.component.Adapter;
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;

public interface TemplateAdapter extends Adapter {
public static class TemplateAdapterType {
Expand All @@ -50,10 +53,14 @@ public String getName() {

public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException;

public TemplateProfile prepare(GetUploadParamsForTemplate cmd) throws ResourceAllocationException;

public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException;

public VMTemplateVO create(TemplateProfile profile);

public List<TemplateOrVolumePostUploadCommand> createTemplateForPostUpload(TemplateProfile profile);

public TemplateProfile prepareDelete(DeleteTemplateCmd cmd);

public TemplateProfile prepareDelete(DeleteIsoCmd cmd);
Expand Down
Loading

0 comments on commit 7e030ee

Please sign in to comment.