This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch 4.20
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.20 by this push:
new ac6b1b382cf Migrate public templates that have URLs on data migration
across secondary storages (#10364)
ac6b1b382cf is described below
commit ac6b1b382cfd552a1d5311e8c2172c563e39a631
Author: Fabricio Duarte <[email protected]>
AuthorDate: Tue Apr 15 08:48:45 2025 -0300
Migrate public templates that have URLs on data migration across secondary
storages (#10364)
Co-authored-by: Fabricio Duarte <[email protected]>
---
.../storage/VMTemplateStorageResourceAssoc.java | 3 +
.../engine/orchestration/DataMigrationUtility.java | 32 ++++-
.../orchestration/DataMigrationUtilityTest.java | 88 +++++++++++++
.../storage/image/SecondaryStorageServiceImpl.java | 91 +++++++++++---
.../image/SecondaryStorageServiceImplTest.java | 138 +++++++++++++++++++++
.../cloud/api/query/dao/TemplateJoinDaoImpl.java | 7 --
.../storage/download/DownloadActiveState.java | 2 +-
.../cloud/storage/download/DownloadListener.java | 1 +
8 files changed, 336 insertions(+), 26 deletions(-)
diff --git
a/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
b/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
index f43d5331222..db702a61f2b 100644
--- a/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
+++ b/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
@@ -17,6 +17,7 @@
package com.cloud.storage;
import java.util.Date;
+import java.util.List;
import org.apache.cloudstack.api.InternalIdentity;
@@ -25,6 +26,8 @@ public interface VMTemplateStorageResourceAssoc extends
InternalIdentity {
UNKNOWN, DOWNLOAD_ERROR, NOT_DOWNLOADED, DOWNLOAD_IN_PROGRESS,
DOWNLOADED, ABANDONED, UPLOADED, NOT_UPLOADED, UPLOAD_ERROR,
UPLOAD_IN_PROGRESS, CREATING, CREATED, BYPASSED
}
+ List<Status> PENDING_DOWNLOAD_STATES = List.of(Status.NOT_DOWNLOADED,
Status.DOWNLOAD_IN_PROGRESS);
+
String getInstallPath();
long getTemplateId();
diff --git
a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/DataMigrationUtility.java
b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/DataMigrationUtility.java
index c260f48dcf8..9609ba7751d 100644
---
a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/DataMigrationUtility.java
+++
b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/DataMigrationUtility.java
@@ -208,9 +208,7 @@ public class DataMigrationUtility {
List<TemplateInfo> files = new LinkedList<>();
for (TemplateDataStoreVO template : templates) {
VMTemplateVO templateVO =
templateDao.findById(template.getTemplateId());
- if (template.getState() ==
ObjectInDataStoreStateMachine.State.Ready && templateVO != null &&
- (!templateVO.isPublicTemplate() ||
(templateVO.isPublicTemplate() && templateVO.getUrl() == null)) &&
- templateVO.getHypervisorType() !=
Hypervisor.HypervisorType.Simulator && templateVO.getParentTemplateId() ==
null) {
+ if (shouldMigrateTemplate(template, templateVO)) {
files.add(templateFactory.getTemplate(template.getTemplateId(), srcDataStore));
}
}
@@ -231,6 +229,34 @@ public class DataMigrationUtility {
return getAllReadyTemplates(srcDataStore, childTemplates, templates);
}
+ /**
+ * Returns whether a template should be migrated. A template should be
migrated if:
+ * <ol>
+ * <li>its state is ready, and</li>
+ * <li>its hypervisor type is not simulator, and</li>
+ * <li>it is not a child template.</li>
+ * </ol>
+ */
+ protected boolean shouldMigrateTemplate(TemplateDataStoreVO template,
VMTemplateVO templateVO) {
+ if (template.getState() != State.Ready) {
+ logger.debug("Template [{}] should not be migrated as it is not
ready.", template);
+ return false;
+ }
+
+ if (templateVO.getHypervisorType() ==
Hypervisor.HypervisorType.Simulator) {
+ logger.debug("Template [{}] should not be migrated as its
hypervisor type is simulator.", template);
+ return false;
+ }
+
+ if (templateVO.getParentTemplateId() != null) {
+ logger.debug("Template [{}] should not be migrated as it has a
parent template.", template);
+ return false;
+ }
+
+ logger.debug("Template [{}] should be migrated.", template);
+ return true;
+ }
+
/** Returns parent snapshots and snapshots that do not have any children;
snapshotChains comprises of the snapshot chain info
* for each parent snapshot and the cumulative size of the chain - this is
done to ensure that all the snapshots in a chain
* are migrated to the same datastore
diff --git
a/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/DataMigrationUtilityTest.java
b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/DataMigrationUtilityTest.java
new file mode 100644
index 00000000000..acd98e1cbff
--- /dev/null
+++
b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/DataMigrationUtilityTest.java
@@ -0,0 +1,88 @@
+// 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.orchestration;
+
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.storage.VMTemplateVO;
+import junit.framework.TestCase;
+import
org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DataMigrationUtilityTest extends TestCase {
+
+ @Spy
+ private DataMigrationUtility dataMigrationUtility;
+
+ @Mock
+ private VMTemplateVO templateVoMock;
+
+ @Mock
+ private TemplateDataStoreVO templateDataStoreVoMock;
+
+ private void prepareForShouldMigrateTemplateTests() {
+
Mockito.when(templateDataStoreVoMock.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);
+
Mockito.when(templateVoMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
+ Mockito.when(templateVoMock.getParentTemplateId()).thenReturn(null);
+ }
+
+ @Test
+ public void shouldMigrateTemplateTestReturnsFalseWhenTemplateIsNotReady() {
+ prepareForShouldMigrateTemplateTests();
+
Mockito.when(templateDataStoreVoMock.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Migrating);
+
+ boolean result =
dataMigrationUtility.shouldMigrateTemplate(templateDataStoreVoMock,
templateVoMock);
+
+ Assert.assertFalse(result);
+ }
+
+ @Test
+ public void
shouldMigrateTemplateTestReturnsFalseWhenHypervisorTypeIsSimulator() {
+ prepareForShouldMigrateTemplateTests();
+
Mockito.when(templateVoMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.Simulator);
+
+ boolean result =
dataMigrationUtility.shouldMigrateTemplate(templateDataStoreVoMock,
templateVoMock);
+
+ Assert.assertFalse(result);
+ }
+
+ @Test
+ public void
shouldMigrateTemplateTestReturnsFalseWhenTemplateHasParentTemplate() {
+ prepareForShouldMigrateTemplateTests();
+ Mockito.when(templateVoMock.getParentTemplateId()).thenReturn(1L);
+
+ boolean result =
dataMigrationUtility.shouldMigrateTemplate(templateDataStoreVoMock,
templateVoMock);
+
+ Assert.assertFalse(result);
+ }
+
+ @Test
+ public void
shouldMigrateTemplateTestReturnsTrueWhenTemplateIsReadyAndDoesNotHaveParentTemplateAndHypervisorTypeIsNotSimulator()
{
+ prepareForShouldMigrateTemplateTests();
+
+ boolean result =
dataMigrationUtility.shouldMigrateTemplate(templateDataStoreVoMock,
templateVoMock);
+
+ Assert.assertTrue(result);
+ }
+}
diff --git
a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/SecondaryStorageServiceImpl.java
b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/SecondaryStorageServiceImpl.java
index 730b003fcb0..502bbaf9e49 100644
---
a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/SecondaryStorageServiceImpl.java
+++
b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/SecondaryStorageServiceImpl.java
@@ -24,6 +24,9 @@ import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.download.DownloadListener;
+import com.cloud.utils.exception.CloudRuntimeException;
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.DataObject;
@@ -118,26 +121,21 @@ public class SecondaryStorageServiceImpl implements
SecondaryStorageService {
}
} else if (srcDataObject instanceof TemplateInfo && templateChain
!= null && templateChain.containsKey(srcDataObject)) {
for (TemplateInfo templateInfo :
templateChain.get(srcDataObject).first()) {
+ if (templateIsOnDestination(templateInfo, destDatastore)) {
+ res.setResult("Template already exists on
destination.");
+ res.setSuccess(true);
+ logger.debug("Deleting template {} from source data
store [{}].", srcDataObject.getTO().toString(),
+
srcDataObject.getDataStore().getTO().toString());
+ srcDataObject.getDataStore().delete(srcDataObject);
+ future.complete(res);
+ continue;
+ }
destDataObject = destDatastore.create(templateInfo);
templateInfo.processEvent(ObjectInDataStoreStateMachine.Event.MigrateDataRequested);
destDataObject.processEvent(ObjectInDataStoreStateMachine.Event.MigrateDataRequested);
migrateJob(future, templateInfo, destDataObject,
destDatastore);
}
- }
- else {
- // Check if template in destination store, if yes, do not
proceed
- if (srcDataObject instanceof TemplateInfo) {
- logger.debug("Checking if template present at
destination");
- TemplateDataStoreVO templateStoreVO =
templateStoreDao.findByStoreTemplate(destDatastore.getId(),
srcDataObject.getId());
- if (templateStoreVO != null) {
- String msg = "Template already exists in destination
store";
- logger.debug(msg);
- res.setResult(msg);
- res.setSuccess(true);
- future.complete(res);
- return future;
- }
- }
+ } else {
destDataObject = destDatastore.create(srcDataObject);
srcDataObject.processEvent(ObjectInDataStoreStateMachine.Event.MigrateDataRequested);
destDataObject.processEvent(ObjectInDataStoreStateMachine.Event.MigrateDataRequested);
@@ -160,6 +158,69 @@ public class SecondaryStorageServiceImpl implements
SecondaryStorageService {
return future;
}
+ /**
+ * Returns a boolean indicating whether a template is ready on the
provided data store. If the template is being downloaded,
+ * waits until the download finishes.
+ * @param srcDataObject the template.
+ * @param destDatastore the data store.
+ */
+ protected boolean templateIsOnDestination(DataObject srcDataObject,
DataStore destDatastore) {
+ if (!(srcDataObject instanceof TemplateInfo)) {
+ return false;
+ }
+
+ String templateAsString = srcDataObject.getTO().toString();
+ String destDatastoreAsString = destDatastore.getTO().toString();
+ TemplateDataStoreVO templateStoreVO;
+
+ long timer = getTemplateDownloadTimeout();
+ long msToSleep = 10000L;
+ int previousDownloadPercentage = -1;
+
+ while (true) {
+ templateStoreVO =
templateStoreDao.findByStoreTemplate(destDatastore.getId(),
srcDataObject.getId());
+ if (templateStoreVO == null) {
+ logger.debug("{} is not present at destination [{}].",
templateAsString, destDatastoreAsString);
+ return false;
+ }
+ VMTemplateStorageResourceAssoc.Status downloadState =
templateStoreVO.getDownloadState();
+ if (downloadState == null ||
!VMTemplateStorageResourceAssoc.PENDING_DOWNLOAD_STATES.contains(downloadState))
{
+ break;
+ }
+ if (previousDownloadPercentage ==
templateStoreVO.getDownloadPercent()) {
+ timer -= msToSleep;
+ } else {
+ timer = getTemplateDownloadTimeout();
+ }
+ if (timer <= 0) {
+ throw new CloudRuntimeException(String.format("Timeout while
waiting for %s to be downloaded to image store [%s]. " +
+ "The download percentage has not changed for %d
milliseconds.", templateAsString, destDatastoreAsString,
getTemplateDownloadTimeout()));
+ }
+ waitForTemplateDownload(msToSleep, templateAsString,
destDatastoreAsString);
+ }
+
+ if (templateStoreVO.getState() ==
ObjectInDataStoreStateMachine.State.Ready) {
+ logger.debug("{} already exists on destination [{}].",
templateAsString, destDatastoreAsString);
+ return true;
+ }
+ return false;
+ }
+
+ protected long getTemplateDownloadTimeout() {
+ return DownloadListener.DOWNLOAD_TIMEOUT;
+ }
+
+ protected void waitForTemplateDownload(long msToSleep, String
templateAsString, String destDatastoreAsString) {
+ logger.debug("{} is being downloaded to destination [{}]; we will
verify in {} milliseconds if the download has finished.",
+ templateAsString, destDatastoreAsString, msToSleep);
+ try {
+ Thread.sleep(msToSleep);
+ } catch (InterruptedException e) {
+ logger.warn("[ignored] interrupted while waiting for template {}
download to finish before trying to migrate it to data store [{}].",
+ templateAsString, destDatastoreAsString);
+ }
+ }
+
protected void migrateJob(AsyncCallFuture<DataObjectResult> future,
DataObject srcDataObject, DataObject destDataObject, DataStore destDatastore)
throws ExecutionException, InterruptedException {
MigrateDataContext<DataObjectResult> context = new
MigrateDataContext<DataObjectResult>(null, future, srcDataObject,
destDataObject, destDatastore);
AsyncCallbackDispatcher<SecondaryStorageServiceImpl,
CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
diff --git
a/engine/storage/image/src/test/java/org/apache/cloudstack/storage/image/SecondaryStorageServiceImplTest.java
b/engine/storage/image/src/test/java/org/apache/cloudstack/storage/image/SecondaryStorageServiceImplTest.java
new file mode 100644
index 00000000000..740194ea253
--- /dev/null
+++
b/engine/storage/image/src/test/java/org/apache/cloudstack/storage/image/SecondaryStorageServiceImplTest.java
@@ -0,0 +1,138 @@
+// 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.image;
+
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.utils.exception.CloudRuntimeException;
+import junit.framework.TestCase;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import
org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SecondaryStorageServiceImplTest extends TestCase {
+
+ @Spy
+ @InjectMocks
+ private SecondaryStorageServiceImpl secondaryStorageService;
+
+ @Mock
+ TemplateDataStoreDao templateDataStoreDaoMock;
+
+ @Mock
+ TemplateDataStoreVO templateDataStoreVoMock;
+
+ @Mock
+ TemplateInfo templateInfoMock;
+
+ @Mock
+ TemplateObjectTO templateObjectToMock;
+
+ @Mock
+ DataStore dataStoreMock;
+
+ @Mock
+ DataStoreTO dataStoreToMock;
+
+ private void prepareForTemplateIsOnDestinationTests() {
+ long dataStoreId = 1;
+ long templateId = 2;
+
+ Mockito.when(dataStoreMock.getId()).thenReturn(dataStoreId);
+ Mockito.when(dataStoreMock.getTO()).thenReturn(dataStoreToMock);
+ Mockito.when(templateInfoMock.getId()).thenReturn(templateId);
+
Mockito.when(templateInfoMock.getTO()).thenReturn(templateObjectToMock);
+
Mockito.doReturn(templateDataStoreVoMock).when(templateDataStoreDaoMock).findByStoreTemplate(dataStoreId,
templateId);
+
Mockito.when(templateDataStoreVoMock.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Ready);
+ }
+
+ @Test
+ public void
templateIsOnDestinationTestReturnsFalseWhenTemplateStoreRefDoesNotExist() {
+ prepareForTemplateIsOnDestinationTests();
+
Mockito.doReturn(null).when(templateDataStoreDaoMock).findByStoreTemplate(Mockito.anyLong(),
Mockito.anyLong());
+
+ boolean result =
secondaryStorageService.templateIsOnDestination(templateInfoMock,
dataStoreMock);
+
+ Assert.assertFalse(result);
+ }
+
+ @Test
+ public void templateIsOnDestinationTestReturnsTrueWhenTemplateIsReady() {
+ prepareForTemplateIsOnDestinationTests();
+
+ boolean result =
secondaryStorageService.templateIsOnDestination(templateInfoMock,
dataStoreMock);
+
+ Assert.assertTrue(result);
+ }
+
+ @Test
+ public void
templateIsOnDestinationTestReturnsFalseWhenTemplateIsNotReady() {
+ prepareForTemplateIsOnDestinationTests();
+
Mockito.when(templateDataStoreVoMock.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Creating);
+
+ boolean result =
secondaryStorageService.templateIsOnDestination(templateInfoMock,
dataStoreMock);
+
+ Assert.assertFalse(result);
+ }
+
+ @Test
+ public void
templateIsOnDestinationTestReturnsTrueIfTemplateIsDownloadedSuccessfully() {
+ prepareForTemplateIsOnDestinationTests();
+
Mockito.when(templateDataStoreVoMock.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS);
+ Mockito.doAnswer(I ->
Mockito.when(templateDataStoreVoMock.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOADED)).when(secondaryStorageService).waitForTemplateDownload(Mockito.anyLong(),
Mockito.anyString(), Mockito.anyString());
+
+ boolean result =
secondaryStorageService.templateIsOnDestination(templateInfoMock,
dataStoreMock);
+
+ Assert.assertTrue(result);
+ }
+
+ @Test
+ public void
templateIsOnDestinationTestReturnsFalseIfTemplateIsNotDownloadedSuccessfully() {
+ prepareForTemplateIsOnDestinationTests();
+
Mockito.when(templateDataStoreVoMock.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS);
+ Mockito.doAnswer(I -> {
+
Mockito.when(templateDataStoreVoMock.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+
Mockito.when(templateDataStoreVoMock.getState()).thenReturn(ObjectInDataStoreStateMachine.State.Failed);
+ return "mocked download fail";
+
}).when(secondaryStorageService).waitForTemplateDownload(Mockito.anyLong(),
Mockito.anyString(), Mockito.anyString());
+
+ boolean result =
secondaryStorageService.templateIsOnDestination(templateInfoMock,
dataStoreMock);
+
+ Assert.assertFalse(result);
+ }
+
+ @Test(expected = CloudRuntimeException.class)
+ public void templateIsOnDestinationTestThrowsExceptionIfDownloadTimesOut()
{
+ prepareForTemplateIsOnDestinationTests();
+
Mockito.when(templateDataStoreVoMock.getDownloadState()).thenReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS);
+
Mockito.doReturn(0L).when(secondaryStorageService).getTemplateDownloadTimeout();
+
+ secondaryStorageService.templateIsOnDestination(templateInfoMock,
dataStoreMock);
+ }
+}
diff --git
a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
index 0bdf5040c82..ac24f14b781 100644
--- a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
@@ -151,11 +151,6 @@ public class TemplateJoinDaoImpl extends
GenericDaoBaseWithTagInformation<Templa
activeTmpltSearch.and("store_id",
activeTmpltSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
activeTmpltSearch.and("type",
activeTmpltSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
activeTmpltSearch.and("templateState",
activeTmpltSearch.entity().getTemplateState(), SearchCriteria.Op.EQ);
- activeTmpltSearch.and().op("public",
activeTmpltSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ);
- activeTmpltSearch.or().op("publicNoUrl",
activeTmpltSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ);
- activeTmpltSearch.and("url", activeTmpltSearch.entity().getUrl(),
SearchCriteria.Op.NULL);
- activeTmpltSearch.cp();
- activeTmpltSearch.cp();
activeTmpltSearch.done();
publicTmpltSearch = createSearchBuilder();
@@ -687,8 +682,6 @@ public class TemplateJoinDaoImpl extends
GenericDaoBaseWithTagInformation<Templa
sc.setParameters("store_id", storeId);
sc.setParameters("type", TemplateType.USER);
sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
- sc.setParameters("public", Boolean.FALSE);
- sc.setParameters("publicNoUrl",Boolean.TRUE);
return searchIncludingRemoved(sc, null, null, false);
}
diff --git
a/server/src/main/java/com/cloud/storage/download/DownloadActiveState.java
b/server/src/main/java/com/cloud/storage/download/DownloadActiveState.java
index 989e0b55f94..889ffbc0b1c 100644
--- a/server/src/main/java/com/cloud/storage/download/DownloadActiveState.java
+++ b/server/src/main/java/com/cloud/storage/download/DownloadActiveState.java
@@ -76,7 +76,7 @@ public abstract class DownloadActiveState extends
DownloadState {
getDownloadListener().log("handleTimeout, updateMs=" + updateMs +
", curr state= " + getName(), Level.TRACE);
}
String newState = getName();
- if (updateMs > 5 * DownloadListener.STATUS_POLL_INTERVAL) {
+ if (updateMs > DownloadListener.DOWNLOAD_TIMEOUT) {
newState = Status.DOWNLOAD_ERROR.toString();
getDownloadListener().log("timeout: transitioning to download
error state, currstate=" + getName(), Level.DEBUG);
} else if (updateMs > 3 * DownloadListener.STATUS_POLL_INTERVAL) {
diff --git
a/server/src/main/java/com/cloud/storage/download/DownloadListener.java
b/server/src/main/java/com/cloud/storage/download/DownloadListener.java
index e06a31d96b5..42b0e394db4 100644
--- a/server/src/main/java/com/cloud/storage/download/DownloadListener.java
+++ b/server/src/main/java/com/cloud/storage/download/DownloadListener.java
@@ -100,6 +100,7 @@ public class DownloadListener implements Listener {
protected Logger logger = LogManager.getLogger(getClass());
public static final int SMALL_DELAY = 100;
public static final long STATUS_POLL_INTERVAL = 10000L;
+ public static final long DOWNLOAD_TIMEOUT = 5 * STATUS_POLL_INTERVAL;
public static final String DOWNLOADED = Status.DOWNLOADED.toString();
public static final String NOT_DOWNLOADED =
Status.NOT_DOWNLOADED.toString();