mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
add image create test case
This commit is contained in:
parent
aa7b3e0f6d
commit
c921118c58
@ -20,12 +20,18 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
|
||||
|
||||
public class CreateCmdResult extends CommandResult {
|
||||
private String path;
|
||||
public CreateCmdResult(String path) {
|
||||
private Long size;
|
||||
public CreateCmdResult(String path, Long size) {
|
||||
super();
|
||||
this.path = path;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ public interface DataObject {
|
||||
public long getId();
|
||||
public String getUri();
|
||||
public DataStore getDataStore();
|
||||
public long getSize();
|
||||
public Long getSize();
|
||||
public DataObjectType getType();
|
||||
public DiskFormat getFormat();
|
||||
public String getUuid();
|
||||
|
||||
@ -21,5 +21,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
|
||||
public enum ScopeType {
|
||||
HOST,
|
||||
CLUSTER,
|
||||
ZONE;
|
||||
ZONE,
|
||||
REGION,
|
||||
GLOBAL;
|
||||
}
|
||||
|
||||
@ -40,11 +40,17 @@ public class ImageDataFactoryImpl implements ImageDataFactory {
|
||||
DataStoreManager storeMgr;
|
||||
@Override
|
||||
public TemplateInfo getTemplate(long templateId, DataStore store) {
|
||||
ImageDataVO templ = imageDataDao.findById(templateId);
|
||||
if (store == null) {
|
||||
TemplateObject tmpl = TemplateObject.getTemplate(templ, null);
|
||||
return tmpl;
|
||||
}
|
||||
ObjectInDataStoreVO obj = objMap.findObject(templateId, DataObjectType.TEMPLATE, store.getId(), store.getRole());
|
||||
if (obj == null) {
|
||||
return null;
|
||||
TemplateObject tmpl = TemplateObject.getTemplate(templ, null);
|
||||
return tmpl;
|
||||
}
|
||||
ImageDataVO templ = imageDataDao.findById(templateId);
|
||||
|
||||
TemplateObject tmpl = TemplateObject.getTemplate(templ, store);
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
@ -78,6 +78,7 @@ public class ImageServiceImpl implements ImageService {
|
||||
TemplateInfo templateOnStore = null;
|
||||
if (obj == null) {
|
||||
templateOnStore = objectInDataStoreMgr.create(template, store);
|
||||
obj = objectInDataStoreMgr.findObject(template.getId(), template.getType(), store.getId(), store.getRole());
|
||||
} else {
|
||||
CommandResult result = new CommandResult();
|
||||
result.setResult("duplicate template on the storage");
|
||||
@ -128,6 +129,10 @@ public class ImageServiceImpl implements ImageService {
|
||||
ObjectInDataStoreVO obj = context.obj;
|
||||
obj.setInstallPath(callbackResult.getPath());
|
||||
|
||||
if (callbackResult.getSize() != null) {
|
||||
obj.setSize(callbackResult.getSize());
|
||||
}
|
||||
|
||||
try {
|
||||
objectInDataStoreMgr.update(templateOnStore, Event.OperationSuccessed);
|
||||
} catch (NoTransitionException e) {
|
||||
|
||||
@ -20,6 +20,8 @@ package org.apache.cloudstack.storage.image.driver;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||
@ -28,11 +30,15 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectCommand;
|
||||
import org.apache.cloudstack.storage.endpoint.EndPointSelector;
|
||||
import org.apache.cloudstack.storage.image.ImageDataStoreDriver;
|
||||
|
||||
//http-read-only based image store
|
||||
public class DefaultImageDataStoreDriverImpl implements ImageDataStoreDriver {
|
||||
|
||||
@Inject
|
||||
EndPointSelector selector;
|
||||
public DefaultImageDataStoreDriverImpl() {
|
||||
}
|
||||
|
||||
@ -57,10 +63,28 @@ public class DefaultImageDataStoreDriverImpl implements ImageDataStoreDriver {
|
||||
public void createAsync(DataObject data,
|
||||
AsyncCompletionCallback<CreateCmdResult> callback) {
|
||||
//for default http data store, can create http based template/iso
|
||||
CreateCmdResult result = new CreateCmdResult("");
|
||||
CreateCmdResult result = new CreateCmdResult("", null);
|
||||
if (!data.getUri().startsWith("http")) {
|
||||
result.setResult("can't register an image which is not a http link");
|
||||
callback.complete(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.getSize() == null && data.getType() == DataObjectType.TEMPLATE) {
|
||||
//the template size is unknown during registration, need to find out the size of template
|
||||
EndPoint ep = selector.select(data);
|
||||
if (ep == null) {
|
||||
result.setResult("can't find storage client for:" + data.getId() + "," + data.getType());
|
||||
callback.complete(result);
|
||||
return;
|
||||
}
|
||||
CreateObjectCommand createCmd = new CreateObjectCommand(data.getUri());
|
||||
CreateObjectAnswer answer = (CreateObjectAnswer)ep.sendMessage(createCmd);
|
||||
if (answer.getResult()) {
|
||||
result = new CreateCmdResult(answer.getPath(), answer.getSize());
|
||||
} else {
|
||||
result.setResult(answer.getDetails());
|
||||
}
|
||||
}
|
||||
|
||||
callback.complete(result);
|
||||
|
||||
@ -21,11 +21,13 @@ package org.apache.cloudstack.storage.image.manager;
|
||||
import org.apache.cloudstack.storage.image.TemplateEvent;
|
||||
import org.apache.cloudstack.storage.image.TemplateState;
|
||||
import org.apache.cloudstack.storage.image.db.ImageDataVO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
|
||||
@Component
|
||||
public class ImageDataManagerImpl implements ImageDataManager {
|
||||
private final static StateMachine2<TemplateState, TemplateEvent, ImageDataVO>
|
||||
private final StateMachine2<TemplateState, TemplateEvent, ImageDataVO>
|
||||
stateMachine = new StateMachine2<TemplateState, TemplateEvent, ImageDataVO>();
|
||||
|
||||
public ImageDataManagerImpl() {
|
||||
|
||||
@ -45,12 +45,16 @@ public class HttpDataStoreImpl implements ImageDataStore {
|
||||
ImageDataDao imageDao;
|
||||
@Inject
|
||||
private ObjectInDataStoreManager objectInStoreMgr;
|
||||
ImageDataStoreDriver driver;
|
||||
ImageDataStoreVO imageDataStoreVO;
|
||||
ImageDataStoreProvider provider;
|
||||
protected ImageDataStoreDriver driver;
|
||||
protected ImageDataStoreVO imageDataStoreVO;
|
||||
protected ImageDataStoreProvider provider;
|
||||
boolean needDownloadToCacheStorage = false;
|
||||
|
||||
private HttpDataStoreImpl(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver,
|
||||
protected HttpDataStoreImpl() {
|
||||
|
||||
}
|
||||
|
||||
protected void configure(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver,
|
||||
ImageDataStoreProvider provider) {
|
||||
this.driver = imageDataStoreDriver;
|
||||
this.imageDataStoreVO = dataStoreVO;
|
||||
@ -59,8 +63,9 @@ public class HttpDataStoreImpl implements ImageDataStore {
|
||||
|
||||
public static HttpDataStoreImpl getDataStore(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver,
|
||||
ImageDataStoreProvider provider) {
|
||||
HttpDataStoreImpl instance = new HttpDataStoreImpl(dataStoreVO, imageDataStoreDriver, provider);
|
||||
return ComponentContext.inject(instance);
|
||||
HttpDataStoreImpl instance = (HttpDataStoreImpl)ComponentContext.inject(HttpDataStoreImpl.class);
|
||||
instance.configure(dataStoreVO, imageDataStoreDriver, provider);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -49,14 +49,18 @@ public class TemplateObject implements TemplateInfo {
|
||||
@Inject
|
||||
ObjectInDataStoreManager ojbectInStoreMgr;
|
||||
|
||||
private TemplateObject(ImageDataVO template, DataStore dataStore) {
|
||||
protected TemplateObject() {
|
||||
}
|
||||
|
||||
protected void configure(ImageDataVO template, DataStore dataStore) {
|
||||
this.imageVO = template;
|
||||
this.dataStore = dataStore;
|
||||
}
|
||||
|
||||
public static TemplateObject getTemplate(ImageDataVO vo, DataStore store) {
|
||||
TemplateObject to = new TemplateObject(vo, store);
|
||||
return ComponentContext.inject(to);
|
||||
TemplateObject to = ComponentContext.inject(TemplateObject.class);
|
||||
to.configure(vo, store);
|
||||
return to;
|
||||
}
|
||||
|
||||
public void setImageStoreId(long id) {
|
||||
@ -90,7 +94,7 @@ public class TemplateObject implements TemplateInfo {
|
||||
} else {
|
||||
ObjectInDataStoreVO obj = ojbectInStoreMgr.findObject(this.imageVO.getId(), DataObjectType.TEMPLATE, this.dataStore.getId(), this.dataStore.getRole());
|
||||
if (obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
|
||||
return this.dataStore.getUri() + File.separator + "&objType=" + DataObjectType.TEMPLATE + "&size=" + this.imageVO.getSize();
|
||||
return this.dataStore.getUri() + File.separator + "&objType=" + DataObjectType.TEMPLATE + "&size=" + this.imageVO.getSize() + "&path=" + this.imageVO.getUrl();
|
||||
} else {
|
||||
return this.dataStore.getUri() + File.separator + "&objType=" + DataObjectType.TEMPLATE + "&path=" + obj.getInstallPath();
|
||||
}
|
||||
@ -98,9 +102,12 @@ public class TemplateObject implements TemplateInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
public Long getSize() {
|
||||
if (this.dataStore == null) {
|
||||
return null;
|
||||
}
|
||||
ObjectInDataStoreVO obj = ojbectInStoreMgr.findObject(this.imageVO.getId(), DataObjectType.TEMPLATE, this.dataStore.getId(), this.dataStore.getRole());
|
||||
return obj.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -23,20 +23,26 @@ import javax.inject.Inject;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper;
|
||||
import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager;
|
||||
import org.apache.cloudstack.storage.image.db.ImageDataStoreDao;
|
||||
import org.apache.cloudstack.storage.image.db.ImageDataStoreVO;
|
||||
|
||||
public class DefaultImageDataStoreLifeCycle implements ImageDataStoreLifeCycle {
|
||||
@Inject
|
||||
protected ImageDataStoreDao imageStoreDao;
|
||||
|
||||
@Inject
|
||||
ImageDataStoreHelper imageStoreHelper;
|
||||
@Inject
|
||||
ImageDataStoreManager imageStoreMgr;
|
||||
public DefaultImageDataStoreLifeCycle() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DataStore initialize(Map<String, String> dsInfos) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
ImageDataStoreVO ids = imageStoreHelper.createImageDataStore(dsInfos);
|
||||
return imageStoreMgr.getImageDataStore(ids.getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -32,19 +32,25 @@ import javax.naming.ConfigurationException;
|
||||
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.ClusterScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
|
||||
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.ScopeType;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk;
|
||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||
import org.apache.cloudstack.storage.HypervisorHostEndPoint;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreVO;
|
||||
import org.apache.cloudstack.storage.datastore.provider.DataStoreProvider;
|
||||
import org.apache.cloudstack.storage.datastore.provider.DataStoreProviderManager;
|
||||
import org.apache.cloudstack.storage.endpoint.EndPointSelector;
|
||||
import org.apache.cloudstack.storage.image.ImageDataFactory;
|
||||
import org.apache.cloudstack.storage.image.ImageService;
|
||||
import org.apache.cloudstack.storage.image.TemplateInfo;
|
||||
import org.apache.cloudstack.storage.image.db.ImageDataDao;
|
||||
import org.apache.cloudstack.storage.image.db.ImageDataVO;
|
||||
import org.apache.cloudstack.storage.volume.VolumeService;
|
||||
@ -52,6 +58,7 @@ import org.apache.cloudstack.storage.volume.db.VolumeDao2;
|
||||
import org.apache.cloudstack.storage.volume.db.VolumeVO;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
@ -69,6 +76,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.org.Cluster.ClusterType;
|
||||
import com.cloud.org.Managed.ManagedState;
|
||||
import com.cloud.resource.ResourceState;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Storage.TemplateType;
|
||||
|
||||
@ContextConfiguration(locations={"classpath:/storageContext.xml"})
|
||||
@ -99,6 +107,8 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
AgentManager agentMgr;
|
||||
@Inject
|
||||
EndPointSelector selector;
|
||||
@Inject
|
||||
ImageDataFactory imageDataFactory;
|
||||
Long dcId;
|
||||
Long clusterId;
|
||||
Long podId;
|
||||
@ -188,6 +198,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
eps.add(HypervisorHostEndPoint.getHypervisorHostEndPoint(host.getId(),
|
||||
host.getPrivateIpAddress()));
|
||||
Mockito.when(selector.selectAll(Mockito.any(DataStore.class))).thenReturn(eps);
|
||||
Mockito.when(selector.select(Mockito.any(DataObject.class))).thenReturn(eps.get(0));
|
||||
}
|
||||
|
||||
private ImageDataVO createImageData() {
|
||||
@ -200,7 +211,7 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
image.setFeatured(true);
|
||||
image.setRequireHvm(true);
|
||||
image.setBits(64);
|
||||
//image.setFormat(new VHD().toString());
|
||||
image.setFormat(Storage.ImageFormat.VHD.toString());
|
||||
image.setAccountId(1);
|
||||
image.setEnablePassword(true);
|
||||
image.setEnableSshKey(true);
|
||||
@ -209,12 +220,20 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
image.setPrepopulate(true);
|
||||
image.setCrossZones(true);
|
||||
image.setExtractable(true);
|
||||
|
||||
//image.setImageDataStoreId(storeId);
|
||||
image = imageDataDao.persist(image);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private TemplateEntity createTemplate() {
|
||||
try {
|
||||
DataStore store = createImageStore();
|
||||
ImageDataVO image = createImageData();
|
||||
TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store);
|
||||
AsyncCallFuture<CommandResult> future = imageService.createTemplateAsync(template, store);
|
||||
future.get();
|
||||
/*imageProviderMgr.configure("image Provider", new HashMap<String, Object>());
|
||||
ImageDataVO image = createImageData();
|
||||
ImageDataStoreProvider defaultProvider = imageProviderMgr.getProvider("DefaultProvider");
|
||||
@ -225,15 +244,17 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
return te;*/
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
Assert.fail("failed", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTemplateTest() {
|
||||
createTemplate();
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void testCreatePrimaryStorage() {
|
||||
DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default primary data store provider");
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
@ -261,6 +282,25 @@ public class volumeServiceTest extends CloudStackTestNGBase {
|
||||
ClusterScope scope = new ClusterScope(clusterId, podId, dcId);
|
||||
lifeCycle.attachCluster(store, scope);
|
||||
}
|
||||
|
||||
private DataStore createImageStore() {
|
||||
DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default image data store");
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
String name = UUID.randomUUID().toString();
|
||||
params.put("name", name);
|
||||
params.put("uuid", name);
|
||||
params.put("protocol", "http");
|
||||
params.put("scope", ScopeType.GLOBAL.toString());
|
||||
params.put("provider", Long.toString(provider.getId()));
|
||||
DataStoreLifeCycle lifeCycle = provider.getLifeCycle();
|
||||
DataStore store = lifeCycle.initialize(params);
|
||||
return store;
|
||||
}
|
||||
@Test
|
||||
public void testcreateImageStore() {
|
||||
createImageStore();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public PrimaryDataStoreInfo createPrimaryDataStore() {
|
||||
|
||||
@ -74,9 +74,9 @@ public class SnapshotObject implements SnapshotInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
public Long getSize() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -21,23 +21,28 @@ package org.apache.cloudstack.storage.command;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
|
||||
public class CreateVolumeAnswer extends Answer {
|
||||
private String volumeUuid;
|
||||
|
||||
protected CreateVolumeAnswer() {
|
||||
public class CreateObjectAnswer extends Answer {
|
||||
private String path;
|
||||
private Long size;
|
||||
protected CreateObjectAnswer() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CreateVolumeAnswer(Command cmd, String volumeUuid) {
|
||||
public CreateObjectAnswer(Command cmd, String path, Long size) {
|
||||
super(cmd);
|
||||
this.volumeUuid = volumeUuid;
|
||||
this.path = path;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public CreateVolumeAnswer(Command cmd, boolean status, String result) {
|
||||
public CreateObjectAnswer(Command cmd, boolean status, String result) {
|
||||
super(cmd, status, result);
|
||||
}
|
||||
|
||||
public String getVolumeUuid() {
|
||||
return this.volumeUuid;
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
}
|
||||
@ -15,21 +15,58 @@
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.storage.db;
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.Event;
|
||||
import org.apache.cloudstack.storage.volume.ObjectInDataStoreStateMachine.State;
|
||||
import org.apache.cloudstack.storage.volume.db.VolumeVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria2;
|
||||
import com.cloud.utils.db.SearchCriteriaService;
|
||||
import com.cloud.utils.db.UpdateBuilder;
|
||||
|
||||
@Component
|
||||
public class ObjectInDataStoreDaoImpl extends GenericDaoBase<ObjectInDataStoreVO, Long> implements ObjectInDataStoreDao {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(ObjectInDataStoreDaoImpl.class);
|
||||
@Override
|
||||
public boolean updateState(State currentState, Event event,
|
||||
State nextState, ObjectInDataStoreVO vo, Object data) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
Long oldUpdated = vo.getUpdatedCount();
|
||||
Date oldUpdatedTime = vo.getUpdated();
|
||||
|
||||
SearchCriteria<ObjectInDataStoreVO> sc = this.createSearchCriteria();
|
||||
sc.setParameters("id", vo.getId());
|
||||
sc.setParameters("state", currentState);
|
||||
sc.setParameters("updatedCount", vo.getUpdatedCount());
|
||||
|
||||
vo.incrUpdatedCount();
|
||||
|
||||
UpdateBuilder builder = getUpdateBuilder(vo);
|
||||
builder.set(vo, "state", nextState);
|
||||
builder.set(vo, "updated", new Date());
|
||||
|
||||
int rows = update((ObjectInDataStoreVO) vo, sc);
|
||||
if (rows == 0 && s_logger.isDebugEnabled()) {
|
||||
ObjectInDataStoreVO dbVol = findByIdIncludingRemoved(vo.getId());
|
||||
if (dbVol != null) {
|
||||
StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
|
||||
str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=")
|
||||
.append(dbVol.getUpdated());
|
||||
str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount())
|
||||
.append("; updatedTime=").append(vo.getUpdated());
|
||||
str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated)
|
||||
.append("; updatedTime=").append(oldUpdatedTime);
|
||||
} else {
|
||||
s_logger.debug("Unable to update objectIndatastore: id=" + vo.getId() + ", as there is no such object exists in the database anymore");
|
||||
}
|
||||
}
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
|
||||
@Enumerated(EnumType.STRING)
|
||||
private DataStoreRole dataStoreRole;
|
||||
|
||||
@Column(name = "ojbect_id")
|
||||
@Column(name = "object_id")
|
||||
long objectId;
|
||||
|
||||
@Column(name = "object_type")
|
||||
@ -85,7 +85,7 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
|
||||
String installPath;
|
||||
|
||||
@Column(name = "size")
|
||||
long size;
|
||||
Long size;
|
||||
|
||||
@Column(name = "state")
|
||||
@Enumerated(EnumType.STRING)
|
||||
@ -94,6 +94,10 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
|
||||
@Column(name="update_count", updatable = true, nullable=false)
|
||||
protected long updatedCount;
|
||||
|
||||
@Column(name = "updated")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
Date updated;
|
||||
|
||||
public ObjectInDataStoreVO() {
|
||||
this.state = ObjectInDataStoreStateMachine.State.Allocated;
|
||||
}
|
||||
@ -146,4 +150,32 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
|
||||
public String getInstallPath() {
|
||||
return this.installPath;
|
||||
}
|
||||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public long getUpdatedCount() {
|
||||
return this.updatedCount;
|
||||
}
|
||||
|
||||
public void incrUpdatedCount() {
|
||||
this.updatedCount++;
|
||||
}
|
||||
|
||||
public void decrUpdatedCount() {
|
||||
this.updatedCount--;
|
||||
}
|
||||
|
||||
public Date getUpdated() {
|
||||
return updated;
|
||||
}
|
||||
|
||||
public void setUpdated(Date updated) {
|
||||
this.updated = updated;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +165,11 @@ public class DefaultEndPointSelector implements EndPointSelector {
|
||||
DataStore store = object.getDataStore();
|
||||
if (store.getRole() == DataStoreRole.Primary) {
|
||||
return findEndpointForPrimaryStorage(store);
|
||||
} else {
|
||||
} else if (store.getRole() == DataStoreRole.Image) {
|
||||
//in case there is no ssvm, directly send down command hypervisor host
|
||||
//TODO: add code to handle in case ssvm is there
|
||||
return findEndpointForPrimaryStorage(store);
|
||||
}else {
|
||||
throw new CloudRuntimeException("not implemented yet");
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
|
||||
import org.apache.cloudstack.storage.image.db.ImageDataStoreDao;
|
||||
import org.apache.cloudstack.storage.image.db.ImageDataStoreVO;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -33,10 +34,16 @@ public class ImageDataStoreHelper {
|
||||
@Inject
|
||||
ImageDataStoreDao imageStoreDao;
|
||||
public ImageDataStoreVO createImageDataStore(Map<String, String> params) {
|
||||
ImageDataStoreVO store = new ImageDataStoreVO();
|
||||
ImageDataStoreVO store = imageStoreDao.findByUuid(params.get("uuid"));
|
||||
if (store != null) {
|
||||
throw new CloudRuntimeException("duplicate uuid");
|
||||
}
|
||||
store = new ImageDataStoreVO();
|
||||
store.setName(params.get("name"));
|
||||
store.setProtocol(params.get("protocol"));
|
||||
store.setProvider(Long.parseLong(params.get("provider")));
|
||||
store.setScope(Enum.valueOf(ScopeType.class, params.get("scope")));
|
||||
store.setUuid(params.get("uuid"));
|
||||
store = imageStoreDao.persist(store);
|
||||
return store;
|
||||
}
|
||||
|
||||
@ -20,10 +20,14 @@ package org.apache.cloudstack.storage.image.db;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.TableGenerator;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
|
||||
|
||||
@Entity
|
||||
@Table(name = "image_data_store")
|
||||
public class ImageDataStoreVO {
|
||||
@ -35,6 +39,9 @@ public class ImageDataStoreVO {
|
||||
@Column(name = "name", nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "uuid", nullable = false)
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "protocol", nullable = false)
|
||||
private String protocol;
|
||||
|
||||
@ -44,6 +51,11 @@ public class ImageDataStoreVO {
|
||||
@Column(name = "data_center_id")
|
||||
private long dcId;
|
||||
|
||||
@Column(name = "scope")
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
private ScopeType scope;
|
||||
|
||||
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
@ -79,4 +91,20 @@ public class ImageDataStoreVO {
|
||||
public long getDcId() {
|
||||
return this.dcId;
|
||||
}
|
||||
|
||||
public ScopeType getScope() {
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
public void setScope(ScopeType scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ public class ImageDataVO implements Identity, StateObject<TemplateState> {
|
||||
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
@Column(name = GenericDao.CREATED_COLUMN)
|
||||
private final Date created = null;
|
||||
private Date created = null;
|
||||
|
||||
@Column(name = GenericDao.REMOVED)
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@ -155,6 +155,7 @@ public class ImageDataVO implements Identity, StateObject<TemplateState> {
|
||||
public ImageDataVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.state = TemplateState.Allocated;
|
||||
this.created = new Date();
|
||||
}
|
||||
|
||||
public boolean getEnablePassword() {
|
||||
|
||||
@ -30,7 +30,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectCommand;
|
||||
import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
||||
import org.apache.cloudstack.storage.command.DeleteCommand;
|
||||
import org.apache.cloudstack.storage.endpoint.EndPointSelector;
|
||||
import org.apache.cloudstack.storage.snapshot.SnapshotInfo;
|
||||
@ -70,11 +70,11 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
||||
|
||||
public Void createAsyncCallback(AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> callback, CreateVolumeContext<CreateCmdResult> context) {
|
||||
CreateCmdResult result = null;
|
||||
CreateVolumeAnswer volAnswer = (CreateVolumeAnswer) callback.getResult();
|
||||
CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult();
|
||||
if (volAnswer.getResult()) {
|
||||
result = new CreateCmdResult(volAnswer.getVolumeUuid());
|
||||
result = new CreateCmdResult(volAnswer.getPath(), volAnswer.getSize());
|
||||
} else {
|
||||
result = new CreateCmdResult("");
|
||||
result = new CreateCmdResult("", null);
|
||||
result.setResult(volAnswer.getDetails());
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ public class VolumeObject implements VolumeInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
public Long getSize() {
|
||||
return volumeVO.getSize();
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ import org.apache.cloudstack.storage.command.CopyCmd;
|
||||
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectCommand;
|
||||
import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd;
|
||||
import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
||||
import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand;
|
||||
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
|
||||
import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol;
|
||||
@ -130,7 +130,12 @@ public class XenServerStorageResource {
|
||||
return params;
|
||||
}
|
||||
|
||||
protected CreateVolumeAnswer execute(CreateObjectCommand cmd) {
|
||||
protected CreateObjectAnswer getTemplateSize(CreateObjectCommand cmd, String templateUrl) {
|
||||
Connection conn = hypervisorResource.getConnection();
|
||||
long size = this.getTemplateSize(conn, templateUrl);
|
||||
return new CreateObjectAnswer(cmd, templateUrl, size);
|
||||
}
|
||||
protected CreateObjectAnswer execute(CreateObjectCommand cmd) {
|
||||
String uriString = cmd.getObjectUri();
|
||||
Map<String, String> params = null;
|
||||
|
||||
@ -139,7 +144,11 @@ public class XenServerStorageResource {
|
||||
params = getParameters(uri);
|
||||
} catch (URISyntaxException e1) {
|
||||
s_logger.debug("uri exception", e1);
|
||||
return new CreateVolumeAnswer(cmd, false, e1.toString());
|
||||
return new CreateObjectAnswer(cmd, false, e1.toString());
|
||||
}
|
||||
|
||||
if (params.get("objType").equalsIgnoreCase("template")) {
|
||||
return getTemplateSize(cmd, params.get("path"));
|
||||
}
|
||||
|
||||
long size = Long.parseLong(params.get("size"));
|
||||
@ -154,7 +163,7 @@ public class XenServerStorageResource {
|
||||
vdi = createVdi(conn, name, primaryDataStoreSR, size);
|
||||
VDI.Record record = vdi.getRecord(conn);
|
||||
result = true;
|
||||
return new CreateVolumeAnswer(cmd, record.uuid);
|
||||
return new CreateObjectAnswer(cmd, record.uuid, record.virtualSize);
|
||||
} catch (BadServerResponse e) {
|
||||
s_logger.debug("Failed to create volume", e);
|
||||
errorMsg = e.toString();
|
||||
@ -174,7 +183,7 @@ public class XenServerStorageResource {
|
||||
}
|
||||
}
|
||||
|
||||
return new CreateVolumeAnswer(cmd, false, errorMsg);
|
||||
return new CreateObjectAnswer(cmd, false, errorMsg);
|
||||
}
|
||||
|
||||
protected Answer execute(DeleteVolumeCommand cmd) {
|
||||
@ -208,7 +217,7 @@ public class XenServerStorageResource {
|
||||
VDI baseVdi = VDI.getByUuid(conn, baseImage.getPathOnPrimaryDataStore());
|
||||
VDI newVol = baseVdi.createClone(conn, new HashMap<String, String>());
|
||||
newVol.setNameLabel(conn, volume.getName());
|
||||
return new CreateVolumeAnswer(cmd, newVol.getUuid(conn));
|
||||
return new CreateObjectAnswer(cmd, newVol.getUuid(conn), newVol.getVirtualSize(conn));
|
||||
} catch (BadServerResponse e) {
|
||||
return new Answer(cmd, false, e.toString());
|
||||
} catch (XenAPIException e) {
|
||||
@ -579,7 +588,7 @@ public class XenServerStorageResource {
|
||||
params = getParameters(uri);
|
||||
} catch (URISyntaxException e1) {
|
||||
s_logger.debug("uri exception", e1);
|
||||
return new CreateVolumeAnswer(cmd, false, e1.toString());
|
||||
return new CreateObjectAnswer(cmd, false, e1.toString());
|
||||
}
|
||||
SR sr = hypervisorResource.getStorageRepository(conn, params.get("storeUuid"));
|
||||
hypervisorResource.setupHeartbeatSr(conn, sr, false);
|
||||
|
||||
@ -26,7 +26,7 @@ import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
||||
import org.apache.cloudstack.storage.command.CreateVolumeAnswer;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
||||
import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.provider.PrimaryDataStoreProvider;
|
||||
@ -112,7 +112,7 @@ public class VolumeTest {
|
||||
results.add(host);
|
||||
Mockito.when(hostDao.listAll()).thenReturn(results);
|
||||
Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results);
|
||||
CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(null,UUID.randomUUID().toString());
|
||||
CreateObjectAnswer createVolumeFromImageAnswer = new CreateObjectAnswer(null,UUID.randomUUID().toString());
|
||||
|
||||
try {
|
||||
Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(CreateVolumeFromBaseImageCommand.class))).thenReturn(createVolumeFromImageAnswer);
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
-- under the License.
|
||||
|
||||
alter table vm_template add image_data_store_id bigint unsigned;
|
||||
alter table vm_template add size bigint unsigned;
|
||||
alter table vm_template add state varchar(255);
|
||||
alter table storage_pool add storage_provider_id bigint unsigned;
|
||||
alter table storage_pool add scope varchar(255);
|
||||
alter table storage_pool modify id bigint unsigned AUTO_INCREMENT UNIQUE NOT NULL;
|
||||
@ -48,6 +50,26 @@ alter table cluster add column owner varchar(255);
|
||||
alter table cluster add column created datetime COMMENT 'date created';
|
||||
alter table cluster add column lastUpdated datetime COMMENT 'last updated';
|
||||
alter table cluster add column engine_state varchar(32) NOT NULL DEFAULT 'Disabled' COMMENT 'the engine state of the zone';
|
||||
CREATE TABLE `cloud`.`object_datastore_ref` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`datastore_id` bigint unsigned NOT NULL,
|
||||
`datastore_role` varchar(255) NOT NULL,
|
||||
`object_id` bigint unsigned NOT NULL,
|
||||
`object_type` varchar(255) NOT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
`last_updated` DATETIME,
|
||||
`job_id` varchar(255),
|
||||
`download_pct` int(10) unsigned,
|
||||
`download_state` varchar(255),
|
||||
`error_str` varchar(255),
|
||||
`local_path` varchar(255),
|
||||
`install_path` varchar(255),
|
||||
`size` bigint unsigned COMMENT 'the size of the template on the pool',
|
||||
`state` varchar(255) NOT NULL,
|
||||
`update_count` bigint unsigned NOT NULL,
|
||||
`updated` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`data_store_provider` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
@ -56,18 +78,16 @@ CREATE TABLE `cloud`.`data_store_provider` (
|
||||
PRIMARY KEY(`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`image_data_store_provider` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`name` varchar(255) NOT NULL COMMENT 'name of data store provider',
|
||||
PRIMARY KEY(`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`image_data_store` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`name` varchar(255) NOT NULL COMMENT 'name of data store',
|
||||
`image_provider_id` bigint unsigned NOT NULL COMMENT 'id of image_data_store_provider',
|
||||
`protocol` varchar(255) NOT NULL COMMENT 'protocol of data store',
|
||||
`data_center_id` bigint unsigned COMMENT 'datacenter id of data store',
|
||||
`scope` varchar(255) COMMENT 'scope of data store',
|
||||
`uuid` varchar(255) COMMENT 'uuid of data store',
|
||||
PRIMARY KEY(`id`),
|
||||
CONSTRAINT `fk_tags__image_data_store_provider_id` FOREIGN KEY(`image_provider_id`) REFERENCES `image_data_store_provider`(`id`)
|
||||
CONSTRAINT `fk_tags__image_data_store_provider_id` FOREIGN KEY(`image_provider_id`) REFERENCES `data_store_provider`(`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`vm_compute_tags` (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user