You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/04/11 20:01:50 UTC
[2/3] git commit: updated refs/heads/object_store to 1c448cd
add cache storage
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e5bf38ed
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e5bf38ed
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e5bf38ed
Branch: refs/heads/object_store
Commit: e5bf38ed051df248e5aaa5e362679fbaf368d2e0
Parents: dcbeea0
Author: Edison Su <ed...@citrix.com>
Authored: Wed Apr 10 23:36:39 2013 -0700
Committer: Edison Su <ed...@citrix.com>
Committed: Thu Apr 11 10:52:53 2013 -0700
----------------------------------------------------------------------
api/src/com/cloud/storage/StorageService.java | 3 +
.../command/admin/storage/CreateCacheStoreCmd.java | 123 +++
.../subsystem/api/storage/DataMotionService.java | 26 +
.../subsystem/api/storage/DataMotionStrategy.java | 28 +
.../subsystem/api/storage/DataStoreManager.java | 1 +
.../subsystem/api/storage/DataStoreProvider.java | 3 +-
.../api/storage/DataStoreProviderManager.java | 1 +
.../subsystem/api/storage/StorageCacheManager.java | 24 +
.../storage/datastore/db/ImageStoreVO.java | 14 +
engine/pom.xml | 4 +-
engine/storage/backup/pom.xml | 50 -
.../storage/backup/BackupMotionService.java | 23 -
.../cloudstack/storage/backup/BackupService.java | 26 -
engine/storage/cache/pom.xml | 50 +
.../cache/allocator/StorageCacheAllocator.java | 26 +
.../allocator/StorageCacheRandomAllocator.java | 51 +
.../cache/manager/StorageCacheManagerImpl.java | 100 ++
engine/storage/datamotion/pom.xml | 62 ++
.../storage/motion/AncientDataMotionStrategy.java | 726 +++++++++++++++
.../storage/motion/DataMotionDriver.java | 25 +
.../storage/motion/DataMotionServiceImpl.java | 63 ++
.../manager/ImageStoreProviderManagerImpl.java | 24 +
engine/storage/imagemotion/pom.xml | 62 --
.../image/motion/DefaultImageMotionStrategy.java | 140 ---
.../image/motion/ImageMotionServiceImpl.java | 70 --
.../storage/image/motion/ImageMotionStrategy.java | 24 -
.../storage/test/MockStorageMotionStrategy.java | 2 +-
.../snapshot/strategy/AncientSnapshotStrategy.java | 13 +-
.../storage/datastore/DataObjectManagerImpl.java | 2 +-
.../storage/datastore/DataStoreManagerImpl.java | 7 +-
.../datastore/ObjectInDataStoreManagerImpl.java | 4 -
.../provider/DataStoreProviderManagerImpl.java | 27 +-
.../storage/image/datastore/ImageStoreHelper.java | 3 +
.../image/datastore/ImageStoreProviderManager.java | 1 +
.../storage/motion/AncientDataMotionStrategy.java | 725 --------------
.../storage/motion/DataMotionDriver.java | 25 -
.../storage/motion/DataMotionService.java | 28 -
.../storage/motion/DataMotionServiceImpl.java | 61 --
.../storage/motion/DataMotionStrategy.java | 30 -
.../volume/TemplateInstallStrategyImpl.java | 2 +-
.../storage/volume/VolumeServiceImpl.java | 3 +-
.../provider/CloudStackImageStoreProviderImpl.java | 1 +
.../src/com/cloud/storage/StorageManagerImpl.java | 70 ++
tools/apidoc/gen_toc.py | 1 +
44 files changed, 1462 insertions(+), 1292 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/api/src/com/cloud/storage/StorageService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java
index ee1a956..869b296 100644
--- a/api/src/com/cloud/storage/StorageService.java
+++ b/api/src/com/cloud/storage/StorageService.java
@@ -20,6 +20,7 @@ import java.net.UnknownHostException;
import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.storage.CreateCacheStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
@@ -47,6 +48,8 @@ public interface StorageService{
*/
StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException,
UnknownHostException, ResourceUnavailableException;
+
+ ImageStore createCacheStore(CreateCacheStoreCmd cmd);
/**
* Delete the storage pool
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java
new file mode 100644
index 0000000..ff01a40
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.api.command.admin.storage;
+
+import java.util.Map;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.DiscoveryException;
+import com.cloud.storage.ImageStore;
+import com.cloud.user.Account;
+
+@APICommand(name = "createCacheStore", description="create cache store.", responseObject=ImageStoreResponse.class)
+public class CreateCacheStoreCmd extends BaseCmd {
+ public static final Logger s_logger = Logger.getLogger(AddImageStoreCmd.class.getName());
+ private static final String s_name = "createcachestoreresponse";
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required=true, description="the URL for the cache store")
+ private String url;
+
+ @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
+ description="the Zone ID for the image store")
+ private Long zoneId;
+
+
+ @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the image store")
+ private Map<String, String> details;
+
+ @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING,
+ required=false, description="the scope of the image store: zone only for now")
+ private String scope;
+
+ @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING,
+ required=false, description="the cache store provider name")
+ private String providerName;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public String getUrl() {
+ return url;
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public Map<String, String> getDetails() {
+ return details;
+ }
+
+ public String getScope() {
+ return this.scope;
+ }
+
+ public String getProviderName() {
+ return this.providerName;
+ }
+
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ try{
+ ImageStore result = _storageService.createCacheStore(this);
+ ImageStoreResponse storeResponse = null;
+ if (result != null ) {
+ storeResponse = _responseGenerator.createImageStoreResponse(result);
+ storeResponse.setResponseName(getCommandName());
+ storeResponse.setObjectName("secondarystorage");
+ this.setResponseObject(storeResponse);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage");
+ }
+ } catch (Exception ex) {
+ s_logger.warn("Exception: ", ex);
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
new file mode 100644
index 0000000..adeeecb
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
@@ -0,0 +1,26 @@
+/*
+ * 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.engine.subsystem.api.storage;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+public interface DataMotionService {
+ public void copyAsync(DataObject srcData, DataObject destData,
+ AsyncCompletionCallback<CopyCommandResult> callback);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
new file mode 100644
index 0000000..e2cc2a0
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
@@ -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.engine.subsystem.api.storage;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+public interface DataMotionStrategy {
+ public boolean canHandle(DataObject srcData, DataObject destData);
+
+ public Void copyAsync(DataObject srcData, DataObject destData,
+ AsyncCompletionCallback<CopyCommandResult> callback);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
index def3b96..1a36c8c 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
@@ -28,5 +28,6 @@ public interface DataStoreManager {
public DataStore getDataStore(String uuid, DataStoreRole role);
public List<DataStore> getImageStoresByScope(ZoneScope scope);
public List<DataStore> getImageStoresByProvider(String provider);
+ public List<DataStore> getImageCacheStores(Scope scope);
public DataStore registerDataStore(Map<String, String> params, String providerUuid);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
index 083c7d3..c0c1f76 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
@@ -27,7 +27,8 @@ import java.util.Set;
public interface DataStoreProvider {
public static enum DataStoreProviderType {
PRIMARY,
- IMAGE
+ IMAGE,
+ ImageCache
}
public DataStoreLifeCycle getDataStoreLifeCycle();
public DataStoreDriver getDataStoreDriver();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
index 8dd8c3a..6872bdf 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
@@ -27,6 +27,7 @@ public interface DataStoreProviderManager extends Manager, DataStoreProviderApiS
public DataStoreProvider getDataStoreProvider(String name);
public DataStoreProvider getDefaultPrimaryDataStoreProvider();
public DataStoreProvider getDefaultImageDataStoreProvider();
+ public DataStoreProvider getDefaultCacheDataStoreProvider();
public List<DataStoreProvider> getDataStoreProviders();
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
new file mode 100644
index 0000000..0fdec11
--- /dev/null
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
@@ -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.engine.subsystem.api.storage;
+
+
+public interface StorageCacheManager {
+ public DataStore getCacheStorage(Scope scope);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
index 7f95036..5503df0 100644
--- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
+++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
@@ -28,6 +28,8 @@ import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
+
import com.cloud.storage.ImageStore;
@@ -69,6 +71,18 @@ public class ImageStoreVO implements ImageStore {
@Column(name=GenericDao.REMOVED_COLUMN)
private Date removed;
+
+ @Column(name = "role")
+ @Enumerated(value = EnumType.STRING)
+ private DataStoreRole role;
+
+ public DataStoreRole getRole() {
+ return role;
+ }
+
+ public void setRole(DataStoreRole role) {
+ this.role = role;
+ }
public long getId() {
return this.id;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/pom.xml
----------------------------------------------------------------------
diff --git a/engine/pom.xml b/engine/pom.xml
index 1a3d896..3b686f2 100644
--- a/engine/pom.xml
+++ b/engine/pom.xml
@@ -39,8 +39,8 @@
<module>storage</module>
<module>storage/volume</module>
<module>storage/image</module>
- <module>storage/imagemotion</module>
- <module>storage/backup</module>
+ <module>storage/datamotion</module>
+ <module>storage/cache</module>
<module>storage/snapshot</module>
<module>storage/integration-test</module>
<module>components-api</module>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/backup/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/backup/pom.xml b/engine/storage/backup/pom.xml
deleted file mode 100644
index 019e09c..0000000
--- a/engine/storage/backup/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <artifactId>cloud-engine-storage-backup</artifactId>
- <name>Apache CloudStack Engine Storage Backup Component</name>
- <parent>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-engine</artifactId>
- <version>4.2.0-SNAPSHOT</version>
- <relativePath>../../pom.xml</relativePath>
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-engine-storage</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>${cs.mysql.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>1.9.5</version>
- </dependency>
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
- </dependency>
- </dependencies>
- <build>
- <defaultGoal>install</defaultGoal>
- <sourceDirectory>src</sourceDirectory>
- <testSourceDirectory>test</testSourceDirectory>
- </build>
-</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java
----------------------------------------------------------------------
diff --git a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java b/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java
deleted file mode 100644
index cb49027..0000000
--- a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.backup;
-
-public interface BackupMotionService {
- boolean copySnapshot(String snapshotUri, String destSnapshotUri);
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java
----------------------------------------------------------------------
diff --git a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java b/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java
deleted file mode 100644
index 67924d2..0000000
--- a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.backup;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-
-public interface BackupService {
- public boolean backupSnapshot(SnapshotInfo snapshot, long backupStoreId);
- public SnapshotOnBackupStoreInfo getSnapshot(long snapshotId);
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/cache/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml
new file mode 100644
index 0000000..f00f6cd
--- /dev/null
+++ b/engine/storage/cache/pom.xml
@@ -0,0 +1,50 @@
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>cloud-engine-storage-cache</artifactId>
+ <name>Apache CloudStack Engine Storage Cache Component</name>
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-engine</artifactId>
+ <version>4.2.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-engine-storage</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${cs.mysql.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.9.5</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <sourceDirectory>src</sourceDirectory>
+ <testSourceDirectory>test</testSourceDirectory>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
----------------------------------------------------------------------
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
new file mode 100644
index 0000000..4259d9e
--- /dev/null
+++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
@@ -0,0 +1,26 @@
+/*
+ * 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.cache.allocator;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+
+public interface StorageCacheAllocator {
+ DataStore getCacheStore(Scope scope);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
----------------------------------------------------------------------
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
new file mode 100644
index 0000000..c357d23
--- /dev/null
+++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
@@ -0,0 +1,51 @@
+/*
+ * 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.cache.allocator;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+
+import com.cloud.storage.ScopeType;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import edu.emory.mathcs.backport.java.util.Collections;
+
+public class StorageCacheRandomAllocator implements StorageCacheAllocator {
+ @Inject
+ DataStoreManager dataStoreMgr;
+ @Override
+ public DataStore getCacheStore(Scope scope) {
+ if (scope.getScopeType() != ScopeType.ZONE) {
+ throw new CloudRuntimeException("Can only support zone wide cache storage");
+ }
+
+ List<DataStore> cacheStores = dataStoreMgr.getImageCacheStores(scope);
+ if (cacheStores.size() <= 0) {
+ throw new CloudRuntimeException("Can't find cache storage in zone: " + scope.getScopeId());
+ }
+
+ Collections.shuffle(cacheStores);
+ return cacheStores.get(0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
new file mode 100644
index 0000000..c85565d
--- /dev/null
+++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
@@ -0,0 +1,100 @@
+/*
+ * 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.cache.manager;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
+import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator;
+
+import com.cloud.utils.component.Manager;
+
+public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
+ @Inject
+ List<StorageCacheAllocator> storageCacheAllocator;
+ @Override
+ public DataStore getCacheStorage(Scope scope) {
+ for (StorageCacheAllocator allocator : storageCacheAllocator) {
+ DataStore store = allocator.getCacheStore(scope);
+ if (store != null) {
+ return store;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setName(String name) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setConfigParams(Map<String, Object> params) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Map<String, Object> getConfigParams() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int getRunLevel() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void setRunLevel(int level) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/datamotion/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml
new file mode 100644
index 0000000..8a3698c
--- /dev/null
+++ b/engine/storage/datamotion/pom.xml
@@ -0,0 +1,62 @@
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>cloud-engine-storage-datamotion</artifactId>
+ <name>Apache CloudStack Engine Storage Data Motion Component</name>
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-engine</artifactId>
+ <version>4.2.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-engine-storage</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-engine-storage-volume</artifactId>
+ <version>${project.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-engine-storage-image</artifactId>
+ <version>${project.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${cs.mysql.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.9.5</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <sourceDirectory>src</sourceDirectory>
+ <testSourceDirectory>test</testSourceDirectory>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
new file mode 100644
index 0000000..1d164cd
--- /dev/null
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -0,0 +1,726 @@
+/*
+ * 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.motion;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.BackupSnapshotAnswer;
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VolumeHostVO;
+import com.cloud.storage.VolumeManager;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateHostDao;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeHostDao;
+import com.cloud.storage.s3.S3Manager;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.storage.swift.SwiftManager;
+import com.cloud.template.TemplateManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DiskProfile;
+
+@Component
+public class AncientDataMotionStrategy implements DataMotionStrategy {
+ private static final Logger s_logger = Logger
+ .getLogger(AncientDataMotionStrategy.class);
+ @Inject
+ TemplateManager templateMgr;
+ @Inject
+ VolumeHostDao volumeHostDao;
+ @Inject
+ HostDao hostDao;
+ @Inject
+ ConfigurationDao configDao;
+ @Inject
+ StorageManager storageMgr;
+ @Inject
+ VolumeDao volDao;
+ @Inject
+ VMTemplateDao templateDao;
+ @Inject
+ SnapshotManager snapshotMgr;
+ @Inject
+ SnapshotDao snapshotDao;
+ @Inject
+ PrimaryDataStoreDao primaryDataStoreDao;
+ @Inject
+ DataStoreManager dataStoreMgr;
+ @Inject
+ VMTemplateHostDao templateHostDao;
+ @Inject DiskOfferingDao diskOfferingDao;
+ @Inject VMTemplatePoolDao templatePoolDao;
+ @Inject
+ VolumeManager volumeMgr;
+ @Inject
+ private SwiftManager _swiftMgr;
+ @Inject
+ private S3Manager _s3Mgr;
+
+ @Override
+ public boolean canHandle(DataObject srcData, DataObject destData) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @DB
+ protected Answer copyVolumeFromImage(DataObject srcData, DataObject destData) {
+ String value = configDao.getValue(Config.RecreateSystemVmEnabled.key());
+ int _copyvolumewait = NumbersUtil.parseInt(value,
+ Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
+
+ VolumeHostVO volumeHostVO = volumeHostDao.findByVolumeId(srcData
+ .getId());
+ HostVO secStorage = hostDao.findById(volumeHostVO.getHostId());
+ String secondaryStorageURL = secStorage.getStorageUrl();
+ String[] volumePath = volumeHostVO.getInstallPath().split("/");
+ String volumeUUID = volumePath[volumePath.length - 1].split("\\.")[0];
+ StoragePool destPool = (StoragePool) destData.getDataStore();
+ CopyVolumeCommand cvCmd = new CopyVolumeCommand(srcData.getId(),
+ volumeUUID, destPool, secondaryStorageURL, false,
+ _copyvolumewait);
+ CopyVolumeAnswer cvAnswer = null;
+ String errMsg = null;
+ try {
+ cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool,
+ cvCmd);
+ } catch (StorageUnavailableException e1) {
+ s_logger.debug("Failed to copy volume " + srcData.getId() + " to "
+ + destData.getId(), e1);
+ errMsg = e1.toString();
+ }
+
+ if (cvAnswer == null || !cvAnswer.getResult()) {
+ errMsg = cvAnswer.getDetails();
+ }
+
+ VolumeVO vol = this.volDao.findById(destData.getId());
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ vol.setPath(cvAnswer.getVolumePath());
+ vol.setFolder(destPool.getPath());
+ vol.setPodId(destPool.getPodId());
+ vol.setPoolId(destPool.getId());
+ vol.setPodId(destPool.getPodId());
+
+ this.volDao.update(vol.getId(), vol);
+ volumeHostDao.remove(volumeHostVO.getId());
+ txn.commit();
+ return cvAnswer;
+ }
+
+ private Answer copyTemplate(DataObject srcData, DataObject destData) {
+ VMTemplateVO template = this.templateDao.findById(srcData.getId());
+ templateMgr.prepareTemplateForCreate(template,
+ (StoragePool) destData.getDataStore());
+ return null;
+ }
+
+ protected Answer copyFromSnapshot(DataObject snapObj, DataObject volObj) {
+ SnapshotVO snapshot = this.snapshotDao.findById(snapObj.getId());
+ StoragePool pool = (StoragePool) volObj.getDataStore();
+ String vdiUUID = null;
+ Long snapshotId = snapshot.getId();
+ Long volumeId = snapshot.getVolumeId();
+ Long dcId = snapshot.getDataCenterId();
+ String secondaryStoragePoolUrl = this.snapshotMgr
+ .getSecondaryStorageURL(snapshot);
+ long accountId = snapshot.getAccountId();
+
+ String backedUpSnapshotUuid = snapshot.getBackupSnapshotId();
+ snapshot = snapshotDao.findById(snapshotId);
+ if (snapshot.getVersion().trim().equals("2.1")) {
+ VolumeVO volume = this.volDao.findByIdIncludingRemoved(volumeId);
+ if (volume == null) {
+ throw new CloudRuntimeException("failed to upgrade snapshot "
+ + snapshotId + " due to unable to find orignal volume:"
+ + volumeId + ", try it later ");
+ }
+ if (volume.getTemplateId() == null) {
+ snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+ } else {
+ VMTemplateVO template = templateDao
+ .findByIdIncludingRemoved(volume.getTemplateId());
+ if (template == null) {
+ throw new CloudRuntimeException(
+ "failed to upgrade snapshot "
+ + snapshotId
+ + " due to unalbe to find orignal template :"
+ + volume.getTemplateId()
+ + ", try it later ");
+ }
+ Long templateId = template.getId();
+ Long tmpltAccountId = template.getAccountId();
+ if (!snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
+ throw new CloudRuntimeException(
+ "failed to upgrade snapshot "
+ + snapshotId
+ + " due to this snapshot is being used, try it later ");
+ }
+ UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null,
+ secondaryStoragePoolUrl, dcId, accountId, volumeId,
+ templateId, tmpltAccountId, null,
+ snapshot.getBackupSnapshotId(), snapshot.getName(),
+ "2.1");
+ Answer answer = null;
+ try {
+ answer = this.storageMgr.sendToPool(pool, cmd);
+ } catch (StorageUnavailableException e) {
+ } finally {
+ snapshotDao.unlockFromLockTable(snapshotId.toString());
+ }
+ if ((answer != null) && answer.getResult()) {
+ snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+ } else {
+ throw new CloudRuntimeException("Unable to upgrade snapshot from 2.1 to 2.2 for "
+ + snapshot.getId());
+ }
+ }
+ }
+ String basicErrMsg = "Failed to create volume from "
+ + snapshot.getName() + " on pool " + pool;
+
+ try {
+ if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) {
+ snapshotMgr.downloadSnapshotsFromSwift(snapshot);
+ } else if (snapshot.getS3Id() != null && snapshot.getS3Id() != 0) {
+ snapshotMgr.downloadSnapshotsFromS3(snapshot);
+ }
+ String value = configDao
+ .getValue(Config.CreateVolumeFromSnapshotWait.toString());
+ int _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value,
+ Integer.parseInt(Config.CreateVolumeFromSnapshotWait
+ .getDefaultValue()));
+ CreateVolumeFromSnapshotCommand createVolumeFromSnapshotCommand = new CreateVolumeFromSnapshotCommand(
+ pool, secondaryStoragePoolUrl, dcId, accountId, volumeId,
+ backedUpSnapshotUuid, snapshot.getName(),
+ _createVolumeFromSnapshotWait);
+ CreateVolumeFromSnapshotAnswer answer;
+ if (!snapshotDao.lockInLockTable(snapshotId.toString(), 10)) {
+ throw new CloudRuntimeException("failed to create volume from "
+ + snapshotId
+ + " due to this snapshot is being used, try it later ");
+ }
+ answer = (CreateVolumeFromSnapshotAnswer) this.storageMgr
+ .sendToPool(pool, createVolumeFromSnapshotCommand);
+ if (answer != null && answer.getResult()) {
+ vdiUUID = answer.getVdi();
+ VolumeVO vol = this.volDao.findById(volObj.getId());
+ vol.setPath(vdiUUID);
+ this.volDao.update(vol.getId(), vol);
+ return null;
+ } else {
+ s_logger.error(basicErrMsg + " due to "
+ + ((answer == null) ? "null" : answer.getDetails()));
+ throw new CloudRuntimeException(basicErrMsg);
+ }
+ } catch (StorageUnavailableException e) {
+ s_logger.error(basicErrMsg, e);
+ throw new CloudRuntimeException(basicErrMsg);
+ } finally {
+ if (snapshot.getSwiftId() != null) {
+ snapshotMgr.deleteSnapshotsDirForVolume(
+ secondaryStoragePoolUrl, dcId, accountId, volumeId);
+ }
+ }
+ }
+
+ protected Answer cloneVolume(DataObject template, DataObject volume) {
+ VolumeInfo volInfo = (VolumeInfo)volume;
+ DiskOfferingVO offering = diskOfferingDao.findById(volInfo.getDiskOfferingId());
+ VMTemplateStoragePoolVO tmpltStoredOn = templatePoolDao.findByPoolTemplate(template.getDataStore().getId(), template.getId());
+
+ DiskProfile diskProfile = new DiskProfile(volInfo, offering,
+ null);
+ CreateCommand cmd = new CreateCommand(diskProfile,
+ tmpltStoredOn.getLocalDownloadPath(),
+ new StorageFilerTO((StoragePool)template.getDataStore()));
+ Answer answer = null;
+ StoragePool pool = (StoragePool)volume.getDataStore();
+ String errMsg = null;
+ try {
+ answer = storageMgr.sendToPool(pool, null, cmd);
+ } catch (StorageUnavailableException e) {
+ s_logger.debug("Failed to send to storage pool", e);
+ throw new CloudRuntimeException("Failed to send to storage pool", e);
+ }
+
+ if (answer.getResult()) {
+ VolumeVO vol = this.volDao.findById(volume.getId());
+ CreateAnswer createAnswer = (CreateAnswer) answer;
+ vol.setFolder(pool.getPath());
+ vol.setPath(createAnswer.getVolume().getPath());
+ vol.setSize(createAnswer.getVolume().getSize());
+ vol.setPoolType(pool.getPoolType());
+ vol.setPoolId(pool.getId());
+ vol.setPodId(pool.getPodId());
+ this.volDao.update(vol.getId(), vol);
+
+ } else {
+ if (tmpltStoredOn != null
+ && (answer instanceof CreateAnswer)
+ && ((CreateAnswer) answer)
+ .templateReloadRequested()) {
+ if (!templateMgr
+ .resetTemplateDownloadStateOnPool(tmpltStoredOn
+ .getId())) {
+
+ }
+ }
+ errMsg = answer.getDetails();
+ }
+
+ return answer;
+ }
+
+ protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) {
+ VolumeInfo volume = (VolumeInfo)srcData;
+ VolumeInfo destVolume = (VolumeInfo)destData;
+ String secondaryStorageURL = this.templateMgr.getSecondaryStorageURL(volume
+ .getDataCenterId());
+ StoragePool srcPool = (StoragePool)this.dataStoreMgr.getDataStore(volume
+ .getPoolId(), DataStoreRole.Primary);
+
+ StoragePool destPool = (StoragePool)this.dataStoreMgr.getDataStore(destVolume.getPoolId(), DataStoreRole.Primary);
+
+ String value = this.configDao.getValue(Config.CopyVolumeWait.toString());
+ int _copyvolumewait = NumbersUtil.parseInt(value,
+ Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
+ CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(),
+ volume.getPath(), srcPool, secondaryStorageURL, true,
+ _copyvolumewait);
+ CopyVolumeAnswer cvAnswer;
+ try {
+ cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(srcPool, cvCmd);
+ } catch (StorageUnavailableException e1) {
+ throw new CloudRuntimeException(
+ "Failed to copy the volume from the source primary storage pool to secondary storage.",
+ e1);
+ }
+
+ if (cvAnswer == null || !cvAnswer.getResult()) {
+ throw new CloudRuntimeException(
+ "Failed to copy the volume from the source primary storage pool to secondary storage.");
+ }
+
+ String secondaryStorageVolumePath = cvAnswer.getVolumePath();
+
+ cvCmd = new CopyVolumeCommand(volume.getId(),
+ secondaryStorageVolumePath, destPool,
+ secondaryStorageURL, false, _copyvolumewait);
+ try {
+ cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool, cvCmd);
+ } catch (StorageUnavailableException e1) {
+ throw new CloudRuntimeException(
+ "Failed to copy the volume from secondary storage to the destination primary storage pool.");
+ }
+
+ if (cvAnswer == null || !cvAnswer.getResult()) {
+ throw new CloudRuntimeException(
+ "Failed to copy the volume from secondary storage to the destination primary storage pool.");
+ }
+
+ VolumeVO destVol = this.volDao.findById(destVolume.getId());
+ destVol.setPath(cvAnswer.getVolumePath());
+ this.volDao.update(destVol.getId(), destVol);
+ return cvAnswer;
+ }
+
+ @Override
+ public Void copyAsync(DataObject srcData, DataObject destData,
+ AsyncCompletionCallback<CopyCommandResult> callback) {
+ Answer answer = null;
+ String errMsg = null;
+ try {
+ if (destData.getType() == DataObjectType.VOLUME
+ && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Image) {
+ answer = copyVolumeFromImage(srcData, destData);
+ } else if (destData.getType() == DataObjectType.TEMPLATE
+ && srcData.getType() == DataObjectType.TEMPLATE) {
+ answer = copyTemplate(srcData, destData);
+ } else if (srcData.getType() == DataObjectType.SNAPSHOT
+ && destData.getType() == DataObjectType.VOLUME) {
+ answer = copyFromSnapshot(srcData, destData);
+ } else if (srcData.getType() == DataObjectType.SNAPSHOT
+ && destData.getType() == DataObjectType.TEMPLATE) {
+ answer = createTemplateFromSnashot(srcData, destData);
+ } else if (srcData.getType() == DataObjectType.VOLUME
+ && destData.getType() == DataObjectType.TEMPLATE) {
+ answer = createTemplateFromVolume(srcData, destData);
+ } else if (srcData.getType() == DataObjectType.TEMPLATE
+ && destData.getType() == DataObjectType.VOLUME) {
+ answer = cloneVolume(srcData, destData);
+ } else if (destData.getType() == DataObjectType.VOLUME
+ && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) {
+ answer = copyVolumeBetweenPools(srcData, destData);
+ } else if (srcData.getType() == DataObjectType.SNAPSHOT &&
+ destData.getType() == DataObjectType.SNAPSHOT) {
+ answer = copySnapshot(srcData, destData);
+ }
+ } catch (Exception e) {
+ s_logger.debug("copy failed", e);
+ errMsg = e.toString();
+ }
+ CopyCommandResult result = new CopyCommandResult(null, answer);
+ result.setResult(errMsg);
+ callback.complete(result);
+
+ return null;
+ }
+
+ @DB
+ protected Answer createTemplateFromSnashot(DataObject srcData,
+ DataObject destData) {
+ long snapshotId = srcData.getId();
+ SnapshotVO snapshot = snapshotDao.findById(snapshotId);
+ if (snapshot == null) {
+ throw new CloudRuntimeException("Unable to find Snapshot for Id "
+ + srcData.getId());
+ }
+ Long zoneId = snapshot.getDataCenterId();
+ HostVO secondaryStorageHost = this.templateMgr
+ .getSecondaryStorageHost(zoneId);
+ String secondaryStorageURL = snapshotMgr
+ .getSecondaryStorageURL(snapshot);
+ VMTemplateVO template = this.templateDao.findById(destData.getId());
+ String name = template.getName();
+ String backupSnapshotUUID = snapshot.getBackupSnapshotId();
+ if (backupSnapshotUUID == null) {
+ throw new CloudRuntimeException(
+ "Unable to create private template from snapshot "
+ + snapshotId
+ + " due to there is no backupSnapshotUUID for this snapshot");
+ }
+
+ Long dcId = snapshot.getDataCenterId();
+ Long accountId = snapshot.getAccountId();
+ Long volumeId = snapshot.getVolumeId();
+
+ String origTemplateInstallPath = null;
+ List<StoragePoolVO> pools = this.storageMgr
+ .ListByDataCenterHypervisor(zoneId,
+ snapshot.getHypervisorType());
+ if (pools == null || pools.size() == 0) {
+ throw new CloudRuntimeException(
+ "Unable to find storage pools in zone " + zoneId);
+ }
+ StoragePoolVO poolvo = pools.get(0);
+ StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(
+ poolvo.getId(), DataStoreRole.Primary);
+ if (snapshot.getVersion() != null
+ && snapshot.getVersion().equalsIgnoreCase("2.1")) {
+ VolumeVO volume = this.volDao.findByIdIncludingRemoved(volumeId);
+ if (volume == null) {
+ throw new CloudRuntimeException("failed to upgrade snapshot "
+ + snapshotId + " due to unable to find orignal volume:"
+ + volumeId + ", try it later ");
+ }
+ if (volume.getTemplateId() == null) {
+ snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+ } else {
+ template = templateDao.findByIdIncludingRemoved(volume
+ .getTemplateId());
+ if (template == null) {
+ throw new CloudRuntimeException(
+ "failed to upgrade snapshot "
+ + snapshotId
+ + " due to unalbe to find orignal template :"
+ + volume.getTemplateId()
+ + ", try it later ");
+ }
+ Long origTemplateId = template.getId();
+ Long origTmpltAccountId = template.getAccountId();
+ if (!this.volDao.lockInLockTable(volumeId.toString(), 10)) {
+ throw new CloudRuntimeException(
+ "failed to upgrade snapshot " + snapshotId
+ + " due to volume:" + volumeId
+ + " is being used, try it later ");
+ }
+ UpgradeSnapshotCommand cmd = new UpgradeSnapshotCommand(null,
+ secondaryStorageURL, dcId, accountId, volumeId,
+ origTemplateId, origTmpltAccountId, null,
+ snapshot.getBackupSnapshotId(), snapshot.getName(),
+ "2.1");
+ if (!this.volDao.lockInLockTable(volumeId.toString(), 10)) {
+ throw new CloudRuntimeException(
+ "Creating template failed due to volume:"
+ + volumeId
+ + " is being used, try it later ");
+ }
+ Answer answer = null;
+ try {
+ answer = this.storageMgr.sendToPool(pool, cmd);
+ cmd = null;
+ } catch (StorageUnavailableException e) {
+ } finally {
+ this.volDao.unlockFromLockTable(volumeId.toString());
+ }
+ if ((answer != null) && answer.getResult()) {
+ snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
+ } else {
+ throw new CloudRuntimeException(
+ "Unable to upgrade snapshot");
+ }
+ }
+ }
+ if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) {
+ snapshotMgr.downloadSnapshotsFromSwift(snapshot);
+ }
+ String value = configDao
+ .getValue(Config.CreatePrivateTemplateFromSnapshotWait
+ .toString());
+ int _createprivatetemplatefromsnapshotwait = NumbersUtil.parseInt(
+ value, Integer
+ .parseInt(Config.CreatePrivateTemplateFromSnapshotWait
+ .getDefaultValue()));
+
+ CreatePrivateTemplateFromSnapshotCommand cmd = new CreatePrivateTemplateFromSnapshotCommand(
+ pool, secondaryStorageURL, dcId, accountId,
+ snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
+ origTemplateInstallPath, template.getId(), name,
+ _createprivatetemplatefromsnapshotwait);
+
+ return sendCommand(cmd, pool, template.getId(), dcId,
+ secondaryStorageHost.getId());
+ }
+
+ @DB
+ protected Answer sendCommand(Command cmd, StoragePool pool,
+ long templateId, long zoneId, long hostId) {
+
+ CreatePrivateTemplateAnswer answer = null;
+ try {
+ answer = (CreatePrivateTemplateAnswer) this.storageMgr.sendToPool(
+ pool, cmd);
+ } catch (StorageUnavailableException e) {
+ throw new CloudRuntimeException(
+ "Failed to execute CreatePrivateTemplateFromSnapshotCommand",
+ e);
+ }
+
+ if (answer == null || !answer.getResult()) {
+ return answer;
+ }
+
+ VMTemplateVO privateTemplate = templateDao.findById(templateId);
+ String answerUniqueName = answer.getUniqueName();
+ if (answerUniqueName != null) {
+ privateTemplate.setUniqueName(answerUniqueName);
+ }
+ ImageFormat format = answer.getImageFormat();
+ if (format != null) {
+ privateTemplate.setFormat(format);
+ } else {
+ // This never occurs.
+ // Specify RAW format makes it unusable for snapshots.
+ privateTemplate.setFormat(ImageFormat.RAW);
+ }
+
+ String checkSum = this.templateMgr
+ .getChecksum(hostId, answer.getPath());
+
+ Transaction txn = Transaction.currentTxn();
+
+ txn.start();
+
+ privateTemplate.setChecksum(checkSum);
+ templateDao.update(privateTemplate.getId(), privateTemplate);
+
+ // add template zone ref for this template
+ templateDao.addTemplateToZone(privateTemplate, zoneId);
+ VMTemplateHostVO templateHostVO = new VMTemplateHostVO(hostId,
+ privateTemplate.getId());
+ templateHostVO.setDownloadPercent(100);
+ templateHostVO.setDownloadState(Status.DOWNLOADED);
+ templateHostVO.setInstallPath(answer.getPath());
+ templateHostVO.setLastUpdated(new Date());
+ templateHostVO.setSize(answer.getVirtualSize());
+ templateHostVO.setPhysicalSize(answer.getphysicalSize());
+ templateHostDao.persist(templateHostVO);
+ txn.close();
+ return answer;
+ }
+
+ private Answer createTemplateFromVolume(DataObject srcObj,
+ DataObject destObj) {
+ long volumeId = srcObj.getId();
+ VolumeVO volume = this.volDao.findById(volumeId);
+ if (volume == null) {
+ throw new CloudRuntimeException("Unable to find volume for Id "
+ + volumeId);
+ }
+ long accountId = volume.getAccountId();
+
+ String vmName = this.volumeMgr.getVmNameOnVolume(volume);
+ Long zoneId = volume.getDataCenterId();
+ HostVO secondaryStorageHost = this.templateMgr
+ .getSecondaryStorageHost(zoneId);
+ if (secondaryStorageHost == null) {
+ throw new CloudRuntimeException(
+ "Can not find the secondary storage for zoneId " + zoneId);
+ }
+ String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
+ VMTemplateVO template = this.templateDao.findById(destObj.getId());
+ StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(
+ volume.getPoolId(), DataStoreRole.Primary);
+ String value = configDao
+ .getValue(Config.CreatePrivateTemplateFromVolumeWait.toString());
+ int _createprivatetemplatefromvolumewait = NumbersUtil.parseInt(value,
+ Integer.parseInt(Config.CreatePrivateTemplateFromVolumeWait
+ .getDefaultValue()));
+
+ CreatePrivateTemplateFromVolumeCommand cmd = new CreatePrivateTemplateFromVolumeCommand(
+ pool, secondaryStorageURL, destObj.getId(), accountId,
+ template.getName(), template.getUniqueName(), volume.getPath(),
+ vmName, _createprivatetemplatefromvolumewait);
+
+ return sendCommand(cmd, pool, template.getId(), zoneId,
+ secondaryStorageHost.getId());
+ }
+
+ private HostVO getSecHost(long volumeId, long dcId) {
+ Long id = snapshotDao.getSecHostId(volumeId);
+ if ( id != null) {
+ return hostDao.findById(id);
+ }
+ return this.templateMgr.getSecondaryStorageHost(dcId);
+ }
+
+ protected Answer copySnapshot(DataObject srcObject, DataObject destObject) {
+ SnapshotInfo srcSnapshot = (SnapshotInfo)srcObject;
+ VolumeInfo baseVolume = srcSnapshot.getBaseVolume();
+ Long dcId = baseVolume.getDataCenterId();
+ Long accountId = baseVolume.getAccountId();
+
+ HostVO secHost = getSecHost(baseVolume.getId(), baseVolume.getDataCenterId());
+ Long secHostId = secHost.getId();
+ String secondaryStoragePoolUrl = secHost.getStorageUrl();
+ String snapshotUuid = srcSnapshot.getPath();
+ // In order to verify that the snapshot is not empty,
+ // we check if the parent of the snapshot is not the same as the parent of the previous snapshot.
+ // We pass the uuid of the previous snapshot to the plugin to verify this.
+ SnapshotVO prevSnapshot = null;
+ String prevSnapshotUuid = null;
+ String prevBackupUuid = null;
+
+
+ SwiftTO swift = _swiftMgr.getSwiftTO();
+ S3TO s3 = _s3Mgr.getS3TO();
+
+ long prevSnapshotId = srcSnapshot.getPrevSnapshotId();
+ if (prevSnapshotId > 0) {
+ prevSnapshot = snapshotDao.findByIdIncludingRemoved(prevSnapshotId);
+ if ( prevSnapshot.getBackupSnapshotId() != null && swift == null) {
+ if (prevSnapshot.getVersion() != null && prevSnapshot.getVersion().equals("2.2")) {
+ prevBackupUuid = prevSnapshot.getBackupSnapshotId();
+ prevSnapshotUuid = prevSnapshot.getPath();
+ }
+ } else if ((prevSnapshot.getSwiftId() != null && swift != null)
+ || (prevSnapshot.getS3Id() != null && s3 != null)) {
+ prevBackupUuid = prevSnapshot.getBackupSnapshotId();
+ prevSnapshotUuid = prevSnapshot.getPath();
+ }
+ }
+ boolean isVolumeInactive = this.volumeMgr.volumeInactive(baseVolume);
+ String vmName = this.volumeMgr.getVmNameOnVolume(baseVolume);
+ StoragePool srcPool = (StoragePool)dataStoreMgr.getPrimaryDataStore(baseVolume.getPoolId());
+ String value = configDao.getValue(Config.BackupSnapshotWait.toString());
+ int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
+ BackupSnapshotCommand backupSnapshotCommand = new BackupSnapshotCommand(secondaryStoragePoolUrl, dcId, accountId, baseVolume.getId(), srcSnapshot.getId(), secHostId, baseVolume.getPath(), srcPool, snapshotUuid,
+ srcSnapshot.getName(), prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, _backupsnapshotwait);
+
+ if ( swift != null ) {
+ backupSnapshotCommand.setSwift(swift);
+ } else if (s3 != null) {
+ backupSnapshotCommand.setS3(s3);
+ }
+ BackupSnapshotAnswer answer = (BackupSnapshotAnswer) this.snapshotMgr.sendToPool(baseVolume, backupSnapshotCommand);
+ if (answer != null && answer.getResult()) {
+ SnapshotVO snapshotVO = this.snapshotDao.findById(srcSnapshot.getId());
+ if (backupSnapshotCommand.getSwift() != null ) {
+ snapshotVO.setSwiftId(swift.getId());
+ snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName());
+ } else if (backupSnapshotCommand.getS3() != null) {
+ snapshotVO.setS3Id(s3.getId());
+ snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName());
+ } else {
+ snapshotVO.setSecHostId(secHost.getId());
+ snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName());
+ }
+ if (answer.isFull()) {
+ snapshotVO.setPrevSnapshotId(0L);
+ }
+ this.snapshotDao.update(srcSnapshot.getId(), snapshotVO);
+ }
+ return answer;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java
new file mode 100644
index 0000000..3a59b21
--- /dev/null
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java
@@ -0,0 +1,25 @@
+/*
+ * 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.motion;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+
+public interface DataMotionDriver {
+ public void copy(DataObject srcObj, DataObject destObj);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
new file mode 100644
index 0000000..93ab412
--- /dev/null
+++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
@@ -0,0 +1,63 @@
+/*
+ * 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.motion;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+public class DataMotionServiceImpl implements DataMotionService {
+ @Inject
+ List<DataMotionStrategy> strategies;
+
+ @Override
+ public void copyAsync(DataObject srcData, DataObject destData,
+ AsyncCompletionCallback<CopyCommandResult> callback) {
+
+ if (srcData.getDataStore().getDriver().canCopy(srcData, destData)) {
+ srcData.getDataStore().getDriver()
+ .copyAsync(srcData, destData, callback);
+ return;
+ } else if (destData.getDataStore().getDriver()
+ .canCopy(srcData, destData)) {
+ destData.getDataStore().getDriver()
+ .copyAsync(srcData, destData, callback);
+ return;
+ }
+
+ for (DataMotionStrategy strategy : strategies) {
+ if (strategy.canHandle(srcData, destData)) {
+ strategy.copyAsync(srcData, destData, callback);
+ return;
+ }
+ }
+ throw new CloudRuntimeException("can't find strategy to move data");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
index dbcfb76..a1096d3 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
@@ -28,6 +28,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
@@ -37,12 +38,18 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
+import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
+import com.cloud.storage.ScopeType;
import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
@Component
public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager {
+ private static final Logger s_logger = Logger.getLogger(ImageStoreProviderManagerImpl.class);
@Inject
ImageStoreDao dataStoreDao;
@Inject
@@ -115,4 +122,21 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager
+ @Override
+ public List<DataStore> listImageCacheStores(Scope scope) {
+ List<DataStore> imageStores = new ArrayList<DataStore>();
+ if (scope.getScopeType() != ScopeType.ZONE) {
+ s_logger.debug("only support zone wide image cache stores");
+ return imageStores;
+ }
+ SearchCriteriaService<ImageStoreVO, ImageStoreVO> sc = SearchCriteria2.create(ImageStoreVO.class);
+ sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE);
+ sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, scope.getScopeId());
+ sc.addAnd(sc.getEntity().getRole(), Op.EQ, DataStoreRole.ImageCache);
+ List<ImageStoreVO> cacheStores = sc.list();
+ for (ImageStoreVO store : cacheStores) {
+ imageStores.add(getImageStore(store.getId()));
+ }
+ return imageStores;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e5bf38ed/engine/storage/imagemotion/pom.xml
----------------------------------------------------------------------
diff --git a/engine/storage/imagemotion/pom.xml b/engine/storage/imagemotion/pom.xml
deleted file mode 100644
index 9a7f3e0..0000000
--- a/engine/storage/imagemotion/pom.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<!-- 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. -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <artifactId>cloud-engine-storage-imagemotion</artifactId>
- <name>Apache CloudStack Engine Storage Image Motion Component</name>
- <parent>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-engine</artifactId>
- <version>4.2.0-SNAPSHOT</version>
- <relativePath>../../pom.xml</relativePath>
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-engine-storage</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-engine-storage-volume</artifactId>
- <version>${project.version}</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.cloudstack</groupId>
- <artifactId>cloud-engine-storage-image</artifactId>
- <version>${project.version}</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>${cs.mysql.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>1.9.5</version>
- </dependency>
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
- </dependency>
- </dependencies>
- <build>
- <defaultGoal>install</defaultGoal>
- <sourceDirectory>src</sourceDirectory>
- <testSourceDirectory>test</testSourceDirectory>
- </build>
-</project>