mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge pull request #2044 from shapeblue/cleanup-unlinked-templates
CLOUDSTACK-9877 Cleanup unlinked templates
This commit is contained in:
commit
64e56a2159
@ -50,6 +50,8 @@ public interface StorageManager extends StorageService {
|
|||||||
"Determines how long (in seconds) to wait before actually expunging destroyed volumes. The default value = the default value of storage.cleanup.interval.", false, ConfigKey.Scope.Global, null);
|
"Determines how long (in seconds) to wait before actually expunging destroyed volumes. The default value = the default value of storage.cleanup.interval.", false, ConfigKey.Scope.Global, null);
|
||||||
static final ConfigKey<Boolean> StorageCleanupEnabled = new ConfigKey<Boolean>(Boolean.class, "storage.cleanup.enabled", "Advanced", "true",
|
static final ConfigKey<Boolean> StorageCleanupEnabled = new ConfigKey<Boolean>(Boolean.class, "storage.cleanup.enabled", "Advanced", "true",
|
||||||
"Enables/disables the storage cleanup thread.", false, ConfigKey.Scope.Global, null);
|
"Enables/disables the storage cleanup thread.", false, ConfigKey.Scope.Global, null);
|
||||||
|
static final ConfigKey<Boolean> TemplateCleanupEnabled = new ConfigKey<Boolean>(Boolean.class, "storage.template.cleanup.enabled", "Storage", "true",
|
||||||
|
"Enable/disable template cleanup activity, only take effect when overall storage cleanup is enabled", false, ConfigKey.Scope.Global, null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a comma separated list of tags for the specified storage pool
|
* Returns a comma separated list of tags for the specified storage pool
|
||||||
|
|||||||
@ -270,7 +270,6 @@
|
|||||||
<bean id="storagePoolTagsDaoImpl" class="com.cloud.storage.dao.StoragePoolTagsDaoImpl" />
|
<bean id="storagePoolTagsDaoImpl" class="com.cloud.storage.dao.StoragePoolTagsDaoImpl" />
|
||||||
<bean id="hostTagDaoImpl" class="com.cloud.api.query.dao.HostTagDaoImpl" />
|
<bean id="hostTagDaoImpl" class="com.cloud.api.query.dao.HostTagDaoImpl" />
|
||||||
<bean id="storagePoolWorkDaoImpl" class="com.cloud.storage.dao.StoragePoolWorkDaoImpl" />
|
<bean id="storagePoolWorkDaoImpl" class="com.cloud.storage.dao.StoragePoolWorkDaoImpl" />
|
||||||
<bean id="templatePrimaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDaoImpl" />
|
|
||||||
<bean id="uploadDaoImpl" class="com.cloud.storage.dao.UploadDaoImpl" />
|
<bean id="uploadDaoImpl" class="com.cloud.storage.dao.UploadDaoImpl" />
|
||||||
<bean id="usageDaoImpl" class="com.cloud.usage.dao.UsageDaoImpl" />
|
<bean id="usageDaoImpl" class="com.cloud.usage.dao.UsageDaoImpl" />
|
||||||
<bean id="usageEventDaoImpl" class="com.cloud.event.dao.UsageEventDaoImpl" />
|
<bean id="usageEventDaoImpl" class="com.cloud.event.dao.UsageEventDaoImpl" />
|
||||||
|
|||||||
@ -43,7 +43,6 @@
|
|||||||
<bean id="objectInDataStoreDaoImpl" class="org.apache.cloudstack.storage.db.ObjectInDataStoreDaoImpl" />
|
<bean id="objectInDataStoreDaoImpl" class="org.apache.cloudstack.storage.db.ObjectInDataStoreDaoImpl" />
|
||||||
<bean id="primaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl" />
|
<bean id="primaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl" />
|
||||||
<bean id="primaryDataStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.volume.db.PrimaryDataStoreDetailsDaoImpl" />
|
<bean id="primaryDataStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.volume.db.PrimaryDataStoreDetailsDaoImpl" />
|
||||||
<bean id="templatePrimaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDaoImpl" />
|
|
||||||
<bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator"/>
|
<bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator"/>
|
||||||
<bean id="clusterScopeStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ClusterScopeStoragePoolAllocator" />
|
<bean id="clusterScopeStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ClusterScopeStoragePoolAllocator" />
|
||||||
<bean id="zoneWideStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ZoneWideStoragePoolAllocator" />
|
<bean id="zoneWideStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ZoneWideStoragePoolAllocator" />
|
||||||
|
|||||||
@ -43,7 +43,6 @@
|
|||||||
<bean id="objectInDataStoreDaoImpl" class="org.apache.cloudstack.storage.db.ObjectInDataStoreDaoImpl" />
|
<bean id="objectInDataStoreDaoImpl" class="org.apache.cloudstack.storage.db.ObjectInDataStoreDaoImpl" />
|
||||||
<bean id="primaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl" />
|
<bean id="primaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl" />
|
||||||
<bean id="primaryDataStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.volume.db.PrimaryDataStoreDetailsDaoImpl" />
|
<bean id="primaryDataStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.volume.db.PrimaryDataStoreDetailsDaoImpl" />
|
||||||
<bean id="templatePrimaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDaoImpl" />
|
|
||||||
<bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator"/>
|
<bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator"/>
|
||||||
<bean id="clusterScopeStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ClusterScopeStoragePoolAllocator" />
|
<bean id="clusterScopeStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ClusterScopeStoragePoolAllocator" />
|
||||||
<bean id="zoneWideStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ZoneWideStoragePoolAllocator" />
|
<bean id="zoneWideStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ZoneWideStoragePoolAllocator" />
|
||||||
|
|||||||
@ -1,31 +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.volume.db;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
|
||||||
|
|
||||||
import com.cloud.utils.db.GenericDao;
|
|
||||||
import com.cloud.utils.fsm.StateDao;
|
|
||||||
|
|
||||||
public interface TemplatePrimaryDataStoreDao extends GenericDao<TemplatePrimaryDataStoreVO, Long>,
|
|
||||||
StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, TemplatePrimaryDataStoreVO> {
|
|
||||||
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolId(long templateId, long poolId);
|
|
||||||
|
|
||||||
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolIdAndReady(long templateId, long poolId);
|
|
||||||
}
|
|
||||||
@ -1,123 +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.volume.db;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
|
|
||||||
|
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
|
||||||
import com.cloud.utils.db.QueryBuilder;
|
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
|
||||||
import com.cloud.utils.db.SearchCriteria.Op;
|
|
||||||
import com.cloud.utils.db.UpdateBuilder;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase<TemplatePrimaryDataStoreVO, Long> implements TemplatePrimaryDataStoreDao {
|
|
||||||
private static final Logger s_logger = Logger.getLogger(TemplatePrimaryDataStoreDaoImpl.class);
|
|
||||||
protected final SearchBuilder<TemplatePrimaryDataStoreVO> updateSearchBuilder;
|
|
||||||
|
|
||||||
public TemplatePrimaryDataStoreDaoImpl() {
|
|
||||||
updateSearchBuilder = createSearchBuilder();
|
|
||||||
updateSearchBuilder.and("id", updateSearchBuilder.entity().getId(), Op.EQ);
|
|
||||||
updateSearchBuilder.and("state", updateSearchBuilder.entity().getState(), Op.EQ);
|
|
||||||
updateSearchBuilder.and("updatedCount", updateSearchBuilder.entity().getUpdatedCount(), Op.EQ);
|
|
||||||
updateSearchBuilder.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolId(long templateId, long poolId) {
|
|
||||||
QueryBuilder<TemplatePrimaryDataStoreVO> sc = QueryBuilder.create(TemplatePrimaryDataStoreVO.class);
|
|
||||||
sc.and(sc.entity().getTemplateId(), Op.EQ, templateId);
|
|
||||||
sc.and(sc.entity().getPoolId(), Op.EQ, poolId);
|
|
||||||
return sc.find();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolIdAndReady(long templateId, long poolId) {
|
|
||||||
QueryBuilder<TemplatePrimaryDataStoreVO> sc = QueryBuilder.create(TemplatePrimaryDataStoreVO.class);
|
|
||||||
sc.and(sc.entity().getTemplateId(), Op.EQ, templateId);
|
|
||||||
sc.and(sc.entity().getPoolId(), Op.EQ, poolId);
|
|
||||||
sc.and(sc.entity().getState(), Op.EQ, ObjectInDataStoreStateMachine.State.Ready);
|
|
||||||
return sc.find();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean updateState(State currentState, Event event, State nextState, TemplatePrimaryDataStoreVO vo, Object data) {
|
|
||||||
Long oldUpdated = vo.getUpdatedCount();
|
|
||||||
Date oldUpdatedTime = vo.getLastUpdated();
|
|
||||||
|
|
||||||
SearchCriteria<TemplatePrimaryDataStoreVO> sc = updateSearchBuilder.create();
|
|
||||||
sc.setParameters("id", vo.getId());
|
|
||||||
sc.setParameters("state", currentState);
|
|
||||||
sc.setParameters("updatedCount", vo.getUpdatedCount());
|
|
||||||
|
|
||||||
vo.incrUpdatedCount();
|
|
||||||
|
|
||||||
UpdateBuilder builder = getUpdateBuilder(vo);
|
|
||||||
builder.set(vo, "state", nextState);
|
|
||||||
builder.set(vo, "lastUpdated", new Date());
|
|
||||||
|
|
||||||
int rows = update(vo, sc);
|
|
||||||
if (rows == 0 && s_logger.isDebugEnabled()) {
|
|
||||||
TemplatePrimaryDataStoreVO template = findByIdIncludingRemoved(vo.getId());
|
|
||||||
if (template != null) {
|
|
||||||
StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
|
|
||||||
str.append(": DB Data={id=")
|
|
||||||
.append(template.getId())
|
|
||||||
.append("; state=")
|
|
||||||
.append(template.getState())
|
|
||||||
.append("; updatecount=")
|
|
||||||
.append(template.getUpdatedCount())
|
|
||||||
.append(";updatedTime=")
|
|
||||||
.append(template.getLastUpdated());
|
|
||||||
str.append(": New Data={id=")
|
|
||||||
.append(vo.getId())
|
|
||||||
.append("; state=")
|
|
||||||
.append(nextState)
|
|
||||||
.append("; event=")
|
|
||||||
.append(event)
|
|
||||||
.append("; updatecount=")
|
|
||||||
.append(vo.getUpdatedCount())
|
|
||||||
.append("; updatedTime=")
|
|
||||||
.append(vo.getLastUpdated());
|
|
||||||
str.append(": stale Data={id=")
|
|
||||||
.append(vo.getId())
|
|
||||||
.append("; state=")
|
|
||||||
.append(currentState)
|
|
||||||
.append("; event=")
|
|
||||||
.append(event)
|
|
||||||
.append("; updatecount=")
|
|
||||||
.append(oldUpdated)
|
|
||||||
.append("; updatedTime=")
|
|
||||||
.append(oldUpdatedTime);
|
|
||||||
} else {
|
|
||||||
s_logger.debug("Unable to update template: id=" + vo.getId() + ", as there is no such template exists in the database anymore");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rows > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,262 +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.volume.db;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.EnumType;
|
|
||||||
import javax.persistence.Enumerated;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.Temporal;
|
|
||||||
import javax.persistence.TemporalType;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
|
||||||
|
|
||||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
|
||||||
import com.cloud.utils.fsm.StateObject;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "template_spool_ref")
|
|
||||||
public class TemplatePrimaryDataStoreVO implements StateObject<ObjectInDataStoreStateMachine.State> {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
||||||
long id;
|
|
||||||
|
|
||||||
@Column(name = "pool_id")
|
|
||||||
private long poolId;
|
|
||||||
|
|
||||||
@Column(name = "template_id")
|
|
||||||
long templateId;
|
|
||||||
|
|
||||||
@Column(name = GenericDaoBase.CREATED_COLUMN)
|
|
||||||
Date created = null;
|
|
||||||
|
|
||||||
@Column(name = "last_updated")
|
|
||||||
@Temporal(value = TemporalType.TIMESTAMP)
|
|
||||||
Date lastUpdated = null;
|
|
||||||
|
|
||||||
@Column(name = "download_pct")
|
|
||||||
int downloadPercent;
|
|
||||||
|
|
||||||
@Column(name = "download_state")
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
Status downloadState;
|
|
||||||
|
|
||||||
@Column(name = "local_path")
|
|
||||||
String localDownloadPath;
|
|
||||||
|
|
||||||
@Column(name = "error_str")
|
|
||||||
String errorString;
|
|
||||||
|
|
||||||
@Column(name = "job_id")
|
|
||||||
String jobId;
|
|
||||||
|
|
||||||
@Column(name = "install_path")
|
|
||||||
String installPath;
|
|
||||||
|
|
||||||
@Column(name = "template_size")
|
|
||||||
long templateSize;
|
|
||||||
|
|
||||||
@Column(name = "marked_for_gc")
|
|
||||||
boolean markedForGC;
|
|
||||||
|
|
||||||
@Column(name = "state")
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
ObjectInDataStoreStateMachine.State state;
|
|
||||||
|
|
||||||
@Column(name = "update_count", updatable = true, nullable = false)
|
|
||||||
protected long updatedCount;
|
|
||||||
|
|
||||||
public long getUpdatedCount() {
|
|
||||||
return this.updatedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrUpdatedCount() {
|
|
||||||
this.updatedCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void decrUpdatedCount() {
|
|
||||||
this.updatedCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInstallPath() {
|
|
||||||
return installPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTemplateSize() {
|
|
||||||
return templateSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getPoolId() {
|
|
||||||
return poolId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setpoolId(long poolId) {
|
|
||||||
this.poolId = poolId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTemplateId() {
|
|
||||||
return templateId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTemplateId(long templateId) {
|
|
||||||
this.templateId = templateId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDownloadPercent() {
|
|
||||||
return downloadPercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDownloadPercent(int downloadPercent) {
|
|
||||||
this.downloadPercent = downloadPercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDownloadState(Status downloadState) {
|
|
||||||
this.downloadState = downloadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getCreated() {
|
|
||||||
return created;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLastUpdated() {
|
|
||||||
return lastUpdated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastUpdated(Date date) {
|
|
||||||
lastUpdated = date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInstallPath(String installPath) {
|
|
||||||
this.installPath = installPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Status getDownloadState() {
|
|
||||||
return downloadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TemplatePrimaryDataStoreVO(long poolId, long templateId) {
|
|
||||||
super();
|
|
||||||
this.poolId = poolId;
|
|
||||||
this.templateId = templateId;
|
|
||||||
this.downloadState = Status.NOT_DOWNLOADED;
|
|
||||||
this.state = ObjectInDataStoreStateMachine.State.Allocated;
|
|
||||||
this.markedForGC = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TemplatePrimaryDataStoreVO(long poolId, long templateId, Date lastUpdated, int downloadPercent, Status downloadState, String localDownloadPath,
|
|
||||||
String errorString, String jobId, String installPath, long templateSize) {
|
|
||||||
super();
|
|
||||||
this.poolId = poolId;
|
|
||||||
this.templateId = templateId;
|
|
||||||
this.lastUpdated = lastUpdated;
|
|
||||||
this.downloadPercent = downloadPercent;
|
|
||||||
this.downloadState = downloadState;
|
|
||||||
this.localDownloadPath = localDownloadPath;
|
|
||||||
this.errorString = errorString;
|
|
||||||
this.jobId = jobId;
|
|
||||||
this.installPath = installPath;
|
|
||||||
this.templateSize = templateSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TemplatePrimaryDataStoreVO() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocalDownloadPath(String localPath) {
|
|
||||||
this.localDownloadPath = localPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocalDownloadPath() {
|
|
||||||
return localDownloadPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setErrorString(String errorString) {
|
|
||||||
this.errorString = errorString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrorString() {
|
|
||||||
return errorString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJobId(String jobId) {
|
|
||||||
this.jobId = jobId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getJobId() {
|
|
||||||
return jobId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTemplateSize(long templateSize) {
|
|
||||||
this.templateSize = templateSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getMarkedForGC() {
|
|
||||||
return markedForGC;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMarkedForGC(boolean markedForGC) {
|
|
||||||
this.markedForGC = markedForGC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj instanceof TemplatePrimaryDataStoreVO) {
|
|
||||||
TemplatePrimaryDataStoreVO other = (TemplatePrimaryDataStoreVO)obj;
|
|
||||||
return (this.templateId == other.getTemplateId() && this.poolId == other.getPoolId());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
Long tid = new Long(templateId);
|
|
||||||
Long hid = new Long(poolId);
|
|
||||||
return tid.hashCode() + hid.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new StringBuilder("TmplPool[").append(id)
|
|
||||||
.append("-")
|
|
||||||
.append(templateId)
|
|
||||||
.append("-")
|
|
||||||
.append("poolId")
|
|
||||||
.append("-")
|
|
||||||
.append(installPath)
|
|
||||||
.append("]")
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ObjectInDataStoreStateMachine.State getState() {
|
|
||||||
return this.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,158 @@
|
|||||||
|
// Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
// or more contributor license agreements. See the NOTICE file
|
||||||
|
// distributed with this work for additional information
|
||||||
|
// regarding copyright ownership. The ASF licenses this file
|
||||||
|
// to you under the Apache License, Version 2.0 (the
|
||||||
|
// "License"); you may not use this file except in compliance
|
||||||
|
// with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing,
|
||||||
|
// software distributed under the License is distributed on an
|
||||||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
// KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations
|
||||||
|
// under the License.
|
||||||
|
package com.cloud.hypervisor.vmware.manager;
|
||||||
|
|
||||||
|
import com.cloud.api.query.dao.TemplateJoinDao;
|
||||||
|
import com.cloud.api.query.vo.TemplateJoinVO;
|
||||||
|
import com.cloud.hypervisor.Hypervisor;
|
||||||
|
import com.cloud.hypervisor.HypervisorGuru;
|
||||||
|
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||||
|
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||||
|
import com.cloud.template.TemplateManager;
|
||||||
|
import com.cloud.template.VirtualMachineTemplate;
|
||||||
|
import com.cloud.vm.UserVmCloneSettingVO;
|
||||||
|
import com.cloud.vm.VMInstanceVO;
|
||||||
|
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
||||||
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
import org.apache.cloudstack.engine.orchestration.VolumeOrchestrator;
|
||||||
|
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Task marks templates that are only used as fully cloned templates and have been deleted from CloudStack for removal from primary stores.
|
||||||
|
*/
|
||||||
|
public class CleanupFullyClonedTemplatesTask extends ManagedContextRunnable {
|
||||||
|
|
||||||
|
private static final Logger s_logger = Logger.getLogger(CleanupFullyClonedTemplatesTask.class);
|
||||||
|
|
||||||
|
private PrimaryDataStoreDao primaryStorageDao;
|
||||||
|
private VMTemplatePoolDao templateDataStoreDao;
|
||||||
|
private TemplateJoinDao templateDao;
|
||||||
|
private VMInstanceDao vmInstanceDao;
|
||||||
|
private UserVmCloneSettingDao cloneSettingDao;
|
||||||
|
private TemplateManager templateManager;
|
||||||
|
|
||||||
|
private Thread mine;
|
||||||
|
|
||||||
|
CleanupFullyClonedTemplatesTask(PrimaryDataStoreDao primaryStorageDao,
|
||||||
|
VMTemplatePoolDao templateDataStoreDao,
|
||||||
|
TemplateJoinDao templateDao,
|
||||||
|
VMInstanceDao vmInstanceDao,
|
||||||
|
UserVmCloneSettingDao cloneSettingDao,
|
||||||
|
TemplateManager templateManager) {
|
||||||
|
this.primaryStorageDao = primaryStorageDao;
|
||||||
|
this.templateDataStoreDao = templateDataStoreDao;
|
||||||
|
this.templateDao = templateDao;
|
||||||
|
this.vmInstanceDao = vmInstanceDao;
|
||||||
|
this.cloneSettingDao = cloneSettingDao;
|
||||||
|
this.templateManager = templateManager;
|
||||||
|
if(s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("new task created: " + this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runInContext() {
|
||||||
|
mine = Thread.currentThread();
|
||||||
|
s_logger.info("running job to mark fully cloned templates for gc in thread " + mine.getName());
|
||||||
|
|
||||||
|
if (HypervisorGuru.VmwareFullClone.value()) { // only run if full cloning is being used (might need to be more fine grained)
|
||||||
|
try {
|
||||||
|
queryAllPools();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
s_logger.error("error during job to mark fully cloned templates for gc in thread " + mine.getName());
|
||||||
|
if(s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("running job to mark fully cloned templates for gc in thread " + mine.getName(),t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void queryAllPools() {
|
||||||
|
List<StoragePoolVO> storagePools = primaryStorageDao.listAll();
|
||||||
|
for (StoragePoolVO pool : storagePools) {
|
||||||
|
long zoneId = pool.getDataCenterId();
|
||||||
|
queryPoolForTemplates(pool, zoneId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void queryPoolForTemplates(StoragePoolVO pool, long zoneId) {
|
||||||
|
// we don't need those specific to other hypervisor types
|
||||||
|
if (pool.getHypervisor() == null || Hypervisor.HypervisorType.VMware.equals(pool.getHypervisor())) {
|
||||||
|
if(s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug(mine.getName() + " is marking fully cloned templates in pool " + pool.getName());
|
||||||
|
}
|
||||||
|
List<VMTemplateStoragePoolVO> templatePrimaryDataStoreVOS = templateDataStoreDao.listByPoolId(pool.getId());
|
||||||
|
for (VMTemplateStoragePoolVO templateMapping : templatePrimaryDataStoreVOS) {
|
||||||
|
if (canRemoveTemplateFromZone(zoneId, templateMapping)) {
|
||||||
|
templateManager.evictTemplateFromStoragePool(templateMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug(mine.getName() + " is ignoring pool " + pool.getName() + " id == " + pool.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canRemoveTemplateFromZone(long zoneId, VMTemplateStoragePoolVO templateMapping) {
|
||||||
|
if (!templateMapping.getMarkedForGC()) {
|
||||||
|
if(s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug(mine.getName() + " is checking template with id " + templateMapping.getTemplateId() + " for deletion from pool with id " + templateMapping.getPoolId());
|
||||||
|
}
|
||||||
|
|
||||||
|
TemplateJoinVO templateJoinVO = templateDao.findByIdIncludingRemoved(templateMapping.getTemplateId());
|
||||||
|
// check if these are deleted (not removed is null)
|
||||||
|
if (VirtualMachineTemplate.State.Inactive.equals(templateJoinVO.getTemplateState())) { // meaning it is removed!
|
||||||
|
// see if we can find vms using it with user_vm_clone_setting != full
|
||||||
|
return markedForGc(templateMapping, zoneId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean markedForGc(VMTemplateStoragePoolVO templateMapping, long zoneId) {
|
||||||
|
boolean used = false;
|
||||||
|
List<VMInstanceVO> vms = vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateMapping.getTemplateId());
|
||||||
|
for (VMInstanceVO vm : vms) {
|
||||||
|
try {
|
||||||
|
UserVmCloneSettingVO cloneSetting = cloneSettingDao.findByVmId(vm.getId());
|
||||||
|
// VolumeOrchestrator or UserVmManagerImpl depending on version
|
||||||
|
if (VolumeOrchestrator.UserVmCloneType.linked.equals(VolumeOrchestrator.UserVmCloneType.valueOf(cloneSetting.getCloneType()))) {
|
||||||
|
used = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.error("failed to retrieve vm clone setting for vm " + vm.toString());
|
||||||
|
if(s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("failed to retrieve vm clone setting for vm " + vm.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!used) {
|
||||||
|
s_logger.info(mine.getName() + " is marking template with id " + templateMapping.getTemplateId() + " for gc in pool with id " + templateMapping.getPoolId());
|
||||||
|
// else
|
||||||
|
// mark it for removal from primary store
|
||||||
|
templateMapping.setMarkedForGC(true);
|
||||||
|
}
|
||||||
|
return !used;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,24 +16,25 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.hypervisor.vmware.manager;
|
package com.cloud.hypervisor.vmware.manager;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.vmware.vim25.ManagedObjectReference;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
|
||||||
|
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
|
import com.vmware.vim25.ManagedObjectReference;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface VmwareManager {
|
public interface VmwareManager {
|
||||||
public final String CONTEXT_STOCK_NAME = "vmwareMgr";
|
public final String CONTEXT_STOCK_NAME = "vmwareMgr";
|
||||||
|
|
||||||
public static final ConfigKey<Long> s_vmwareNicHotplugWaitTimeout = new ConfigKey<Long>("Advanced", Long.class, "vmware.nic.hotplug.wait.timeout", "15000",
|
public static final ConfigKey<Long> s_vmwareNicHotplugWaitTimeout = new ConfigKey<Long>("Advanced", Long.class, "vmware.nic.hotplug.wait.timeout", "15000",
|
||||||
"Wait timeout (milli seconds) for hot plugged NIC of VM to be detected by guest OS.", false, ConfigKey.Scope.Global);
|
"Wait timeout (milli seconds) for hot plugged NIC of VM to be detected by guest OS.", false, ConfigKey.Scope.Global);
|
||||||
|
|
||||||
|
public static final ConfigKey<Long> templateCleanupInterval = new ConfigKey<Long>("Advanced", Long.class, "vmware.full.clone.template.cleanup.period", "0",
|
||||||
|
"period (in minutes) between the start of template cleanup jobs for vmware full cloned templates.", false, ConfigKey.Scope.Global);
|
||||||
|
|
||||||
public static final ConfigKey<Boolean> s_vmwareCleanOldWorderVMs = new ConfigKey<Boolean>("Advanced", Boolean.class, "vmware.clean.old.worker.vms", "false",
|
public static final ConfigKey<Boolean> s_vmwareCleanOldWorderVMs = new ConfigKey<Boolean>("Advanced", Boolean.class, "vmware.clean.old.worker.vms", "false",
|
||||||
"If a worker vm is older then twice the 'job.expire.minutes' + 'job.cancel.threshold.minutes' , remove it.", true, ConfigKey.Scope.Global);
|
"If a worker vm is older then twice the 'job.expire.minutes' + 'job.cancel.threshold.minutes' , remove it.", true, ConfigKey.Scope.Global);
|
||||||
|
|||||||
@ -16,43 +16,6 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.hypervisor.vmware.manager;
|
package com.cloud.hypervisor.vmware.manager;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.rmi.RemoteException;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.naming.ConfigurationException;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import com.vmware.vim25.AboutInfo;
|
|
||||||
import com.vmware.vim25.ManagedObjectReference;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
|
||||||
import org.apache.cloudstack.framework.config.Configurable;
|
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|
||||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.Listener;
|
import com.cloud.agent.Listener;
|
||||||
import com.cloud.agent.api.AgentControlAnswer;
|
import com.cloud.agent.api.AgentControlAnswer;
|
||||||
@ -61,6 +24,7 @@ import com.cloud.agent.api.Answer;
|
|||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
import com.cloud.agent.api.StartupCommand;
|
import com.cloud.agent.api.StartupCommand;
|
||||||
import com.cloud.agent.api.StartupRoutingCommand;
|
import com.cloud.agent.api.StartupRoutingCommand;
|
||||||
|
import com.cloud.api.query.dao.TemplateJoinDao;
|
||||||
import com.cloud.cluster.ClusterManager;
|
import com.cloud.cluster.ClusterManager;
|
||||||
import com.cloud.cluster.ManagementServerHost;
|
import com.cloud.cluster.ManagementServerHost;
|
||||||
import com.cloud.cluster.dao.ManagementServerHostPeerDao;
|
import com.cloud.cluster.dao.ManagementServerHostPeerDao;
|
||||||
@ -103,9 +67,9 @@ import com.cloud.hypervisor.vmware.util.VmwareContext;
|
|||||||
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||||
import com.cloud.network.CiscoNexusVSMDeviceVO;
|
import com.cloud.network.CiscoNexusVSMDeviceVO;
|
||||||
import com.cloud.network.NetworkModel;
|
import com.cloud.network.NetworkModel;
|
||||||
import com.cloud.network.VmwareTrafficLabel;
|
|
||||||
import com.cloud.network.Networks.BroadcastDomainType;
|
import com.cloud.network.Networks.BroadcastDomainType;
|
||||||
import com.cloud.network.Networks.TrafficType;
|
import com.cloud.network.Networks.TrafficType;
|
||||||
|
import com.cloud.network.VmwareTrafficLabel;
|
||||||
import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
|
import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
|
||||||
import com.cloud.org.Cluster.ClusterType;
|
import com.cloud.org.Cluster.ClusterType;
|
||||||
import com.cloud.secstorage.CommandExecLogDao;
|
import com.cloud.secstorage.CommandExecLogDao;
|
||||||
@ -113,6 +77,9 @@ import com.cloud.server.ConfigurationServer;
|
|||||||
import com.cloud.storage.ImageStoreDetailsUtil;
|
import com.cloud.storage.ImageStoreDetailsUtil;
|
||||||
import com.cloud.storage.JavaStorageLayer;
|
import com.cloud.storage.JavaStorageLayer;
|
||||||
import com.cloud.storage.StorageLayer;
|
import com.cloud.storage.StorageLayer;
|
||||||
|
import com.cloud.storage.StorageManager;
|
||||||
|
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||||
|
import com.cloud.template.TemplateManager;
|
||||||
import com.cloud.utils.FileUtil;
|
import com.cloud.utils.FileUtil;
|
||||||
import com.cloud.utils.NumbersUtil;
|
import com.cloud.utils.NumbersUtil;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
@ -127,14 +94,48 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||||||
import com.cloud.utils.script.Script;
|
import com.cloud.utils.script.Script;
|
||||||
import com.cloud.utils.ssh.SshHelper;
|
import com.cloud.utils.ssh.SshHelper;
|
||||||
import com.cloud.vm.DomainRouterVO;
|
import com.cloud.vm.DomainRouterVO;
|
||||||
|
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
||||||
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
import com.vmware.vim25.AboutInfo;
|
||||||
|
import com.vmware.vim25.ManagedObjectReference;
|
||||||
|
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
import org.apache.cloudstack.framework.config.Configurable;
|
||||||
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
|
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.naming.ConfigurationException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.rmi.RemoteException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
|
public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
|
||||||
private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class);
|
private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class);
|
||||||
|
|
||||||
private static final long SECONDS_PER_MINUTE = 60;
|
private static final long SECONDS_PER_MINUTE = 60;
|
||||||
private static final int STARTUP_DELAY = 60000; // 60 seconds
|
|
||||||
private static final long DEFAULT_HOST_SCAN_INTERVAL = 600000; // every 10 minutes
|
|
||||||
private long _hostScanInterval = DEFAULT_HOST_SCAN_INTERVAL;
|
|
||||||
private int _timeout;
|
private int _timeout;
|
||||||
|
|
||||||
private String _instance;
|
private String _instance;
|
||||||
@ -175,6 +176,18 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
private ClusterManager _clusterMgr;
|
private ClusterManager _clusterMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private ImageStoreDetailsUtil imageStoreDetailsUtil;
|
private ImageStoreDetailsUtil imageStoreDetailsUtil;
|
||||||
|
@Inject
|
||||||
|
private PrimaryDataStoreDao primaryStorageDao;
|
||||||
|
@Inject
|
||||||
|
private VMTemplatePoolDao templateDataStoreDao;
|
||||||
|
@Inject
|
||||||
|
private TemplateJoinDao templateDao;
|
||||||
|
@Inject
|
||||||
|
private VMInstanceDao vmInstanceDao;
|
||||||
|
@Inject
|
||||||
|
private UserVmCloneSettingDao cloneSettingDao;
|
||||||
|
@Inject
|
||||||
|
private TemplateManager templateManager;
|
||||||
|
|
||||||
private String _mountParent;
|
private String _mountParent;
|
||||||
private StorageLayer _storage;
|
private StorageLayer _storage;
|
||||||
@ -196,15 +209,15 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
private final String _dataDiskController = DiskControllerType.osdefault.toString();
|
private final String _dataDiskController = DiskControllerType.osdefault.toString();
|
||||||
|
|
||||||
private final Map<String, String> _storageMounts = new HashMap<String, String>();
|
private final Map<String, String> _storageMounts = new HashMap<>();
|
||||||
|
|
||||||
private final Random _rand = new Random(System.currentTimeMillis());
|
private final Random _rand = new Random(System.currentTimeMillis());
|
||||||
|
|
||||||
|
private static ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));;
|
||||||
|
|
||||||
private final VmwareStorageManager _storageMgr;
|
private final VmwareStorageManager _storageMgr;
|
||||||
private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
|
private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
|
||||||
|
|
||||||
private final ScheduledExecutorService _hostScanScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-Host-Scan"));
|
|
||||||
|
|
||||||
public VmwareManagerImpl() {
|
public VmwareManagerImpl() {
|
||||||
_storageMgr = new VmwareStorageManagerImpl(this);
|
_storageMgr = new VmwareStorageManagerImpl(this);
|
||||||
}
|
}
|
||||||
@ -216,7 +229,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigKey<?>[] getConfigKeys() {
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
return new ConfigKey<?>[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs};
|
return new ConfigKey<?>[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -313,10 +326,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
s_logger.info("Additional VNC port allocation range is settled at " + _additionalPortRangeStart + " to " + (_additionalPortRangeStart + _additionalPortRangeSize));
|
s_logger.info("Additional VNC port allocation range is settled at " + _additionalPortRangeStart + " to " + (_additionalPortRangeStart + _additionalPortRangeSize));
|
||||||
|
|
||||||
value = _configDao.getValue("vmware.host.scan.interval");
|
|
||||||
_hostScanInterval = NumbersUtil.parseLong(value, DEFAULT_HOST_SCAN_INTERVAL);
|
|
||||||
s_logger.info("VmwareManagerImpl config - vmware.host.scan.interval: " + _hostScanInterval);
|
|
||||||
|
|
||||||
((VmwareStorageManagerImpl)_storageMgr).configure(params);
|
((VmwareStorageManagerImpl)_storageMgr).configure(params);
|
||||||
|
|
||||||
_agentMgr.registerForHostEvents(this, true, true, true);
|
_agentMgr.registerForHostEvents(this, true, true, true);
|
||||||
@ -327,21 +336,20 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean start() {
|
public boolean start() {
|
||||||
_hostScanScheduler.scheduleAtFixedRate(getHostScanTask(), STARTUP_DELAY, _hostScanInterval, TimeUnit.MILLISECONDS);
|
// Do not run empty task _hostScanScheduler.scheduleAtFixedRate(getHostScanTask(), STARTUP_DELAY, _hostScanInterval, TimeUnit.MILLISECONDS);
|
||||||
|
// but implement it first!
|
||||||
|
|
||||||
|
startTemplateCleanJobSchedule();
|
||||||
startupCleanup(_mountParent);
|
startupCleanup(_mountParent);
|
||||||
|
|
||||||
|
s_logger.info("start done");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean stop() {
|
public boolean stop() {
|
||||||
_hostScanScheduler.shutdownNow();
|
s_logger.info("shutting down scheduled tasks");
|
||||||
try {
|
templateCleanupScheduler.shutdown();
|
||||||
_hostScanScheduler.awaitTermination(3000, TimeUnit.MILLISECONDS);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
s_logger.debug("[ignored] interupted while stopping<:/.");
|
|
||||||
}
|
|
||||||
|
|
||||||
shutdownCleanup();
|
shutdownCleanup();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -670,19 +678,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
return keyFile;
|
return keyFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable getHostScanTask() {
|
|
||||||
return new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// TODO scan vSphere for newly added hosts.
|
|
||||||
// we are going to both support adding host from CloudStack UI and
|
|
||||||
// adding host via vSphere server
|
|
||||||
//
|
|
||||||
// will implement host scanning later
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMountPoint(String storageUrl, Integer nfsVersion) {
|
public String getMountPoint(String storageUrl, Integer nfsVersion) {
|
||||||
String mountPoint = null;
|
String mountPoint = null;
|
||||||
@ -1288,4 +1283,55 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startTemplateCleanJobSchedule() {
|
||||||
|
if(s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("checking to see if we should schedule a job to search for fully cloned templates to clean-up");
|
||||||
|
}
|
||||||
|
if(StorageManager.StorageCleanupEnabled.value() &&
|
||||||
|
StorageManager.TemplateCleanupEnabled.value() &&
|
||||||
|
templateCleanupInterval.value() > 0) {
|
||||||
|
try {
|
||||||
|
if (s_logger.isInfoEnabled()) {
|
||||||
|
s_logger.info("scheduling job to search for fully cloned templates to clean-up once per " + templateCleanupInterval.value() + " minutes.");
|
||||||
|
}
|
||||||
|
// futureTemplateCleanup =
|
||||||
|
Runnable task = getCleanupFullyClonedTemplatesTask();
|
||||||
|
templateCleanupScheduler.scheduleAtFixedRate(task,
|
||||||
|
templateCleanupInterval.value(),
|
||||||
|
templateCleanupInterval.value(),
|
||||||
|
TimeUnit.MINUTES);
|
||||||
|
if (s_logger.isTraceEnabled()) {
|
||||||
|
s_logger.trace("scheduled job to search for fully cloned templates to clean-up.");
|
||||||
|
}
|
||||||
|
} catch (RejectedExecutionException ree) {
|
||||||
|
s_logger.error("job to search for fully cloned templates cannot be scheduled");
|
||||||
|
s_logger.debug("job to search for fully cloned templates cannot be scheduled;", ree);
|
||||||
|
} catch (NullPointerException npe) {
|
||||||
|
s_logger.error("job to search for fully cloned templates is invalid");
|
||||||
|
s_logger.debug("job to search for fully cloned templates is invalid;", npe);
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
s_logger.error("job to search for fully cloned templates is scheduled at invalid intervals");
|
||||||
|
s_logger.debug("job to search for fully cloned templates is scheduled at invalid intervals;", iae);
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.error("job to search for fully cloned templates failed for unknown reasons");
|
||||||
|
s_logger.debug("job to search for fully cloned templates failed for unknown reasons;", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This task is to cleanup templates from primary storage that are otherwise not cleaned by the {@link com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
|
||||||
|
* it is called at regular intervals when storage.template.cleanup.enabled == true
|
||||||
|
* It collect all templates that
|
||||||
|
* - are deleted from cloudstack
|
||||||
|
* - when vmware.create.full.clone == true and the entries for VMs having volumes on the primary storage in db table “user_vm_clone_setting” reads 'full'
|
||||||
|
*/
|
||||||
|
private Runnable getCleanupFullyClonedTemplatesTask() {
|
||||||
|
return new CleanupFullyClonedTemplatesTask(primaryStorageDao,
|
||||||
|
templateDataStoreDao,
|
||||||
|
templateDao,
|
||||||
|
vmInstanceDao,
|
||||||
|
cloneSettingDao,
|
||||||
|
templateManager);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,48 +17,8 @@
|
|||||||
|
|
||||||
package com.cloud.hypervisor.vmware;
|
package com.cloud.hypervisor.vmware;
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import com.cloud.user.User;
|
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Matchers;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
|
||||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.FilterType;
|
|
||||||
import org.springframework.core.type.classreading.MetadataReader;
|
|
||||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
|
||||||
import org.springframework.core.type.filter.TypeFilter;
|
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|
||||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
|
||||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
|
|
||||||
import org.apache.cloudstack.context.CallContext;
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
|
||||||
import org.apache.cloudstack.test.utils.SpringUtils;
|
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
|
import com.cloud.api.query.dao.TemplateJoinDao;
|
||||||
import com.cloud.cluster.ClusterManager;
|
import com.cloud.cluster.ClusterManager;
|
||||||
import com.cloud.cluster.dao.ManagementServerHostPeerDao;
|
import com.cloud.cluster.dao.ManagementServerHostPeerDao;
|
||||||
import com.cloud.dc.ClusterDetailsDao;
|
import com.cloud.dc.ClusterDetailsDao;
|
||||||
@ -89,15 +49,58 @@ import com.cloud.org.Managed.ManagedState;
|
|||||||
import com.cloud.secstorage.CommandExecLogDao;
|
import com.cloud.secstorage.CommandExecLogDao;
|
||||||
import com.cloud.server.ConfigurationServer;
|
import com.cloud.server.ConfigurationServer;
|
||||||
import com.cloud.storage.ImageStoreDetailsUtil;
|
import com.cloud.storage.ImageStoreDetailsUtil;
|
||||||
|
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||||
|
import com.cloud.template.TemplateManager;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import com.cloud.user.AccountService;
|
import com.cloud.user.AccountService;
|
||||||
import com.cloud.user.AccountVO;
|
import com.cloud.user.AccountVO;
|
||||||
|
import com.cloud.user.User;
|
||||||
import com.cloud.user.UserVO;
|
import com.cloud.user.UserVO;
|
||||||
import com.cloud.user.dao.AccountDao;
|
import com.cloud.user.dao.AccountDao;
|
||||||
import com.cloud.utils.component.ComponentContext;
|
import com.cloud.utils.component.ComponentContext;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
||||||
import com.cloud.vm.dao.UserVmDao;
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||||
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
|
import org.apache.cloudstack.test.utils.SpringUtils;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Matchers;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.FilterType;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
import org.springframework.core.type.filter.TypeFilter;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
||||||
@ -447,6 +450,36 @@ public class VmwareDatacenterApiUnitTest {
|
|||||||
return Mockito.mock(ImageStoreDetailsDao.class);
|
return Mockito.mock(ImageStoreDetailsDao.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public VMTemplatePoolDao templateDataStoreDao() {
|
||||||
|
return Mockito.mock(VMTemplatePoolDao.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TemplateJoinDao templateDao() {
|
||||||
|
return Mockito.mock(TemplateJoinDao.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public VMInstanceDao vmInstanceDao() {
|
||||||
|
return Mockito.mock(VMInstanceDao.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public UserVmCloneSettingDao cloneSettingDao() {
|
||||||
|
return Mockito.mock(UserVmCloneSettingDao.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PrimaryDataStoreDao primaryStorageDao() {
|
||||||
|
return Mockito.mock(PrimaryDataStoreDao.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TemplateManager templateManager() {
|
||||||
|
return Mockito.mock(TemplateManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
public static class Library implements TypeFilter {
|
public static class Library implements TypeFilter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -182,14 +182,6 @@ public enum Config {
|
|||||||
"3600",
|
"3600",
|
||||||
"Timeout (in seconds) to synchronize storage pool operations.",
|
"Timeout (in seconds) to synchronize storage pool operations.",
|
||||||
null),
|
null),
|
||||||
StorageTemplateCleanupEnabled(
|
|
||||||
"Storage",
|
|
||||||
ManagementServer.class,
|
|
||||||
Boolean.class,
|
|
||||||
"storage.template.cleanup.enabled",
|
|
||||||
"true",
|
|
||||||
"Enable/disable template cleanup activity, only take effect when overall storage cleanup is enabled",
|
|
||||||
null),
|
|
||||||
PrimaryStorageDownloadWait(
|
PrimaryStorageDownloadWait(
|
||||||
"Storage",
|
"Storage",
|
||||||
TemplateManager.class,
|
TemplateManager.class,
|
||||||
|
|||||||
@ -314,7 +314,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
protected SearchBuilder<StoragePoolVO> LocalStorageSearch;
|
protected SearchBuilder<StoragePoolVO> LocalStorageSearch;
|
||||||
|
|
||||||
ScheduledExecutorService _executor = null;
|
ScheduledExecutorService _executor = null;
|
||||||
boolean _templateCleanupEnabled = true;
|
|
||||||
int _storagePoolAcquisitionWaitSeconds = 1800; // 30 minutes
|
int _storagePoolAcquisitionWaitSeconds = 1800; // 30 minutes
|
||||||
int _downloadUrlCleanupInterval;
|
int _downloadUrlCleanupInterval;
|
||||||
int _downloadUrlExpirationInterval;
|
int _downloadUrlExpirationInterval;
|
||||||
@ -477,11 +476,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
_agentMgr.registerForHostEvents(new StoragePoolMonitor(this, _storagePoolDao, _dataStoreProviderMgr), true, false, true);
|
_agentMgr.registerForHostEvents(new StoragePoolMonitor(this, _storagePoolDao, _dataStoreProviderMgr), true, false, true);
|
||||||
|
|
||||||
String value = _configDao.getValue(Config.StorageTemplateCleanupEnabled.key());
|
|
||||||
_templateCleanupEnabled = (value == null ? true : Boolean.parseBoolean(value));
|
|
||||||
|
|
||||||
s_logger.info("Storage cleanup enabled: " + StorageCleanupEnabled.value() + ", interval: " + StorageCleanupInterval.value() + ", delay: " + StorageCleanupDelay.value() +
|
s_logger.info("Storage cleanup enabled: " + StorageCleanupEnabled.value() + ", interval: " + StorageCleanupInterval.value() + ", delay: " + StorageCleanupDelay.value() +
|
||||||
", template cleanup enabled: " + _templateCleanupEnabled);
|
", template cleanup enabled: " + TemplateCleanupEnabled.value());
|
||||||
|
|
||||||
String cleanupInterval = configs.get("extract.url.cleanup.interval");
|
String cleanupInterval = configs.get("extract.url.cleanup.interval");
|
||||||
_downloadUrlCleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200);
|
_downloadUrlCleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200);
|
||||||
@ -1065,7 +1061,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
if (scanLock.lock(3)) {
|
if (scanLock.lock(3)) {
|
||||||
try {
|
try {
|
||||||
// Cleanup primary storage pools
|
// Cleanup primary storage pools
|
||||||
if (_templateCleanupEnabled) {
|
if (TemplateCleanupEnabled.value()) {
|
||||||
List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
|
List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
|
||||||
for (StoragePoolVO pool : storagePools) {
|
for (StoragePoolVO pool : storagePools) {
|
||||||
try {
|
try {
|
||||||
@ -2426,7 +2422,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigKey<?>[] getConfigKeys() {
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
return new ConfigKey<?>[] {StorageCleanupInterval, StorageCleanupDelay, StorageCleanupEnabled};
|
return new ConfigKey<?>[] {StorageCleanupInterval, StorageCleanupDelay, StorageCleanupEnabled, TemplateCleanupEnabled};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user