refactor download template

This commit is contained in:
Edison Su 2012-11-16 18:50:28 -08:00
parent 71f2af5c00
commit 6866613af4
28 changed files with 716 additions and 78 deletions

View File

@ -20,7 +20,7 @@ import java.util.Date;
public interface VMTemplateStorageResourceAssoc {
public static enum Status {
UNKNOWN, DOWNLOAD_ERROR, NOT_DOWNLOADED, DOWNLOAD_IN_PROGRESS, DOWNLOADED, ABANDONED, UPLOADED, NOT_UPLOADED, UPLOAD_ERROR, UPLOAD_IN_PROGRESS
UNKNOWN, DOWNLOAD_ERROR, NOT_DOWNLOADED, DOWNLOAD_IN_PROGRESS, DOWNLOADED, ABANDONED, UPLOADED, NOT_UPLOADED, UPLOAD_ERROR, UPLOAD_IN_PROGRESS, CREATING, CREATED
}
String getInstallPath();

View File

@ -32,4 +32,5 @@ public interface PrimaryDataStoreInfo {
public long getCapacity();
public long getAvailableCapacity();
public List<EndPoint> getEndPoints();
public long getId();
}

View File

@ -360,22 +360,7 @@ public class StorageOrchestratorImpl implements StorageOrchestrator {
@Override
public boolean createVolumeFromTemplate(VolumeEntity volume, long dataStoreId, VolumeDiskType diskType, TemplateEntity template) {
PrimaryDataStore pd = primaryStorageMgr.getPrimaryDataStore(dataStoreId);
boolean existsOnPrimaryStorage = pd.templateExists(template.getId());
if (!existsOnPrimaryStorage) {
TemplateInfo ti = ((TemplateEntityImpl)template).getTemplateInfo();
//TODO: hold lock
VolumeEntity baseImage = volumeService.allocateVolumeInDb(template.getVirtualSize(), new BaseImage(), "BaseImage-" + template.getName(), template.getId());
VolumeInfo vi = pd.createVolume(getVolumeInfo(baseImage), pd.getDefaultDiskType());
volumeService.startCopying(vi);
boolean copyResult = imageMotionService.copyTemplate(ti, vi);
if (copyResult) {
volumeService.copyingSucceed(vi);
} else {
volumeService.copyingFailed(vi);
}
}
return false;
}
}

View File

@ -1,5 +1,6 @@
package org.apache.cloudstack.storage.command;
import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO;
import org.apache.cloudstack.storage.to.TemplateTO;
import org.apache.cloudstack.storage.to.VolumeTO;
@ -7,17 +8,15 @@ import com.cloud.agent.api.Command;
public class CopyTemplateToPrimaryStorage extends Command {
private VolumeTO volume;
private TemplateTO template;
private ImageOnPrimayDataStoreTO imageTO;
protected CopyTemplateToPrimaryStorage() {
super();
}
public CopyTemplateToPrimaryStorage(TemplateTO template, VolumeTO volume) {
public CopyTemplateToPrimaryStorage(ImageOnPrimayDataStoreTO image) {
super();
this.volume = volume;
this.template = template;
this.imageTO = image;
}
@Override

View File

@ -0,0 +1,39 @@
/*
* 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.storage.to.ImageOnPrimayDataStoreTO;
import org.apache.cloudstack.storage.to.VolumeTO;
import com.cloud.agent.api.Command;
public class CreateVolumeFromBaseImageCommand extends Command {
private VolumeTO volume;
private ImageOnPrimayDataStoreTO image;
public CreateVolumeFromBaseImageCommand(VolumeTO volume, ImageOnPrimayDataStoreTO image) {
this.volume = volume;
this.image = image;
}
@Override
public boolean executeInSequence() {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -17,6 +17,8 @@ import org.apache.cloudstack.storage.datastore.driver.PrimaryDataStoreDriver;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.image.TemplateObject;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
import org.apache.cloudstack.storage.volume.TemplatePrimaryDataStoreManager;
import org.apache.cloudstack.storage.volume.VolumeEntityImpl;
import org.apache.cloudstack.storage.volume.VolumeEvent;
import org.apache.cloudstack.storage.volume.VolumeObject;
@ -42,6 +44,8 @@ public class DefaultPrimaryDataStoreImpl implements PrimaryDataStore {
private VolumeDao volumeDao;
@Inject
private HostDao hostDao;
@Inject
TemplatePrimaryDataStoreManager templatePrimaryStoreMgr;
public DefaultPrimaryDataStoreImpl(PrimaryDataStoreDriver driver, DataStoreVO pdsv, PrimaryDataStoreInfo pdsInfo) {
this.driver = driver;
this.pdsv = pdsv;
@ -138,16 +142,8 @@ public class DefaultPrimaryDataStoreImpl implements PrimaryDataStore {
}
@Override
public boolean templateExists(long templateId) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean installTemplate(TemplateInfo template) {
return false;
public boolean templateExists(TemplateInfo template) {
return (templatePrimaryStoreMgr.findTemplateOnPrimaryDataStore(template, this) != null) ? true : false;
}
@Override
@ -155,4 +151,29 @@ public class DefaultPrimaryDataStoreImpl implements PrimaryDataStore {
// TODO Auto-generated method stub
return null;
}
@Override
public long getId() {
// TODO Auto-generated method stub
return 0;
}
@Override
public TemplateOnPrimaryDataStoreInfo getTemplate(TemplateInfo template) {
return templatePrimaryStoreMgr.findTemplateOnPrimaryDataStore(template, this);
}
@Override
public VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo template) {
VolumeObject vo = (VolumeObject)volume;
vo.setVolumeDiskType(template.getTemplate().getDiskType());
this.driver.createVolumeFromBaseImage(vo, template);
return volume;
}
@Override
public boolean installTemplate(TemplateOnPrimaryDataStoreInfo template) {
// TODO Auto-generated method stub
return true;
}
}

View File

@ -27,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.image.TemplateObject;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
import org.apache.cloudstack.storage.volume.VolumeObject;
@ -35,10 +36,13 @@ public interface PrimaryDataStore extends PrimaryDataStoreInfo {
List<VolumeInfo> getVolumes();
boolean deleteVolume(long id);
VolumeInfo createVolume(VolumeInfo vo, VolumeDiskType diskType);
VolumeInfo createVoluemFromBaseImage(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore);
List<EndPoint> getEndPoints();
PrimaryDataStoreInfo getDataStoreInfo();
boolean exists(VolumeInfo vi);
boolean templateExists(long templateId);
boolean installTemplate(TemplateInfo template);
boolean templateExists(TemplateInfo template);
TemplateOnPrimaryDataStoreInfo getTemplate(TemplateInfo template);
boolean installTemplate(TemplateOnPrimaryDataStoreInfo template);
VolumeDiskType getDefaultDiskType();
}

View File

@ -72,4 +72,10 @@ public class PrimaryDataStoreInfoImpl implements PrimaryDataStoreInfo {
// TODO Auto-generated method stub
return null;
}
@Override
public long getId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -7,12 +7,17 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
import org.apache.cloudstack.storage.command.CreateVolumeCommand;
import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand;
import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO;
import org.apache.cloudstack.storage.to.VolumeTO;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
import org.apache.cloudstack.storage.volume.VolumeObject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.utils.exception.CloudRuntimeException;
@Component
public class DefaultPrimaryDataStoreDriverImpl implements
@ -63,5 +68,44 @@ public class DefaultPrimaryDataStoreDriverImpl implements
// TODO Auto-generated method stub
return false;
}
protected Answer sendOutCommand(Command cmd, List<EndPoint> endPoints) {
Answer answer = null;
int retries = 3;
int i = 0;
for (EndPoint ep : endPoints) {
answer = ep.sendMessage(cmd);
if (answer == null || answer.getDetails() != null) {
if (i < retries) {
s_logger.debug("create volume failed, retrying: " + i);
}
i++;
} else {
break;
}
}
return answer;
}
@Override
public boolean createVolumeFromBaseImage(VolumeObject volume, TemplateOnPrimaryDataStoreInfo template) {
VolumeTO vol = new VolumeTO(volume);
ImageOnPrimayDataStoreTO image = new ImageOnPrimayDataStoreTO(template);
CreateVolumeFromBaseImageCommand cmd = new CreateVolumeFromBaseImageCommand(vol, image);
List<EndPoint> endPoints = volume.getDataStore().getEndPoints();
Answer answer = sendOutCommand(cmd, endPoints);
if (answer == null || answer.getDetails() != null) {
if (answer == null) {
throw new CloudRuntimeException("Failed to created volume");
} else {
throw new CloudRuntimeException(answer.getDetails());
}
} else {
CreateVolumeAnswer volAnswer = (CreateVolumeAnswer)answer;
volume.setPath(volAnswer.getVolumeUuid());
return true;
}
}
}

View File

@ -1,12 +1,13 @@
package org.apache.cloudstack.storage.datastore.driver;
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
import org.apache.cloudstack.storage.volume.VolumeObject;
public interface PrimaryDataStoreDriver {
boolean createVolume(VolumeObject vol);
boolean createVolumeFromBaseImage(VolumeObject volume, TemplateOnPrimaryDataStoreInfo template);
boolean deleteVolume(VolumeObject vo);
String grantAccess(VolumeObject vol, EndPoint ep);
boolean revokeAccess(VolumeObject vol, EndPoint ep);

View File

@ -27,7 +27,7 @@ public interface ImageService {
boolean deleteTemplate(long templateId);
long registerIso(String isoUrl, long accountId);
boolean deleteIso(long isoId);
String grantTemplateAccess(TemplateInfo template, EndPoint endpointId);
TemplateInfo grantTemplateAccess(TemplateInfo template, EndPoint endpointId);
boolean revokeTemplateAccess(long templateId, long endpointId);
String grantIsoAccess(long isoId, long endpointId);
boolean revokeIsoAccess(long isoId, long endpointId);

View File

@ -87,7 +87,7 @@ public class ImageServiceImpl implements ImageService {
}
@Override
public String grantTemplateAccess(TemplateInfo template, EndPoint endpointId) {
public TemplateInfo grantTemplateAccess(TemplateInfo template, EndPoint endpointId) {
// TODO Auto-generated method stub
return null;
}

View File

@ -18,8 +18,11 @@
*/
package org.apache.cloudstack.storage.image;
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
import org.apache.cloudstack.storage.image.store.ImageDataStoreInfo;
public interface TemplateInfo {
ImageDataStoreInfo getImageDataStore();
long getId();
VolumeDiskType getDiskType();
}

View File

@ -18,14 +18,30 @@
*/
package org.apache.cloudstack.storage.image;
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskTypeHelper;
import org.apache.cloudstack.storage.image.db.ImageDataVO;
import org.apache.cloudstack.storage.image.store.ImageDataStoreInfo;
public class TemplateObject implements TemplateInfo {
private ImageDataVO imageVO;
public TemplateObject(ImageDataVO template) {
this.imageVO = template;
}
@Override
public ImageDataStoreInfo getImageDataStore() {
// TODO Auto-generated method stub
return null;
}
@Override
public long getId() {
// TODO Auto-generated method stub
return 0;
}
@Override
public VolumeDiskType getDiskType() {
return VolumeDiskTypeHelper.getDiskType(imageVO.getFormat());
}
}

View File

@ -25,30 +25,29 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorage;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO;
import org.apache.cloudstack.storage.to.TemplateTO;
import org.apache.cloudstack.storage.to.VolumeTO;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
public class DefaultImageMotionStrategy implements ImageMotionStrategy {
@Override
public boolean canHandle(TemplateInfo template, VolumeInfo volume) {
public boolean canHandle(TemplateOnPrimaryDataStoreInfo templateStore) {
// TODO Auto-generated method stub
return true;
}
//For default strategy, we will use one of endpoint in volume's datastore
@Override
public EndPoint getEndPoint(TemplateInfo template, VolumeInfo volume) {
PrimaryDataStoreInfo pdi = volume.getDataStore();
public EndPoint getEndPoint(TemplateOnPrimaryDataStoreInfo templateStore) {
PrimaryDataStoreInfo pdi = templateStore.getPrimaryDataStore();
return pdi.getEndPoints().get(0);
}
@Override
public boolean copyTemplate(TemplateInfo template, VolumeInfo volume,
EndPoint ep) {
VolumeTO vt = new VolumeTO(volume);
TemplateTO tt = new TemplateTO(template);
CopyTemplateToPrimaryStorage copyCommand = new CopyTemplateToPrimaryStorage(tt, vt);
public boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep) {
ImageOnPrimayDataStoreTO imageTo = new ImageOnPrimayDataStoreTO(templateStore);
CopyTemplateToPrimaryStorage copyCommand = new CopyTemplateToPrimaryStorage(imageTo);
ep.sendMessage(copyCommand);
return true;
}

View File

@ -18,13 +18,9 @@
*/
package org.apache.cloudstack.storage.image.motion;
import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
public interface ImageMotionService {
boolean copyTemplate(TemplateInfo template, VolumeInfo baseImage);
boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore);
boolean copyIso(String isoUri, String destIsoUri);
}

View File

@ -29,6 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.image.ImageService;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
import org.apache.cloudstack.storage.volume.VolumeService;
import com.cloud.utils.exception.CloudRuntimeException;
@ -47,10 +48,10 @@ public class ImageMotionServiceImpl implements ImageMotionService {
}
@Override
public boolean copyTemplate(TemplateInfo template, VolumeInfo volume) {
public boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore) {
ImageMotionStrategy ims = null;
for (ImageMotionStrategy strategy : motionStrategies) {
if (strategy.canHandle(template, volume)) {
if (strategy.canHandle(templateStore)) {
ims = strategy;
break;
}
@ -60,10 +61,11 @@ public class ImageMotionServiceImpl implements ImageMotionService {
throw new CloudRuntimeException("Can't find proper image motion strategy");
}
EndPoint ep = ims.getEndPoint(template, volume);
EndPoint ep = ims.getEndPoint(templateStore);
volumeService.grantAccess(volume, ep);
volumeService.grantAccess(templateStore, ep);
TemplateInfo template = templateStore.getTemplate();
imageService.grantTemplateAccess(template, ep);
return ims.copyTemplate(template, volume, ep);
return ims.copyTemplate(templateStore, ep);
}
}

View File

@ -18,14 +18,11 @@
*/
package org.apache.cloudstack.storage.image.motion;
import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
public interface ImageMotionStrategy {
public boolean canHandle(TemplateInfo template, VolumeInfo volume);
public EndPoint getEndPoint(TemplateInfo template, VolumeInfo volume);
public boolean copyTemplate(TemplateInfo template, VolumeInfo volume, EndPoint ep);
public boolean canHandle(TemplateOnPrimaryDataStoreInfo templateStore);
public EndPoint getEndPoint(TemplateOnPrimaryDataStoreInfo templateStore);
public boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep);
}

View File

@ -0,0 +1,27 @@
/*
* 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.to;
import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo;
public class ImageOnPrimayDataStoreTO {
public ImageOnPrimayDataStoreTO(TemplateOnPrimaryDataStoreInfo template) {
}
}

View File

@ -0,0 +1,29 @@
/*
* 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.volume;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.storage.image.TemplateInfo;
public interface TemplateOnPrimaryDataStoreInfo {
public String getPath();
public void setPath(String path);
public PrimaryDataStoreInfo getPrimaryDataStore();
public TemplateInfo getTemplate();
}

View File

@ -0,0 +1,68 @@
/*
* 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.volume;
import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDao;
import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
public class TemplateOnPrimaryDataStoreObject implements TemplateOnPrimaryDataStoreInfo {
protected PrimaryDataStoreInfo dataStore;
protected TemplateInfo template;
protected TemplatePrimaryDataStoreVO vo;
@Inject
TemplatePrimaryDataStoreDao templateStoreDao;
public TemplateOnPrimaryDataStoreObject(PrimaryDataStoreInfo primaryDataStore, TemplateInfo template, TemplatePrimaryDataStoreVO vo) {
this.dataStore = primaryDataStore;
this.template = template;
this.vo = vo;
}
@Override
public String getPath() {
return vo.getInstallPath();
}
@Override
public void setPath(String path) {
this.vo.setInstallPath(path);
}
@Override
public PrimaryDataStoreInfo getPrimaryDataStore() {
return this.dataStore;
}
@Override
public TemplateInfo getTemplate() {
return this.template;
}
public void updateStatus(Status status) {
vo.setDownloadState(status);
templateStoreDao.update(vo.getId(), vo);
}
}

View File

@ -0,0 +1,27 @@
/*
* 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.volume;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.storage.image.TemplateInfo;
public interface TemplatePrimaryDataStoreManager {
public TemplateOnPrimaryDataStoreInfo createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore);
public TemplateOnPrimaryDataStoreInfo findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore);
}

View File

@ -0,0 +1,54 @@
/*
* 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.volume;
import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDao;
import org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.utils.db.SearchCriteria2;
import com.cloud.utils.db.SearchCriteriaService;
import com.cloud.utils.db.SearchCriteria.Op;
public class TemplatePrimaryDataStoreManagerImpl implements TemplatePrimaryDataStoreManager {
@Inject
TemplatePrimaryDataStoreDao templateStoreDao;
@Override
public TemplateOnPrimaryDataStoreObject createTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore) {
TemplatePrimaryDataStoreVO templateStoreVO = new TemplatePrimaryDataStoreVO(dataStore.getId(), template.getId());
templateStoreVO = templateStoreDao.persist(templateStoreVO);
TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO);
return templateStoreObject;
}
@Override
public TemplateOnPrimaryDataStoreObject findTemplateOnPrimaryDataStore(TemplateInfo template, PrimaryDataStoreInfo dataStore) {
SearchCriteriaService<TemplatePrimaryDataStoreVO, TemplatePrimaryDataStoreVO> sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class);
sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, template.getId());
sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, dataStore.getId());
sc.addAnd(sc.getEntity().getDownloadState(), Op.EQ, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
TemplatePrimaryDataStoreVO templateStoreVO = sc.find();
TemplateOnPrimaryDataStoreObject templateStoreObject = new TemplateOnPrimaryDataStoreObject(dataStore, template, templateStoreVO);
return templateStoreObject;
}
}

View File

@ -18,11 +18,13 @@
*/
package org.apache.cloudstack.storage.volume;
import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
import org.apache.cloudstack.storage.image.TemplateInfo;
public interface VolumeService {
@ -63,12 +65,13 @@ public interface VolumeService {
*/
String grantAccess(VolumeInfo volume, EndPoint endpointId);
TemplateOnPrimaryDataStoreInfo grantAccess(TemplateOnPrimaryDataStoreInfo template, EndPoint endPoint);
/**
*
*/
boolean rokeAccess(long volumeId, long endpointId);
VolumeInfo startCopying(VolumeInfo volume);
VolumeInfo copyingSucceed(VolumeInfo volume);
VolumeInfo copyingFailed(VolumeInfo volume);
VolumeEntity getVolumeEntity(long volumeId);
VolumeInfo createVolumeFromTemplate(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template);
}

View File

@ -20,18 +20,24 @@ package org.apache.cloudstack.storage.volume;
import javax.inject.Inject;
import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType;
import org.apache.cloudstack.engine.subsystem.api.storage.type.BaseImage;
import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreManager;
import org.apache.cloudstack.storage.image.TemplateEntityImpl;
import org.apache.cloudstack.storage.image.TemplateInfo;
import org.apache.cloudstack.storage.image.motion.ImageMotionService;
import org.apache.cloudstack.storage.volume.db.VolumeDao;
import org.apache.cloudstack.storage.volume.db.VolumeVO;
import org.springframework.stereotype.Service;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.Volume;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
@ -45,6 +51,10 @@ public class VolumeServiceImpl implements VolumeService {
VolumeDao volDao;
@Inject
PrimaryDataStoreManager dataStoreMgr;
@Inject
TemplatePrimaryDataStoreManager templatePrimaryStoreMgr;
@Inject
ImageMotionService imageMotion;
@Override
public VolumeInfo createVolume(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType) {
PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(dataStoreId);
@ -114,26 +124,63 @@ public class VolumeServiceImpl implements VolumeService {
}
}
@Override
public String grantAccess(VolumeInfo volume, EndPoint endpointId) {
// TODO Auto-generated method stub
return null;
}
protected TemplateOnPrimaryDataStoreObject createBaseImage(PrimaryDataStore dataStore, TemplateInfo template) {
TemplateOnPrimaryDataStoreObject templateOnPrimaryStoreObj = (TemplateOnPrimaryDataStoreObject)templatePrimaryStoreMgr.createTemplateOnPrimaryDataStore(template, dataStore);
templateOnPrimaryStoreObj.updateStatus(Status.CREATING);
try {
dataStore.installTemplate(templateOnPrimaryStoreObj);
templateOnPrimaryStoreObj.updateStatus(Status.CREATED);
} catch (Exception e) {
templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
throw new CloudRuntimeException(e.toString());
}
templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOAD_IN_PROGRESS);
try {
imageMotion.copyTemplate(templateOnPrimaryStoreObj);
templateOnPrimaryStoreObj.updateStatus(Status.DOWNLOADED);
} catch (Exception e) {
templateOnPrimaryStoreObj.updateStatus(Status.ABANDONED);
throw new CloudRuntimeException(e.toString());
}
return templateOnPrimaryStoreObj;
}
@Override
public VolumeInfo startCopying(VolumeInfo volume) {
// TODO Auto-generated method stub
return null;
public VolumeInfo createVolumeFromTemplate(VolumeInfo volume, long dataStoreId, VolumeDiskType diskType, TemplateInfo template) {
PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
TemplateOnPrimaryDataStoreInfo templateOnPrimaryStore = pd.getTemplate(template);
if (templateOnPrimaryStore == null) {
templateOnPrimaryStore = createBaseImage(pd, template);
}
VolumeObject vo = (VolumeObject)volume;
try {
vo.stateTransit(VolumeEvent.CreateRequested);
} catch (Exception e) {
throw new CloudRuntimeException(e.toString());
}
try {
volume = pd.createVoluemFromBaseImage(volume, templateOnPrimaryStore);
vo.stateTransit(VolumeEvent.OperationSucceeded);
} catch (Exception e) {
vo.stateTransit(VolumeEvent.OperationFailed);
throw new CloudRuntimeException(e.toString());
}
return volume;
}
@Override
public VolumeInfo copyingSucceed(VolumeInfo volume) {
// TODO Auto-generated method stub
return null;
}
@Override
public VolumeInfo copyingFailed(VolumeInfo volume) {
public TemplateOnPrimaryDataStoreInfo grantAccess(TemplateOnPrimaryDataStoreInfo template, EndPoint endPoint) {
// TODO Auto-generated method stub
return null;
}

View File

@ -0,0 +1,24 @@
/*
* 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.volume.db;
import com.cloud.utils.db.GenericDao;
public interface TemplatePrimaryDataStoreDao extends GenericDao<TemplatePrimaryDataStoreVO, Long> {
}

View File

@ -0,0 +1,28 @@
/*
* 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.volume.db;
import org.springframework.stereotype.Component;
import com.cloud.utils.db.GenericDaoBase;
@Component
public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase<TemplatePrimaryDataStoreVO, Long> implements TemplatePrimaryDataStoreDao {
}

View File

@ -0,0 +1,218 @@
/*
* 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.volume.db;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.utils.db.GenericDaoBase;
@Entity
@Table(name="template_spool_ref")
public class TemplatePrimaryDataStoreVO {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
long id;
@Column(name="pool_id")
private long poolId;
@Column(name="template_id") long templateId;
@Column(name=GenericDaoBase.CREATED_COLUMN) Date created = null;
@Column(name="last_updated")
@Temporal(value=TemporalType.TIMESTAMP) Date lastUpdated = null;
@Column (name="download_pct") int downloadPercent;
@Column (name="download_state")
@Enumerated(EnumType.STRING) Status downloadState;
@Column (name="local_path") String localDownloadPath;
@Column (name="error_str") String errorString;
@Column (name="job_id") String jobId;
@Column (name="install_path") String installPath;
@Column (name="template_size") long templateSize;
@Column (name="marked_for_gc") boolean markedForGC;
public String getInstallPath() {
return installPath;
}
public long getTemplateSize() {
return templateSize;
}
public long getPoolId() {
return poolId;
}
public void setpoolId(long poolId) {
this.poolId = poolId;
}
public long getTemplateId() {
return templateId;
}
public void setTemplateId(long templateId) {
this.templateId = templateId;
}
public int getDownloadPercent() {
return downloadPercent;
}
public void setDownloadPercent(int downloadPercent) {
this.downloadPercent = downloadPercent;
}
public void setDownloadState(Status downloadState) {
this.downloadState = downloadState;
}
public long getId() {
return id;
}
public Date getCreated() {
return created;
}
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date date) {
lastUpdated = date;
}
public void setInstallPath(String installPath) {
this.installPath = installPath;
}
public Status getDownloadState() {
return downloadState;
}
public TemplatePrimaryDataStoreVO(long poolId, long templateId) {
super();
this.poolId = poolId;
this.templateId = templateId;
this.downloadState = Status.NOT_DOWNLOADED;
this.markedForGC = false;
}
public TemplatePrimaryDataStoreVO(long poolId, long templateId, Date lastUpdated,
int downloadPercent, Status downloadState,
String localDownloadPath, String errorString, String jobId,
String installPath, long templateSize) {
super();
this.poolId = poolId;
this.templateId = templateId;
this.lastUpdated = lastUpdated;
this.downloadPercent = downloadPercent;
this.downloadState = downloadState;
this.localDownloadPath = localDownloadPath;
this.errorString = errorString;
this.jobId = jobId;
this.installPath = installPath;
this.templateSize = templateSize;
}
protected TemplatePrimaryDataStoreVO() {
}
public void setLocalDownloadPath(String localPath) {
this.localDownloadPath = localPath;
}
public String getLocalDownloadPath() {
return localDownloadPath;
}
public void setErrorString(String errorString) {
this.errorString = errorString;
}
public String getErrorString() {
return errorString;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public String getJobId() {
return jobId;
}
public void setTemplateSize(long templateSize) {
this.templateSize = templateSize;
}
public boolean getMarkedForGC() {
return markedForGC;
}
public void setMarkedForGC(boolean markedForGC) {
this.markedForGC = markedForGC;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TemplatePrimaryDataStoreVO) {
TemplatePrimaryDataStoreVO other = (TemplatePrimaryDataStoreVO)obj;
return (this.templateId==other.getTemplateId() && this.poolId==other.getPoolId());
}
return false;
}
@Override
public int hashCode() {
Long tid = new Long(templateId);
Long hid = new Long(poolId);
return tid.hashCode()+hid.hashCode();
}
@Override
public String toString() {
return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append("poolId").append("-").append(installPath).append("]").toString();
}
}