diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java index f75662659ce..c818522d337 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; @@ -35,7 +36,7 @@ public interface PrimaryDataStoreInfo { public long getId(); public String getUuid(); - public Volume.State getManagedState(); + public DataCenterResourceEntity.State getManagedState(); public String getName(); public String getType(); public PrimaryDataStoreLifeCycle getLifeCycle(); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index 0370d204ef1..347ae6ce1a1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -32,7 +32,7 @@ public interface VolumeInfo { public String getPath(); public PrimaryDataStoreInfo getDataStore() ; public String getTemplateUuid(); - public String getTemplatePath() ; + public String getTemplatePath(); public VolumeType getType(); public VolumeDiskType getDiskType(); public long getId(); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java index 6eef23d16bc..68ad317655e 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java @@ -91,4 +91,16 @@ public class ImageDataStoreImpl implements ImageDataStore { return to; } + @Override + public String getType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getUri() { + // TODO Auto-generated method stub + return null; + } + } diff --git a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java index 8ebe8fdb017..f9c03889668 100644 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java +++ b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java @@ -23,7 +23,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackHandler; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.EndPoint; import org.apache.cloudstack.storage.command.CommandResult; -import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorage; +import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageCmd; import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; @@ -48,7 +48,7 @@ public class DefaultImageMotionStrategy implements ImageMotionStrategy { @Override public boolean copyTemplate(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep) { ImageOnPrimayDataStoreTO imageTo = new ImageOnPrimayDataStoreTO(templateStore); - CopyTemplateToPrimaryStorage copyCommand = new CopyTemplateToPrimaryStorage(imageTo); + CopyTemplateToPrimaryStorageCmd copyCommand = new CopyTemplateToPrimaryStorageCmd(imageTo); ep.sendMessage(copyCommand); return true; } @@ -56,7 +56,7 @@ public class DefaultImageMotionStrategy implements ImageMotionStrategy { @Override public void copyTemplateAsync(TemplateOnPrimaryDataStoreInfo templateStore, EndPoint ep, AsyncCompletionCallback callback) { ImageOnPrimayDataStoreTO imageTo = new ImageOnPrimayDataStoreTO(templateStore); - CopyTemplateToPrimaryStorage copyCommand = new CopyTemplateToPrimaryStorage(imageTo); + CopyTemplateToPrimaryStorageCmd copyCommand = new CopyTemplateToPrimaryStorageCmd(imageTo); AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this).setParentCallback(callback) .setOperationName("defaultImageStrategy.copytemplate.callback") .setContextParam("templateStore", templateStore); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java index 6142c3e13d0..35b5bb1edd6 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.HostEndpointRpcServer; -import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorage; +import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageCmd; import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer; import org.apache.cloudstack.storage.command.CreateVolumeAnswer; import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; @@ -50,7 +50,7 @@ public class MockHypervsiorHostEndPointRpcServer implements HostEndpointRpcServe public void run() { try { Answer answer = new Answer(cmd, false, "unknown command"); - if (cmd instanceof CopyTemplateToPrimaryStorage) { + if (cmd instanceof CopyTemplateToPrimaryStorageCmd) { answer = new CopyTemplateToPrimaryStorageAnswer(cmd, UUID.randomUUID().toString()); } else if (cmd instanceof CreateVolumeFromBaseImageCommand) { answer = new CreateVolumeAnswer(cmd, UUID.randomUUID().toString()); diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorage.java b/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageCmd.java similarity index 56% rename from engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorage.java rename to engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageCmd.java index d092e9e320c..dd2030d95ec 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorage.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageCmd.java @@ -1,23 +1,25 @@ 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; import com.cloud.agent.api.Command; -public class CopyTemplateToPrimaryStorage extends Command { +public class CopyTemplateToPrimaryStorageCmd extends Command implements StorageSubSystemCommand { private ImageOnPrimayDataStoreTO imageTO; - protected CopyTemplateToPrimaryStorage() { + protected CopyTemplateToPrimaryStorageCmd() { super(); } - public CopyTemplateToPrimaryStorage(ImageOnPrimayDataStoreTO image) { + public CopyTemplateToPrimaryStorageCmd(ImageOnPrimayDataStoreTO image) { super(); this.imageTO = image; } + + public ImageOnPrimayDataStoreTO getImage() { + return this.imageTO; + } @Override public boolean executeInSequence() { diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java index 0042c9504f2..4780e00d00c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java @@ -23,14 +23,22 @@ 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 class CreateVolumeFromBaseImageCommand extends Command implements StorageSubSystemCommand { + private final VolumeTO volume; + private final ImageOnPrimayDataStoreTO image; public CreateVolumeFromBaseImageCommand(VolumeTO volume, ImageOnPrimayDataStoreTO image) { this.volume = volume; this.image = image; } + + public VolumeTO getVolume() { + return this.volume; + } + + public ImageOnPrimayDataStoreTO getImage() { + return this.image; + } @Override public boolean executeInSequence() { diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java b/engine/storage/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java new file mode 100644 index 00000000000..d14161ae4c5 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java @@ -0,0 +1,23 @@ +/* + * 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; + +public interface StorageSubSystemCommand { + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateInfo.java b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateInfo.java index 0e11f3eb358..71e6e3acc3a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateInfo.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateInfo.java @@ -31,4 +31,6 @@ public interface TemplateInfo { String getPath(); String getUuid(); + + long getVirtualSize(); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/store/ImageDataStoreInfo.java b/engine/storage/src/org/apache/cloudstack/storage/image/store/ImageDataStoreInfo.java index a5d3d0f7eba..17564773ef1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/store/ImageDataStoreInfo.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/store/ImageDataStoreInfo.java @@ -20,4 +20,6 @@ package org.apache.cloudstack.storage.image.store; public interface ImageDataStoreInfo { public long getImageDataStoreId(); + public String getType(); + public String getUri(); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java index ca1e9b7426c..9fd335ab9ce 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java @@ -3,7 +3,18 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.storage.image.store.ImageDataStoreInfo; public class ImageDataStoreTO { + private final String type; + private final String uri; public ImageDataStoreTO(ImageDataStoreInfo dataStore) { - + this.type = dataStore.getType(); + this.uri = dataStore.getUri(); + } + + public String getType() { + return this.type; + } + + public String getUri() { + return this.uri; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java index cc31bc7dcf5..4c040f4f34f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java @@ -21,7 +21,24 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; public class ImageOnPrimayDataStoreTO { + private final String pathOnPrimaryDataStore; + private final PrimaryDataStoreTO dataStore; + private final TemplateTO template; public ImageOnPrimayDataStoreTO(TemplateOnPrimaryDataStoreInfo template) { - + this.pathOnPrimaryDataStore = template.getPath(); + this.dataStore = new PrimaryDataStoreTO(template.getPrimaryDataStore()); + this.template = new TemplateTO(template.getTemplate()); + } + + public String getPathOnPrimaryDataStore() { + return this.pathOnPrimaryDataStore; + } + + public PrimaryDataStoreTO getPrimaryDataStore() { + return this.dataStore; + } + + public TemplateTO getTemplate() { + return this.template; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java index bd97dda9651..77086211738 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java @@ -3,7 +3,24 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; public class PrimaryDataStoreTO { + private final String uuid; + private final String name; + private final String type; public PrimaryDataStoreTO(PrimaryDataStoreInfo dataStore) { - + this.uuid = dataStore.getUuid(); + this.name = dataStore.getName(); + this.type = dataStore.getType(); + } + + public String getUuid() { + return this.uuid; + } + + public String getName() { + return this.name; + } + + public String getType() { + return this.type; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java index d5f9d09c9f3..704f36ea169 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java @@ -1,9 +1,39 @@ package org.apache.cloudstack.storage.to; +import org.apache.cloudstack.engine.subsystem.api.storage.disktype.VolumeDiskType; import org.apache.cloudstack.storage.image.TemplateInfo; public class TemplateTO { + private final String path; + private final String uuid; + private final VolumeDiskType diskType; + private final ImageDataStoreTO imageDataStore; + private final long size; public TemplateTO(TemplateInfo template) { - + this.path = template.getPath(); + this.uuid = template.getUuid(); + this.diskType = template.getDiskType(); + this.imageDataStore = new ImageDataStoreTO(template.getImageDataStore()); + this.size = template.getVirtualSize(); + } + + public String getPath() { + return this.path; + } + + public String getUuid() { + return this.uuid; + } + + public VolumeDiskType getDiskType() { + return this.diskType; + } + + public ImageDataStoreTO getImageDataStore() { + return this.imageDataStore; + } + + public long getSize() { + return this.size; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java index eff22f0191a..d507eb47a91 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java @@ -1,9 +1,40 @@ package org.apache.cloudstack.storage.to; 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; public class VolumeTO { + private final String uuid; + private final String path; + private final VolumeType volumeType; + private final VolumeDiskType diskType; + private final PrimaryDataStoreTO dataStore; public VolumeTO(VolumeInfo volume) { - + this.uuid = volume.getUuid(); + this.path = volume.getPath(); + this.volumeType = volume.getType(); + this.diskType = volume.getDiskType(); + this.dataStore = new PrimaryDataStoreTO(volume.getDataStore()); + } + + public String getUuid() { + return this.uuid; + } + + public String getPath() { + return this.path; + } + + public VolumeType getVolumeType() { + return this.volumeType; + } + + public VolumeDiskType getDiskType() { + return this.diskType; + } + + public PrimaryDataStoreTO getDataStore() { + return this.dataStore; } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java index 267e977c766..a9781e1f42e 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java @@ -5,6 +5,7 @@ import java.util.List; import javax.inject.Inject; +import org.apache.cloudstack.engine.datacenter.entity.api.DataCenterResourceEntity; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; @@ -196,14 +197,14 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { public void createVoluemFromBaseImageAsync(VolumeInfo volume, TemplateOnPrimaryDataStoreInfo templateStore, AsyncCompletionCallback callback) { VolumeObject vo = (VolumeObject) volume; vo.setVolumeDiskType(templateStore.getTemplate().getDiskType()); - AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this) - .setParentCallback(callback) + AsyncCallbackDispatcher caller = new AsyncCallbackDispatcher(this); + caller.setCallback(caller.getTarget().createVoluemFromBaseImageAsyncCallback(null, null)) .setOperationName("primarydatastore.createvolumefrombaseImage"); this.driver.createVolumeFromBaseImageAsync(vo, templateStore, caller); } @AsyncCallbackHandler(operationName="primarydatastore.createvolumefrombaseImage") - public void createVoluemFromBaseImageAsyncCallback(AsyncCallbackDispatcher callback) { + public Object createVoluemFromBaseImageAsyncCallback(AsyncCallbackDispatcher callback, Object parames) { AsyncCallbackDispatcher parent = callback.getParentCallback(); CommandResult result = callback.getResult(); parent.complete(result); @@ -222,7 +223,7 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { } @Override - public Volume.State getManagedState() { + public DataCenterResourceEntity.State getManagedState() { // TODO Auto-generated method stub return null; } diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java index fff6eadb384..d5190719733 100644 --- a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java +++ b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java @@ -18,9 +18,8 @@ */ package org.apache.cloudstack.storage.volume.test; -import org.apache.cloudstack.storage.HostEndpointRpcServer; import org.apache.cloudstack.storage.image.motion.ImageMotionService; -import org.apache.cloudstack.storage.test.MockHypervsiorHostEndPointRpcServer; + import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -40,9 +39,4 @@ public class TestConfiguration { public ClusterDao clusterDao() { return Mockito.mock(ClusterDaoImpl.class); } - - @Bean - public HostEndpointRpcServer rpcServer() { - return new MockHypervsiorHostEndPointRpcServer(); - } } \ No newline at end of file diff --git a/plugins/hypervisors/xen/pom.xml b/plugins/hypervisors/xen/pom.xml index 959c972e080..0a57afca284 100644 --- a/plugins/hypervisors/xen/pom.xml +++ b/plugins/hypervisors/xen/pom.xml @@ -1,22 +1,15 @@ - - + + 4.0.0 cloud-plugin-hypervisor-xen Apache CloudStack Plugin - Hypervisor Xen @@ -27,11 +20,22 @@ ../../pom.xml + + org.apache.cloudstack + cloud-engine-storage + ${project.version} + org.apache.cloudstack cloud-plugin-network-ovs ${project.version} + + org.apache.httpcomponents + httpclient + 4.2.2 + compile + org.apache.cloudstack xapi @@ -42,6 +46,6 @@ junit - + diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index d2db85c8597..a0066c88fc9 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -176,6 +176,7 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.storage.StorageCommand; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; @@ -305,6 +306,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected boolean _canBridgeFirewall = false; protected boolean _isOvs = false; protected List _tmpDom0Vif = new ArrayList(); + protected XenServerStorageResource storageResource; public enum SRType { NFS, LVM, ISCSI, ISO, LVMOISCSI, LVMOHBA, EXT, FILE; @@ -557,6 +559,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((Site2SiteVpnCfgCommand) cmd); } else if (clazz == CheckS2SVpnConnectionsCommand.class) { return execute((CheckS2SVpnConnectionsCommand) cmd); + } else if (clazz == StorageCommand.class) { + return this.storageResource.handleStorageCommands((StorageCommand)cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -5528,9 +5532,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } CheckXenHostInfo(); + + this.storageResource = getStorageResource(); return true; } + + protected XenServerStorageResource getStorageResource() { + return new XenServerStorageResource(this); + } private void CheckXenHostInfo() throws ConfigurationException { Connection conn = _connPool.slaveConnect(_host.ip, _username, _password); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java new file mode 100644 index 00000000000..b80b5d923c0 --- /dev/null +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -0,0 +1,187 @@ +/* + * 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 com.cloud.hypervisor.xen.resource; + +import java.io.IOException; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageCmd; +import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.ImageDataStoreTO; +import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.TemplateTO; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; +import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.PBD; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.BadServerResponse; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VDI; + +public class XenServerStorageResource { + private static final Logger s_logger = Logger.getLogger(XenServerStorageResource.class); + protected CitrixResourceBase hypervisorResource; + + public XenServerStorageResource(CitrixResourceBase resource) { + this.hypervisorResource = resource; + } + + public Answer handleStorageCommands(StorageSubSystemCommand command) { + if (command instanceof CopyTemplateToPrimaryStorageCmd) { + return this.execute((CopyTemplateToPrimaryStorageCmd)command); + } + return new Answer((Command)command, false, "not implemented yet"); + } + + private long getTemplateSize(String url) { + HttpGet method = new HttpGet(url); + HttpClient client = new HttpClient(); + try { + int responseCode = client.executeMethod(method); + if (responseCode != HttpStatus.SC_OK) { + throw new CloudRuntimeException("http get returns error code:" + responseCode); + } + method.get + } catch (HttpException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + protected Answer directDownloadHttpTemplate(TemplateTO template, PrimaryDataStoreTO primarDataStore) { + String primaryStoreUuid = primarDataStore.getUuid(); + Connection conn = hypervisorResource.getConnection(); + SR poolsr = null; + VDI vdi = null; + try { + + Set srs = SR.getByNameLabel(conn, primaryStoreUuid); + if (srs.size() != 1) { + throw new CloudRuntimeException("storage uuid: " + primaryStoreUuid + " is not unique"); + } + poolsr = srs.iterator().next(); + VDI.Record vdir = new VDI.Record(); + vdir.nameLabel = "Base-Image-" + UUID.randomUUID().toString(); + vdir.SR = poolsr; + vdir.type = Types.VdiType.USER; + + vdir.virtualSize = template.getSize(); + vdi = VDI.create(conn, vdir); + + vdir = vdi.getRecord(conn); + String vdiLocation = vdir.location; + Set pbds = poolsr.getPBDs(conn); + if (pbds.size() != 1) { + throw new CloudRuntimeException("Don't how to handle multiple pbds:" + pbds.size() + " for sr: " + poolsr.getUuid(conn)); + } + PBD pbd = pbds.iterator().next(); + PBD.Record pbdRec = pbd.getRecord(conn); + Map deviceCfg = pbd.getDeviceConfig(conn); + String pbdLocation = deviceCfg.get("location"); + if (pbdLocation == null) { + throw new CloudRuntimeException("Can't get pbd: " + pbd.getUuid(conn) + " location"); + } + + String vdiPath = pbdLocation + "/" + vdiLocation; + //download a url into vdipath + + } catch (BadServerResponse e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (XenAPIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (XmlRpcException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + protected Answer execute(CopyTemplateToPrimaryStorageCmd cmd) { + ImageOnPrimayDataStoreTO imageTO = cmd.getImage(); + TemplateTO template = imageTO.getTemplate(); + ImageDataStoreTO imageStore = template.getImageDataStore(); + if (imageStore.getType().equalsIgnoreCase("http")) { + return directDownloadHttpTemplate(template, imageTO.getPrimaryDataStore()); + } else { + return new Answer(cmd, false, "not implemented yet"); + /* + String tmplturl = cmd.getUrl(); + String poolName = cmd.getPoolUuid(); + int wait = cmd.getWait(); + try { + URI uri = new URI(tmplturl); + String tmplpath = uri.getHost() + ":" + uri.getPath(); + Connection conn = hypervisorResource.getConnection(); + SR poolsr = null; + Set srs = SR.getByNameLabel(conn, poolName); + if (srs.size() != 1) { + String msg = "There are " + srs.size() + " SRs with same name: " + poolName; + s_logger.warn(msg); + return new PrimaryStorageDownloadAnswer(msg); + } else { + poolsr = srs.iterator().next(); + } + String pUuid = poolsr.getUuid(conn); + boolean isISCSI = IsISCSI(poolsr.getType(conn)); + String uuid = copy_vhd_from_secondarystorage(conn, tmplpath, pUuid, wait); + VDI tmpl = getVDIbyUuid(conn, uuid); + VDI snapshotvdi = tmpl.snapshot(conn, new HashMap()); + String snapshotUuid = snapshotvdi.getUuid(conn); + snapshotvdi.setNameLabel(conn, "Template " + cmd.getName()); + String parentuuid = getVhdParent(conn, pUuid, snapshotUuid, isISCSI); + VDI parent = getVDIbyUuid(conn, parentuuid); + Long phySize = parent.getPhysicalUtilisation(conn); + tmpl.destroy(conn); + poolsr.scan(conn); + try{ + Thread.sleep(5000); + } catch (Exception e) { + } + return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize); + } catch (Exception e) { + String msg = "Catch Exception " + e.getClass().getName() + " on host:" + _host.uuid + " for template: " + + tmplturl + " due to " + e.toString(); + s_logger.warn(msg, e); + return new PrimaryStorageDownloadAnswer(msg); + }*/ + } + + } +}